> For the complete documentation index, see [llms.txt](https://docs.maetra.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maetra.io/mcp-server/end-to-end-example.md).

# End-to-end example

A complete flow over the MCP server: initialize, discover tools, request approval for an action, poll until the human decides, and scan content. Replace `https://mcp.maetra.io` with your [deployed MCP host](/mcp-server/overview-and-connection.md).

### 1. Initialize

```json
// → request
{
  "jsonrpc": "2.0", "id": 1, "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": { "name": "billing-bot", "version": "0.1.0" }
  }
}
```

```json
// ← response
{
  "jsonrpc": "2.0", "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": { "tools": {} },
    "serverInfo": { "name": "maetra-mcp", "version": "1.0.0" }
  }
}
```

### 2. Discover tools

```json
// → request
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
```

The result lists all seven tools with their input schemas — see the [Tools reference](/mcp-server/tools-reference.md).

### 3. Request approval

```json
// → request
{
  "jsonrpc": "2.0", "id": 3, "method": "tools/call",
  "params": {
    "name": "request_approval",
    "arguments": {
      "action": "transfer_funds",
      "agent_name": "billing-bot",
      "autonomy_level": "L3",
      "payload": { "amount": 5000, "currency": "USD", "to": "acct_9931" },
      "reasoning": "Refund exceeds the auto-approve limit."
    }
  }
}
```

```json
// ← response  (pending — a human must decide)
{
  "jsonrpc": "2.0", "id": 3,
  "result": {
    "content": [{ "type": "text", "text": "{ \"checkpoint_id\": \"cp_7Yh2Qa\", \"status\": \"pending\", ... }" }]
  }
}
```

`request_approval` returns immediately. Read the `checkpoint_id` and `status` from the result. If `status` is already terminal, skip to step 5.

### 4. Poll for the decision

Call `get_approval_status` in a loop — it long-polls up to 20 seconds per call, so you re-issue it until the status is terminal.

```json
// → request
{
  "jsonrpc": "2.0", "id": 4, "method": "tools/call",
  "params": {
    "name": "get_approval_status",
    "arguments": { "checkpoint_id": "cp_7Yh2Qa", "wait_seconds": 30 }
  }
}
```

```json
// ← response  (approved)
{
  "jsonrpc": "2.0", "id": 4,
  "result": {
    "content": [{ "type": "text", "text": "{ \"status\": \"approved\", \"decision_token\": \"eyJ...\", ... }" }]
  }
}
```

Proceed with the transfer only when `status` is `approved`. The [`decision_token`](/govern-api/decision-tokens.md) is your verifiable proof.

### 5. Scan content along the way

Before executing a tool call, screen it with `check_action`:

```json
// → request
{
  "jsonrpc": "2.0", "id": 5, "method": "tools/call",
  "params": {
    "name": "check_action",
    "arguments": {
      "scan_type": "tool_call",
      "tool_name": "http_request",
      "content": "{\"url\":\"https://paste.example.com\",\"body\":\"<PII>\"}"
    }
  }
}
```

The result carries the verdict (`safe` / `flagged` / `blocked`) and a `recommended_action` — honor it before proceeding.

### Batching

You can send steps as a single batched request — an array of JSON-RPC messages — and receive an array of responses:

```json
[
  { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "billing-bot", "version": "0.1.0" } } },
  { "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
]
```
