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

# MCP

> Connect all StackOne platform actions directly to LLM clients via the Model Context Protocol

The **[Model Context Protocol (MCP)](https://modelcontextprotocol.io)** is an open protocol that standardizes how AI applications provide context to LLMs.

StackOne provides a **pre-built MCP server** for each linked account, giving your AI agents direct access to thousands of actions across hundreds of [connectors](/connectors/introduction). Use it from your product's backend, from agent frameworks, or from the clients your users already run — ChatGPT, Claude, Cursor, and more.

<Tip>
  **Not sure if MCP is right for you?** Check out [Call Actions](/embed/call-actions/overview) to understand when to use MCP vs the Agent SDK vs A2A.
</Tip>

<Accordion title="MCP: Understanding the Protocol" icon="graduation-cap">
  **What is MCP?** The Model Context Protocol is an open standard originally developed by Anthropic and now adopted across the ecosystem — Claude, ChatGPT, Cursor, and most agent frameworks ship MCP clients. It defines how an AI application discovers and calls tools exposed by a server, regardless of which model or framework it uses.

  **Why does MCP exist?** Without a standard protocol, every app-to-tool connection is a custom integration. MCP solves this with a single, universal interface: any MCP client can use any MCP server's tools with no integration code.

  **How does it work?** MCP uses familiar web standards: JSON-RPC 2.0 messages over an HTTP transport. A client initializes a session, calls `tools/list` to discover what the server offers (each tool has a name, description, and JSON Schema), and `tools/call` to run one. Servers can also expose prompts and resources, though tools are the part StackOne uses.

  **MCP vs A2A**: These protocols are complementary, not competing. MCP standardizes how agents connect to **tools** - stateless functions like calculators or database queries. A2A standardizes how agents communicate with **other agents** - autonomous systems that can reason, plan, and have multi-turn conversations. Use MCP when you need tools; use A2A when you need to collaborate with other agents.
</Accordion>

<Accordion title="How StackOne MCP works" icon="layer-group">
  The StackOne MCP Server dynamically generates its tool catalog based on your account's configured connectors and enabled actions. Authentication to third-party providers is completely abstracted — you only need your StackOne API key and account ID. One linked account = one server endpoint; switch accounts by changing `x-account-id`.

  ```mermaid theme={null}
  flowchart LR
      Client[LLM Client or Agent] <-->|MCP Streamable HTTP| StackOneMCP[StackOne MCP Server]
      StackOneMCP <-->|tools/list| Toolset[StackOne Tool Catalog]
      StackOneMCP <-->|tools/call| Providers[(Connected SaaS APIs)]
      IntegrationConfig[Connector Profile & Account Settings] -->|Defines available tools| Toolset

      style StackOneMCP fill:#10b981,stroke:#059669,color:#fff
      style Toolset fill:#10b981,stroke:#059669,color:#fff
      style IntegrationConfig fill:#10b981,stroke:#059669,color:#fff
  ```

  The server speaks the Streamable HTTP transport — HTTPS only, POST for all operations, no SSE, stateless. Behind the scenes, tool calls route through the same engine and actions as every other protocol StackOne offers.

  StackOne tools aren't direct wrappers to single API endpoints. Many are mapped to high-value, context-optimized actions tailored to common business use cases.
</Accordion>

<Note>
  Looking to use connectors inside an existing Agent Clients? See the [Agent Setup](/connect/agent-setup/overview) walkthroughs (e.g. [Claude Desktop](/connect/agent-setup/claude-desktop), [Claude Code](/connect/agent-setup/claude-code)) for ready-to-paste configs.
</Note>

## Calling actions

Before starting you need to have followed the previous setup steps described in the [Getting Started](/embed/getting-started). Then the full protocol round-trip with cURL:

<Steps>
  <Step title="Build your authentication headers">
    Every request goes to `https://api.stackone.com/mcp` with these headers:

    ```bash theme={null}
    Authorization: Basic <BASE64_ENCODED_STACKONE_API_KEY>
    x-account-id: <ACCOUNT_ID>
    Content-Type: application/json
    Accept: application/json,text/event-stream
    ```

    <Warning>
      **The `Accept: application/json,text/event-stream` header is mandatory** — required by the MCP specification itself, on every request, with both formats listed. Without it you'll receive `406 Not Acceptable`. ([MCP spec — Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports))
    </Warning>

    To create the Basic auth token, append a colon to your API key, then base64 encode (see the [API Keys guide](/embed/api-keys) if you need to generate a new key):

    <CodeGroup>
      ```bash cURL theme={null}
      # -u auto-encodes to base64
      curl -u "$STACKONE_API_KEY:" https://api.stackone.com/mcp ...
      ```

      ```typescript TypeScript theme={null}
      const encoded = Buffer.from(`${apiKey}:`).toString('base64');
      fetch(url, { headers: { 'Authorization': `Basic ${encoded}` } });
      ```

      ```python Python theme={null}
      import base64
      encoded = base64.b64encode(f"{api_key}:".encode()).decode()
      headers = {'Authorization': f'Basic {encoded}'}
      ```
    </CodeGroup>

    Account IDs are on each linked account under **Accounts**, or via the [List Accounts endpoint](/platform/api-reference/accounts/list-accounts).

    For clients that can't set custom headers, the account ID can fall back to a query parameter: `https://api.stackone.com/mcp?x-account-id=<ACCOUNT_ID>` (the header wins if both are present). The optional `MCP-Protocol-Version` header is handled automatically by most clients — StackOne supports the recent protocol revisions.
  </Step>

  <Step title="Initialize the connection">
    ```bash theme={null}
    curl -X POST https://api.stackone.com/mcp \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>' \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json, text/event-stream' \
      -d '{
        "jsonrpc": "2.0",
        "id": "init-1",
        "method": "initialize",
        "params": {
          "clientInfo": { "name": "my-client", "version": "1.0.0" },
          "protocolVersion": "2025-06-18",
          "capabilities": {}
        }
      }'
    ```

    A successful response also confirms your authentication is configured correctly.
  </Step>

  <Step title="List available tools">
    ```bash theme={null}
    curl -X POST https://api.stackone.com/mcp \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>' \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json, text/event-stream' \
      -d '{
        "jsonrpc": "2.0",
        "id": "tools-1",
        "method": "tools/list"
      }'
    ```
  </Step>

  <Step title="Call a tool">
    ```bash theme={null}
    curl -X POST https://api.stackone.com/mcp \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>' \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json, text/event-stream' \
      -d '{
        "jsonrpc": "2.0",
        "id": "call-1",
        "method": "tools/call",
        "params": {
          "name": "bamboohr_list_employees",
          "arguments": { "limit": 10 }
        }
      }'
    ```
  </Step>
</Steps>

## Test it

<CardGroup cols={3}>
  <Card title="AI Playground" icon="play" href="/embed/call-actions/troubleshooting/playground">
    No setup. Test with natural language instantly.
  </Card>

  <Card title="Postman" icon="circle-nodes" href="/embed/call-actions/troubleshooting/postman">
    Fork the StackOne collection and test MCP requests.
  </Card>

  <Card title="MCP Inspector" icon="magnifying-glass" href="/embed/call-actions/mcp/troubleshooting#mcp-inspector">
    Inspect the raw protocol exchange while debugging.
  </Card>
</CardGroup>

## Tool discovery modes

See [Tool Discovery](/features/tool-discovery) for a full run-down between different tool discovery methods.

The `tool-mode` query parameter controls how tools are registered — append `?tool-mode=search_execute` to the endpoint URL to switch:

| Mode                   | Tools registered          | Best for                                                                              |
| ---------------------- | ------------------------- | ------------------------------------------------------------------------------------- |
| `individual` (default) | One tool per action       | Small action sets (under \~50 tools), or when the agent should see every tool upfront |
| `search_execute`       | 2 tools: search + execute | Large catalogs, context window constraints                                            |

In `search_execute` mode the server registers exactly two tools:

| Tool                        | Description                                                                                                                                              |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{provider}_search_actions` | Takes a natural language `query` (optional `top_k` — default 10, max 50) and returns ranked matching actions with their `action_id` and similarity score |
| `{provider}_execute_action` | Executes any action by its `action_id`, with optional `path`, `query`, `body`, and `headers`                                                             |

<Warning>
  The agent **must** call `search_actions` first — `action_id` values are discovered at runtime based on what's enabled for the account. Never hardcode them.
</Warning>

## Per-user connections

Every end-user of your product maps to a [linked account](/gateway/concepts/linked-accounts) — your backend holds the API key, and each user's tools are addressed by their account ID. Two ways to wire MCP into your product:

* **Server-side** — your backend calls the MCP endpoint with your API key and the end-user's `x-account-id`. The key never leaves your infrastructure; switching users is just switching the header.
* **Token URLs** — for user-facing clients that connect directly, hand out a token URL (`https://api.stackone.com/mcp?token=<session_token>`) generated in the dashboard: open the connector and click **Use in Agent**. Your API key stays on the backend.

Your end-users can also bring their own MCP clients: give them a token URL and point them at the per-client walkthroughs in [Agent Setup](/connect/agent-setup/overview) — ChatGPT, Claude, Cursor, and more.

## Framework guides

Most frameworks support MCP natively:

<CardGroup cols={3}>
  <Card title="Anthropic SDK" icon="message" href="/embed/call-actions/mcp/anthropic-sdk" />

  <Card title="OpenAI Agents SDK" icon="brain" href="/embed/call-actions/mcp/openai-agents-sdk" />

  <Card title="Vercel AI SDK" icon="triangle" href="/embed/call-actions/mcp/vercel-ai-sdk" />

  <Card title="LangChain" icon="link" href="/embed/call-actions/mcp/langchain" />

  <Card title="LangGraph" icon="diagram-project" href="/embed/call-actions/mcp/langgraph" />

  <Card title="CrewAI" icon="users" href="/embed/call-actions/mcp/crewai" />

  <Card title="Pydantic AI" icon="python" href="/embed/call-actions/mcp/pydantic-ai" />

  <Card title="Google ADK" icon="google" href="/embed/call-actions/mcp/google-adk" />

  <Card title="Azure AI Foundry" icon="microsoft" href="/embed/call-actions/mcp/azure-agents" />
</CardGroup>
