> ## Documentation Index
> Fetch the complete documentation index at: https://noorle.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# tools/call

> Execute a tool on a Noorle MCP gateway, with the autonomy outcomes, billing checks, and error codes a caller has to handle

Execute one tool and return its result.

## Request

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "web_search",
    "arguments": { "query": "wasm component model" }
  }
}
```

| Field       | Type   | Required | Description                                                             |
| ----------- | ------ | -------- | ----------------------------------------------------------------------- |
| `name`      | string | Yes      | The namespaced wire name from [`tools/list`](/docs/reference/mcp/tools-list) |
| `arguments` | object | Yes      | Arguments matching the tool's `inputSchema`                             |

In Discovery or Unified presentation mode, call the meta-tool
(`execute_tool` or `unified_tool`) rather than the underlying tool — the
underlying names are not directly callable in those modes.

## Response

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      { "type": "text", "text": "..." }
    ]
  }
}
```

## What happens before your tool runs

Five checks run in order, and each has a distinct failure shape. The first two
happen at the transport, before the method is dispatched, so they fail as HTTP
statuses rather than JSON-RPC errors.

<Steps>
  <Step title="Authentication">
    Handled at the transport. A failure never reaches this method — see
    [Authentication](/docs/reference/authentication).
  </Step>

  <Step title="Billing state">
    Also at the transport, on every request the gateway admits. An account with
    no available budget gets **HTTP 402**; a billing check that cannot complete
    gets **HTTP 503**. Neither carries a JSON-RPC body.
  </Step>

  <Step title="Rate limit">
    600 requests per minute per gateway per caller, shared with `tools/list`.
    Exceeded returns JSON-RPC **-32029**. The separate `initialize` handshake
    limit does not apply to `tools/call`.
  </Step>

  <Step title="Budget allocation">
    A budget is allocated against the account for this specific call. No
    available budget — a hard stop, a zero balance, or an exceeded spending cap
    — returns JSON-RPC **-32600** at HTTP 200, reading
    `"Account has insufficient credits or has been suspended"`.
  </Step>

  <Step title="Autonomy">
    The call passes through the admission door. On an MCP gateway this can only
    allow or deny; it cannot pause. See below.
  </Step>
</Steps>

<Note>
  Budget is checked twice on a `tools/call`: once as a transport-level account
  state (402) and once as a per-call allocation (-32600). A client needs to
  handle both shapes.
</Note>

## Autonomy on this surface

MCP is an **unattended** surface. There is no live channel to ask a human for
approval, so a call that would pause for approval **denies** instead, with the
reason `non_interactive_surface`.

Check the `_meta["dev.noorle/autonomy"].outcome` on the tool listing before
offering a tool to a model:

| `outcome`          | What a call will do                |
| ------------------ | ---------------------------------- |
| `allow`            | Execute                            |
| `deny`             | Fail deterministically             |
| `may_deny_on_args` | Depends on the arguments           |
| `ungated`          | Execute; the gateway has no policy |

The annotation is a hint the gate re-evaluates at dispatch — a stale `allow`
can still deny.

## Errors

| Code       | Cause                                                 |
| ---------- | ----------------------------------------------------- |
| -32601     | Unknown method                                        |
| -32602     | Arguments do not satisfy the tool's `inputSchema`     |
| -32603     | Tool execution failed, or an internal error           |
| **-32029** | Rate limit exhausted. Retryable — back off first      |
| -32600     | No billing budget, or a tool used with the wrong type |

An unknown or unexposed tool name returns an invalid-tool-name error.

<Note>
  **A withheld tool returns the same error as a nonexistent one.** Calling a
  tool that requires a workspace anchor you do not have — `file_*`, `sandbox_*`,
  or Browser's `screenshot` / `pdf` / `snapshot` as an anonymous caller —
  returns the identical invalid-tool-name shape as a tool that does not exist.
  The response deliberately does not confirm the tool is there.
</Note>

Some failures carry a structured `data` payload rather than only a message:

| `data` key               | Meaning                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `ambiguous_commit: true` | The external effect **may** have committed. Do not blindly retry — the operation is not known to have failed |
| `run_superseded`         | A newer run replaced this one                                                                                |

## Timeouts

The gateway enforces a **240-second** request timeout, after which it returns
504\. Individual capabilities have their own, shorter limits — a WASM plugin's
execution timeout defaults to 30 seconds and is capped at 120.

## Related

* [tools/list](/docs/reference/mcp/tools-list)
* [MCP overview](/docs/reference/mcp/overview)
* [Errors and rate limits](/docs/reference/errors-and-rate-limits)
