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

# Agent Tools (MCP)

> How @xentfi/mcp-sdk works, and how to connect it to every supported MCP client — Claude, Cursor, VS Code, ChatGPT, ElizaOS, CrewAI, Codex — plus remote HTTP deployment.

<Note>
  This page covers **concepts and client integrations** for `@xentfi/mcp-sdk`. For the tool-by-tool argument/return reference, see [Tools Reference](/agent/tools-reference) in the Agent tab.
</Note>

## Overview

`@xentfi/mcp-sdk` is XentFi's official **Model Context Protocol (MCP)** server — it exposes an agent's XentFi wallet, spend policy, and payments as 15 tools any MCP-compatible client can call directly, with no custom integration code.

```bash theme={null}
npm install @xentfi/mcp-sdk
```

```mermaid theme={null}
flowchart TB
    subgraph Client["MCP Client"]
        Claude[Claude Desktop / Code]
        Cursor[Cursor / VS Code]
        ChatGPT[ChatGPT connector]
        Custom[ElizaOS / CrewAI / Codex]
    end

    subgraph SDK["@xentfi/mcp-sdk"]
        Stdio[xentfi-mcp — stdio]
        Http[xentfi-mcp-http — Streamable HTTP]
        Tools[15 xentfi_* tools]
    end

    subgraph XentFi["XentFi Platform"]
        AgentSelf[Agent Self API]
        Policy[Policy Engine]
        Assets[Assets & Prices API]
    end

    Client --> SDK
    SDK --> Tools
    Tools --> XentFi
    Policy -.enforces limits on.-> AgentSelf
```

<CardGroup cols={2}>
  <Card title="🔑 One credential" icon="key">
    Your agent's Agent API Key authenticates every tool call — no separate OAuth flow to build.
  </Card>

  <Card title="🛡️ Server-side guardrails" icon="shield-check">
    Every payment is checked against the agent's XentFi Policy (limits, allowlists, allowed hours) before it executes — enforced by the API, not the client.
  </Card>

  <Card title="🔌 Two transports" icon="plug">
    `xentfi-mcp` (stdio) for local desktop clients, `xentfi-mcp-http` (Streamable HTTP) for remote and multi-tenant deployments.
  </Card>

  <Card title="🧩 Programmatic SDK" icon="code">
    Import `createXentfiMcpServer()` or the raw `XentfiClient` to embed XentFi tools in your own MCP server or agent framework.
  </Card>
</CardGroup>

Tools call the same `/v1/agent-self/*` routes documented in [API Reference](/api-reference/introduction) — the SDK doesn't add new backend behavior, it exposes that surface with agent-friendly names, descriptions, and error messages.

## Client integrations

Pick your client below. Every one ultimately needs the same two pieces of information: **command** `npx`, **args** `["-y", "@xentfi/mcp-sdk"]`, and **env** `XENTFI_AGENT_API_KEY`.

