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

# MCP Server

> Connect your AI assistant to the SendPilot docs — Claude, Codex, Gemini, Cursor, or your own code

SendPilot hosts a **Model Context Protocol (MCP)** server that connects your AI assistant — Claude, OpenAI Codex, Gemini, Cursor, VS Code Copilot, or your own application — directly to the SendPilot documentation. Your assistant can look up endpoints, schemas, and webhook payloads in real time, so the integration code it writes against our API stays accurate.

<Info>
  **Beta.** This MCP server is in beta and currently provides **documentation search and reading** only. A full version that exposes the SendPilot API as **callable tools** — create campaigns, add leads, send messages, and more, all directly from your assistant — is coming soon. For now, your assistant reads the docs here and makes API calls itself using your key (see [Making API calls](#making-api-calls)).
</Info>

## What is the MCP server?

The Model Context Protocol is an open standard that lets AI assistants connect to external tools and knowledge. SendPilot hosts its MCP server at:

```
https://docs.sendpilot.ai/mcp
```

It uses **streamable HTTP** transport and exposes two documentation tools:

| Tool                                   | What it does                                                                       |
| -------------------------------------- | ---------------------------------------------------------------------------------- |
| `search_send_pilot_api`                | Searches the docs and returns relevant snippets with titles and direct links       |
| `query_docs_filesystem_send_pilot_api` | Reads documentation pages directly (`head`, `cat`, `rg`, `tree`) for exact lookups |

<Note>
  The MCP server is **read-only**: it searches and reads your documentation. It does **not** call the SendPilot API. Connecting requires **no API key** — see [Making API calls](#making-api-calls) for how your assistant actually runs requests.
</Note>

## Connect the MCP server

Pick your client below. Every client points at the same URL: `https://docs.sendpilot.ai/mcp`. No API key or header is needed to connect.

<Tabs>
  <Tab title="Claude Code">
    Run the following command in your terminal:

    ```bash theme={null}
    claude mcp add --transport http sendpilot https://docs.sendpilot.ai/mcp
    ```

    Verify with `claude mcp list`, then start a session and ask Claude to search the SendPilot docs.
  </Tab>

  <Tab title="Claude Desktop">
    Open **Settings → Developer → Edit Config** and add the server:

    ```json theme={null}
    {
      "mcpServers": {
        "sendpilot": {
          "url": "https://docs.sendpilot.ai/mcp"
        }
      }
    }
    ```

    Restart Claude Desktop. The SendPilot tools appear in the tools menu.
  </Tab>

  <Tab title="Claude web & Cowork">
    On **claude.ai**, **Claude Cowork**, and the mobile apps, the SendPilot server is added as a **custom connector** through the UI rather than a config file:

    1. Open **Settings → Connectors** (on claude.ai: **Customize → Connectors**).
    2. Click **Add custom connector**.
    3. Name it `SendPilot` and enter the URL `https://docs.sendpilot.ai/mcp`.
    4. Save. The SendPilot tools become available in your chats.

    <Info>
      Custom connectors connect from Anthropic's cloud, so the server must be reachable over public HTTPS — SendPilot's MCP server is. Available on Free, Pro, Max, Team, and Enterprise plans (free users get one custom connector).
    </Info>
  </Tab>

  <Tab title="OpenAI Codex">
    Edit `~/.codex/config.toml` and add the server:

    ```toml theme={null}
    [mcp_servers.sendpilot]
    url = "https://docs.sendpilot.ai/mcp"
    ```

    Confirm it's registered with `codex mcp list`.
  </Tab>

  <Tab title="Gemini CLI">
    Add the server to `~/.gemini/settings.json` (or a project-level `.gemini/settings.json`). Note Gemini uses the `httpUrl` key for streamable HTTP servers:

    ```json theme={null}
    {
      "mcpServers": {
        "sendpilot": {
          "httpUrl": "https://docs.sendpilot.ai/mcp"
        }
      }
    }
    ```

    Restart the Gemini CLI and run `/mcp` to confirm SendPilot is connected.
  </Tab>

  <Tab title="Cursor">
    Add the server to `~/.cursor/mcp.json` (or the project-level `.cursor/mcp.json`):

    ```json theme={null}
    {
      "mcpServers": {
        "sendpilot": {
          "url": "https://docs.sendpilot.ai/mcp"
        }
      }
    }
    ```

    Reload Cursor and confirm **SendPilot** shows up under **Settings → MCP**.
  </Tab>

  <Tab title="VS Code">
    Create `.vscode/mcp.json` in your workspace:

    ```json theme={null}
    {
      "servers": {
        "sendpilot": {
          "type": "http",
          "url": "https://docs.sendpilot.ai/mcp"
        }
      }
    }
    ```

    Open Copilot Chat in **Agent** mode and the SendPilot tools become available.
  </Tab>

  <Tab title="Other clients">
    Any MCP-compatible client works. Provide these values wherever the client asks for server details:

    | Setting        | Value                           |
    | -------------- | ------------------------------- |
    | Transport      | Streamable HTTP                 |
    | URL            | `https://docs.sendpilot.ai/mcp` |
    | Authentication | None                            |

    Most JSON-based clients use either a `url` (Claude, Cursor, VS Code) or `httpUrl` (Gemini) field under an `mcpServers` object.
  </Tab>
</Tabs>

### Verify the connection

Ask your assistant a question that requires the docs, for example:

> *"Using the SendPilot MCP, what's the request body for creating a lead extractor campaign?"*

If it returns the correct endpoint (`POST /v1/lead-extractor/campaigns`) with the `name`, `urls`, `limit`, `url_type`, and `mode` fields, the server is connected.

## Making API calls

This is the part people get wrong, so it's worth being explicit:

<Warning>
  The MCP server only **searches your docs** — it never calls the SendPilot API. Putting your API key in the MCP config does **nothing**; the server ignores it. To let your assistant actually run API requests, give your key to the **assistant's environment**, not the MCP server.
</Warning>

The two pieces work as separate channels:

1. **The MCP server** teaches the assistant your API — it reads the docs to learn the right endpoint, fields, and auth.
2. **Your assistant** then writes and runs the request itself (a script, `curl`, etc.), authenticating with an API key from **its own runtime**.

So the setup is:

<Steps>
  <Step title="Create an API key">
    In the SendPilot dashboard, go to **Integrations → API Keys**, click **Create API Key**, and copy the `sp_live_...` value.

    <Warning>
      Keys are shown once at creation. Store yours immediately.
    </Warning>
  </Step>

  <Step title="Give the key to your assistant's environment">
    Set it as an environment variable wherever your assistant runs code — for example, in the terminal where you run Claude Code or Cursor:

    ```bash theme={null}
    export SENDPILOT_API_KEY=sp_live_...
    ```

    Then your prompts can say *"read my API key from `SENDPILOT_API_KEY`"* and the generated code will authenticate with the `X-API-Key` header. See [Authentication](/api-reference/authentication) for details.
  </Step>
</Steps>

<Note>
  Only give your API key to an assistant/environment you trust — that key can take real, billable actions (sending messages, spending credits). The key, not the MCP server, is the access boundary.
</Note>

## Use it in code

You don't need a chat client — you can connect to the MCP server programmatically with the official MCP SDKs to build your own agents or tools on top of the SendPilot docs. No API key is needed to connect.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

  const client = new Client({ name: "my-app", version: "1.0.0" });
  const transport = new StreamableHTTPClientTransport(
    new URL("https://docs.sendpilot.ai/mcp"),
  );

  await client.connect(transport);

  // List available tools
  const { tools } = await client.listTools();
  console.log(tools.map((t) => t.name));

  // Search the SendPilot docs
  const result = await client.callTool({
    name: "search_send_pilot_api",
    arguments: { query: "create a lead extractor campaign" },
  });
  console.log(result.content);

  await client.close();
  ```

  ```python Python theme={null}
  import asyncio
  from mcp import ClientSession
  from mcp.client.streamable_http import streamablehttp_client


  async def main():
      async with streamablehttp_client("https://docs.sendpilot.ai/mcp") as (
          read,
          write,
          _,
      ):
          async with ClientSession(read, write) as session:
              await session.initialize()

              # List available tools
              tools = await session.list_tools()
              print([t.name for t in tools.tools])

              # Search the SendPilot docs
              result = await session.call_tool(
                  "search_send_pilot_api",
                  {"query": "create a lead extractor campaign"},
              )
              print(result.content)


  asyncio.run(main())
  ```
</CodeGroup>

<Tip>
  Install the SDKs with `npm install @modelcontextprotocol/sdk` (TypeScript) or `pip install mcp` (Python).
</Tip>

## Scenarios & example prompts

Once the MCP server is connected (and your assistant has your API key in its environment), talk to it in plain language. The prompts below are copy-paste ready — they tell the assistant to use the SendPilot MCP so the output matches the current API.

<AccordionGroup>
  <Accordion title="Build an integration from scratch" icon="hammer">
    > *"Use the SendPilot MCP to find the endpoint for creating a lead extractor campaign, then write a Node.js script that creates one from a LinkedIn people-search URL, polls the status endpoint until it completes, and prints the extracted leads. Read my API key from `SENDPILOT_API_KEY`."*

    The assistant looks up `POST /v1/lead-extractor/campaigns`, the `/status` and `/results` endpoints, and the exact field names before writing code.
  </Accordion>

  <Accordion title="Discover what the API can do" icon="compass">
    > *"Using the SendPilot MCP, list the available endpoint groups and give me a one-line summary of what each one is for."*

    Great first prompt to understand campaigns, leads, inbox, lead database, lead extractor, and webhooks at a glance.
  </Accordion>

  <Accordion title="Generate types from webhook payloads" icon="code">
    > *"Search the SendPilot docs for the `reply.received` webhook payload and generate a TypeScript interface for it. Include every field shown in the example payload."*

    The assistant reads the webhook event page and produces types that match the real payload shape.
  </Accordion>

  <Accordion title="Map API fields to your CRM" icon="arrows-left-right">
    > *"Use the SendPilot MCP to find all fields returned by the lead extractor results endpoint, then map them to my HubSpot contact properties (first name, last name, company, job title, LinkedIn URL)."*

    Useful for building sync jobs without guessing field names.
  </Accordion>

  <Accordion title="Debug a failing request" icon="bug">
    > *"I'm getting a 401 from `GET /v1/campaigns`. Use the SendPilot MCP to look up the authentication requirements and tell me what's wrong with this request: `curl https://api.sendpilot.ai/v1/campaigns -H 'Authorization: Bearer abc'`."*

    The assistant finds that SendPilot expects an `X-API-Key` header, not a bearer token, and corrects the request.
  </Accordion>

  <Accordion title="Add leads to a campaign" icon="user-plus">
    > *"Write a Python function that adds a list of leads to a SendPilot campaign. Confirm the exact request body and required fields with the SendPilot MCP before writing the code."*

    The assistant verifies `POST /v1/leads` (including the required `campaignId`) so the payload is correct the first time.
  </Accordion>
</AccordionGroup>

<Tip>
  The pattern that works best: ask the assistant to **"confirm the endpoint and request body with the SendPilot MCP before writing code."** This keeps generated integrations aligned with the live API instead of relying on the model's memory.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="The MCP server doesn't show up in my assistant">
    Confirm the URL is exactly `https://docs.sendpilot.ai/mcp` and that your client supports HTTP-transport MCP servers. Remember Gemini uses `httpUrl` while Claude, Cursor, and VS Code use `url`. Restart the client after editing its config file.
  </Accordion>

  <Accordion title="My assistant can read the docs but its API calls fail">
    The MCP server only searches docs — it doesn't make API calls. Your assistant runs those itself, so make sure your API key is available in its environment (e.g. `SENDPILOT_API_KEY`), not in the MCP config. See [Making API calls](#making-api-calls).
  </Accordion>

  <Accordion title="I get a 401 Unauthorized from the API">
    Check that the request sends an `X-API-Key` header with a valid `sp_live_...` key (SendPilot does not use bearer tokens). See [Authentication → Error Responses](/api-reference/authentication#error-responses).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    API key best practices, scoping, and error handling
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Browse every available endpoint
  </Card>
</CardGroup>
