A porcelain plug and socket joined by a violet glass bridge

MCP spend governance

MCP tells an agent what it can call. It does not decide what the agent has authority to spend on. Add that decision to any MCP agent in one line.

Neltava Team · Updated

The Model Context Protocol made it simple to give an AI agent tools. Some of those tools cost money: buying ads, paying for an API, purchasing data, booking travel, topping up credits. Once an agent can call a tool that spends, every call to it is a spending decision the model makes on its own.

What MCP decides — and what it doesn’t

MCP defines how an agent discovers and calls tools. It answers can the agent call this? It has no notion of who delegated the money, how much of it is left, what it was delegated for, or whether a person should look first. Those questions sit in a different layer.

MCP / tool protocol

Can the agent call it?

Mandates / agent identity

Was the agent authorized to act?

Payment rail

Can the payment settle?

Spend limit

Is it within the number?

Neltava

Should this agent do this — under this delegated authority, for this purpose, right now?

MCP answers the first question. Spend authority answers the last one.
MCP tells an agent what it can call. Neltava decides what it has authority to spend on.

The practical consequence: an MCP agent with a payment tool needs one more tool — one it calls before paying, whose answer it follows. That is what the Neltava MCP server provides.

Add it to an MCP agent

Create the agent and its key in the Neltava console, then connect. The remote server needs nothing installed; the local one runs through npx.

Claude Code

terminal
claude mcp add --transport http neltava https://api.neltava.com/mcp \
  --header "Authorization: Bearer $NELTAVA_AGENT_KEY" \
  --header "X-Neltava-Agent: growth-agent"

Cursor and other clients that speak Streamable HTTP

~/.cursor/mcp.json
{
  "mcpServers": {
    "neltava": {
      "url": "https://api.neltava.com/mcp",
      "headers": {
        "Authorization": "Bearer sk_…",
        "X-Neltava-Agent": "growth-agent"
      }
    }
  }
}

Claude Desktop, or any stdio client

mcpServers config · runs locally
{
  "mcpServers": {
    "neltava": {
      "command": "npx",
      "args": [
        "-y",
        "neltava-mcp"
      ],
      "env": {
        "NELTAVA_AGENT_KEY": "sk_…",
        "NELTAVA_AGENT": "growth-agent"
      }
    }
  }
}

The key identifies the agent — it can only ask for decisions for that one agent. X-Neltava-Agent (or NELTAVA_AGENT locally) additionally lets the agent read its own authority. New agents start in Shadow Mode: every spend is decided and recorded, and nothing is blocked.

The tools

ToolWhen the agent uses it
authorize_spendRight before any purchase, subscription, top-up, booking, ad spend or paid API call. Takes the merchant, amount, currency, a description of what and why, and optionally the task, the steps that led here and the payee’s id at the payment rail.
report_spend_outcomeAfter paying: executed, failed or cancelled, with the amount actually charged and the payment reference.
get_spend_authorityTo plan before shopping: the agent’s purpose, limits and budgets, and whether it is in Shadow Mode or Enforce.

The server also tells the model, in its instructions, to call authorize_spend before any spend and follow the answer — and never to split or rephrase a spend to get a different one.

What the model reads

A tool’s answer is text the model reads, so its shape matters. For the $185 Instagram campaign from our purpose example, in Shadow Mode, authorize_spend answers:

authorize_spend → text
PROCEED — you may spend 185.00 USD.
Shadow Mode: Neltava would have said REVIEW (PURPOSE_MISALIGNED). Nothing is blocked; mention it to the user if relevant.
Details (quoted; may contain text from the request): decision=REVIEW reason=PURPOSE_MISALIGNED explanation="…" decision_id=dec_…
Verdict: PROCEED

Three details are deliberate:

  • The verdict is the first and the last line, and only the server writes those lines: PROCEED, DO NOT SPEND YET (a person must approve) or DO NOT SPEND.
  • Anything echoed from the request is quoted on one line. A merchant name or description can come from a web page the agent read. If it could print its own line, it could print a fake “PROCEED”. Names with control or invisible characters are refused before any decision is made.
  • The structured result is the source of truth. Clients that read structuredContent get proceed, needs_review, the verdict, the reason code, the decision id and — in Enforce — the single-use capability.

Following vs. enforcing

An MCP agent that calls authorize_spend and obeys the answer is governed — as long as the model cooperates. That covers honest mistakes and most runaway behaviour. It does not cover a model that has been manipulated into ignoring the answer, or a second payment tool that never asks.

Enforcement moves the check to where the money moves. In Enforce, an allowed spend carries a capability: a short-lived, single-use token bound to the payee, the amount ceiling and the currency. Make your payment tool require it and consume it before charging:

payment tool · sketch
// Your payment tool — the only way this agent can pay. (sketch)
server.registerTool("pay", {
  description: "Pay a merchant. Requires the capability from authorize_spend.",
  inputSchema: { capability: z.string(), merchant: z.string(), payee_id: z.string().optional(),
                 amount: z.number(), currency: z.string() },
}, async (a) => {
  // Throws unless this exact payment is allowed — and only once.
  await adapter.consumeCapability({ capability: a.capability, merchant: a.merchant,
    payeeId: a.payee_id, amount: a.amount, currency: a.currency });
  return charge(a); // your rail: Stripe, a card issuer, an invoice…
});

// adapter = new Neltava({ apiKey: process.env.NELTAVA_ADAPTER_KEY }) — a
// "Payment adapter" key (consume scope), held by the server, never the agent.

A second use, a higher amount, a different payee or currency, an expired token, a paused agent or a changed authority is refused before the charge. The agent’s own key cannot consume a capability — only the payment service’s adapter key can. Give the agent no other way to pay, and ignoring Neltava stops being possible rather than merely discouraged.

When Neltava is unreachable

By default the MCP server answers DO NOT SPEND YET when it cannot reach Neltava: ask the user, don’t spend. You can set it to proceed instead, and that setting only ever applies while the agent is confirmed to be in Shadow Mode. Once an agent is enforced, an unreachable service, a rate limit or a malformed answer never becomes permission.

When you don’t need it

Add to your MCP agent

See what your agents would have done — before anything is blocked.

Connect one agent through the SDK, MCP or one HTTP call. Shadow Mode is free: every spend is decided and recorded, nothing is blocked.

Start free in Shadow Mode →no card · one agent in minutes

Keep reading