<AccordionGroup>
  <Accordion title="Claude Desktop & Claude Code" icon="bot">
    **Claude Desktop** — edit (Settings → Developer → Edit Config, or directly):

    * macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
    * Windows: `%APPDATA%\Claude\claude_desktop_config.json`
    * Linux: `~/.config/Claude/claude_desktop_config.json`

    ```json theme={null}
    {
        "mcpServers": {
            "xentfi": {
                "command": "npx",
                "args": [
                    "-y",
                    "@xentfi/mcp-sdk"
                ],
                "env": {
                    "XENTFI_AGENT_API_KEY": "sk_agent_xxx"
                }
            }
        }
    }
    ```

    Fully quit and reopen the app, open a new chat, and confirm `xentfi` appears with 15 tools.

    **Claude Code:**

    ```bash theme={null}
    claude mcp add xentfi -- npx -y @xentfi/mcp-sdk
    ```

    Set `XENTFI_AGENT_API_KEY` in the shell Claude Code runs in, or in the generated config's `env` block. Verify with `claude mcp list`.

    *Global install alternative:* `npm install -g @xentfi/mcp-sdk`, then use `"command": "xentfi-mcp"` instead of `npx`.

    *Troubleshooting:* no server showing → check Settings → Developer → Open Logs Folder for `[xentfi-mcp]` lines or a `Missing XENTFI_AGENT_API_KEY` error. Tool errors about a missing key → the `env` block isn't inside the `xentfi` entry.
  </Accordion>

  <Accordion title="Cursor" icon="mouse-pointer-2">
    Edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` in your repo root (project-only, useful for per-project Agent API keys):

    ```json theme={null}
    {
        "mcpServers": {
            "xentfi": {
                "command": "npx",
                "args": [
                    "-y",
                    "@xentfi/mcp-sdk"
                ],
                "env": {
                    "XENTFI_AGENT_API_KEY": "sk_agent_xxx"
                }
            }
        }
    }
    ```

    Check **Cursor Settings → MCP** for a green/active `xentfi` entry. Cursor spawns one subprocess per config entry and keeps it running for the session — restart only needed after editing `mcp.json`.

    For a key that can *read* but never move funds unattended, restrict the Policy attached to that agent's Agent API Key rather than relying on client-side restrictions — `xentfi_create_payment` is still callable by any client holding a valid key.
  </Accordion>

  <Accordion title="VS Code" icon="square-code">
    Create `.vscode/mcp.json`:

    ```json theme={null}
    {
        "servers": {
            "xentfi": {
                "type": "stdio",
                "command": "npx",
                "args": [
                    "-y",
                    "@xentfi/mcp-sdk"
                ],
                "env": {
                    "XENTFI_AGENT_API_KEY": "${input:xentfi_agent_api_key}"
                }
            }
        },
        "inputs": [
            {
                "id": "xentfi_agent_api_key",
                "type": "promptString",
                "description": "XentFi Agent API Key",
                "password": true
            }
        ]
    }
    ```

    Using `inputs` means VS Code prompts for the key once and stores it securely instead of writing it to a file you might commit.

    Command Palette → **MCP: List Servers** to confirm `xentfi` is running, then use Copilot Chat's **Agent** mode. Debug with **MCP: Show Server Output**.
  </Accordion>

  <Accordion title="ChatGPT (custom connector)" icon="message-circle">
    ChatGPT speaks MCP over **remote Streamable HTTP**, not stdio — deploy `xentfi-mcp-http` first (see [Remote HTTP Deployment](#remote-http-deployment) below), then:

    1. Configure a custom `Authorization: Bearer sk_agent_xxx` header in ChatGPT's connector setup.
    2. **Settings → Connectors → Advanced settings → Add custom connector**: Name `XentFi`, MCP Server URL `https://your-deployment/mcp`, auth via the custom headers above.
    3. Enable the connector via the "+"/tools menu in a chat.

    Every distinct ChatGPT user/workspace should get its **own** agent, Agent API Key, and Policy — the header is the credential that authorizes payments. Enable ChatGPT's tool-use/action-review setting for this connector so `xentfi_create_payment` calls are surfaced for confirmation before finalizing.
  </Accordion>

  <Accordion title="ElizaOS" icon="cpu">
    ElizaOS reaches MCP servers through the community MCP plugin (`@elizaos/plugin-mcp` or equivalent):

    ```bash theme={null}
    npm install @elizaos/plugin-mcp
    ```

    ```json theme={null}
    {
        "name": "MyTradingAgent",
        "plugins": [
            "@elizaos/plugin-mcp"
        ],
        "settings": {
            "mcp": {
                "servers": {
                    "xentfi": {
                        "type": "stdio",
                        "command": "npx",
                        "args": [
                            "-y",
                            "@xentfi/mcp-sdk"
                        ],
                        "env": {
                            "XENTFI_AGENT_API_KEY": "sk_agent_xxx"
                        }
                    }
                }
            }
        }
    }
    ```

    Since ElizaOS agents often act with minimal human review, set tight `perTransactionLimitUsd`/`dailyLimitUsd` and an `allowedRecipients` allowlist on the attached Policy, make sure your action logic sets `confirm: true` deliberately rather than reflexively, and call `xentfi_get_policy` in planning before large payments.
  </Accordion>

  <Accordion title="CrewAI" icon="users">
    CrewAI (Python) consumes MCP servers via `crewai-tools`' `MCPServerAdapter`:

    ```bash theme={null}
    pip install crewai crewai-tools
    ```

    ```python theme={null}
    import os
    from crewai import Agent, Task, Crew
    from crewai_tools import MCPServerAdapter
    from mcp import StdioServerParameters

    xentfi_params = StdioServerParameters(
        command="npx",
        args=["-y", "@xentfi/mcp-sdk"],
        env={**os.environ, "XENTFI_AGENT_API_KEY": os.environ["XENTFI_AGENT_API_KEY"]},
    )

    with MCPServerAdapter(xentfi_params) as xentfi_tools:
        agent = Agent(role="Treasury Operator", tools=xentfi_tools, ...)
        crew = Crew(agents=[agent], tasks=[...])
        crew.kickoff()
    ```

    For a two-step audit trail, split into a **planner agent** (decides what to pay, no payment tools) and an **executor agent** (only has `xentfi_create_payment`, calls it with `confirm: true` only after your own validation passes).

    Newer `crewai-tools` versions also support connecting `MCPServerAdapter` to a remote server over SSE/Streamable HTTP — point it at a shared `xentfi-mcp-http` deployment with an `Authorization: Bearer <agent-api-key>` header.
  </Accordion>

  <Accordion title="Codex CLI & OpenAI Agents SDK" icon="terminal">
    **Codex CLI** — `~/.codex/config.toml`:

    ```toml theme={null}
    [mcp_servers.xentfi]
    command = "npx"
    args = ["-y", "@xentfi/mcp-sdk"]
    [mcp_servers.xentfi.env]
    XENTFI_AGENT_API_KEY = "sk_agent_xxx"
    ```

    **OpenAI Agents SDK** (Python):

    ```python theme={null}
    from agents import Agent, Runner
    from agents.mcp import MCPServerStdio

    async with MCPServerStdio(params={
        "command": "npx", "args": ["-y", "@xentfi/mcp-sdk"],
        "env": {"XENTFI_AGENT_API_KEY": os.environ["XENTFI_AGENT_API_KEY"]},
    }) as xentfi_server:
        agent = Agent(name="Treasury Agent", mcp_servers=[xentfi_server])
        result = await Runner.run(agent, "List my XentFi wallets and their balances.")
    ```

    Both SDKs cache the tool list at connect time — restart/reconnect after rotating the Agent API Key. Combine the Agents SDK's tool-use approval hooks with `confirm: true` for a human-in-the-loop checkpoint on top of server-side Policy enforcement.
  </Accordion>

  <Accordion title="Any other MCP client" icon="puzzle">
    All any stdio-based client needs: command `npx`, args `["-y", "@xentfi/mcp-sdk"]`, env `XENTFI_AGENT_API_KEY`.

    To test without any client at all, use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

    ```bash theme={null}
    XENTFI_AGENT_API_KEY=sk_agent_xxx npx @modelcontextprotocol/inspector npx -y @xentfi/mcp-sdk
    ```
  </Accordion>
</AccordionGroup>

## Remote HTTP deployment

Use `xentfi-mcp-http` instead of the stdio server when you need a hosted, network-reachable MCP endpoint — for ChatGPT connectors, a shared team deployment, or any client that only supports remote servers.

```mermaid theme={null}
sequenceDiagram
    participant Agent as MCP Client (ChatGPT, etc.)
    participant HTTP as xentfi-mcp-http
    participant API as XentFi API

    Agent->>HTTP: POST /mcp<br/>Authorization: Bearer sk_agent_xxx
    HTTP->>HTTP: Build fresh McpServer + XentfiClient<br/>bound to this request's key
    HTTP->>API: tools/call → /v1/agent-self/...
    API-->>HTTP: response
    HTTP-->>Agent: MCP tool result
    HTTP->>HTTP: Tear down server + transport
```

It runs **stateless**: every request builds a fresh MCP server + client pair bound to that request's own credentials, then tears it down. One process safely serves many agents/organizations at once, with no session state to scale.

```bash theme={null}
npm install @xentfi/mcp-sdk
npx xentfi-mcp-http
# Listening on http://localhost:8787/mcp (health check: /healthz)
```

Every request must carry its own credentials:

```
Authorization: Bearer <agent-api-key>
```

<CodeGroup>
  ```dockerfile Dockerfile theme={null}
  FROM node:20-slim
  WORKDIR /app
  RUN npm install @xentfi/mcp-sdk
  EXPOSE 8787
  CMD ["npx", "xentfi-mcp-http"]
  ```

  ```bash Build & run theme={null}
  docker build -t xentfi-mcp-http .
  docker run -p 8787:8787 xentfi-mcp-http
  ```
</CodeGroup>

<Note>
  Put this behind a TLS-terminating reverse proxy — ChatGPT requires HTTPS. Fly.io, Render, and Railway all provision HTTPS automatically.
</Note>

| Variable                   | Default | Purpose                    |
| -------------------------- | ------- | -------------------------- |
| `PORT` / `XENTFI_MCP_PORT` | `8787`  | Port to listen on.         |
| `XENTFI_MCP_PATH`          | `/mcp`  | Path for the MCP endpoint. |

### Programmatic embedding

```ts theme={null}
import { createXentfiMcpServer } from "@xentfi/mcp-sdk";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";

app.post("/mcp", async (req, res) => {
  const apiKey = req.header("authorization")?.replace(/^Bearer\s+/i, "");
  if (!apiKey) return res.status(401).json({ error: "missing agent api key" });

  const server = createXentfiMcpServer({ apiKey });
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  res.on("close", () => { transport.close(); server.close(); });

  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});
```

## Related

<CardGroup cols={3}>
  <Card title="Tools Reference" icon="list" href="/agent/tools-reference">
    Every `xentfi_*` tool, arguments, and return shape.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/agent/quickstart">
    Get credentials and make your first call.
  </Card>

  <Card title="x402 guide" icon="bolt" href="/essentials/x402">
    The other way an agent can transact — pay per call.
  </Card>
</CardGroup>
