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

# Installation

> Configure the SenderKit MCP server in your AI client.

This page covers all supported ways to connect to SenderKit's MCP server:
OAuth (for clients that handle auth themselves), the hosted API-key endpoint,
and the local stdio server bundled in the CLI.

## Connect via OAuth

If your client handles auth through OAuth rather than a manual API key (Claude
on the web, desktop, or mobile; ChatGPT custom connectors; or any other
OAuth-compatible MCP client), you don't need an API key — the client drives the
auth flow through SenderKit's OAuth 2.1 authorization server.

<Steps>
  <Step title="Find the custom connector / MCP section in your client">
    In Claude, this is typically **Customise → Add custom connector**. Other
    clients have similar settings screens.
  </Step>

  <Step title="Add `https://mcp.senderkit.com` as the server URL">
    The client will discover SenderKit's OAuth endpoints automatically.
  </Step>

  <Step title="Sign in with your SenderKit account">
    You'll be redirected to senderkit.com to authenticate.
  </Step>

  <Step title="Choose a workspace and mode on the consent screen">
    Pick which workspace the agent should act on, and whether it should use
    **live** mode (real delivery) or **test** mode (recorded but not sent).
    You can revoke the connection at any time from **Dashboard → Settings →
    Connected Apps**.
  </Step>
</Steps>

<Note>
  The workspace and mode you choose at consent time are fixed for that
  connection. To switch, revoke and reconnect. Call
  [`senderkit_context`](/mcp/tools#senderkit_context) from within a session to
  confirm which workspace and mode are active.
</Note>

## Prerequisites (API-key connection)

* A SenderKit API key. Create one in the
  [dashboard](https://senderkit.com/app/dashboard); see [Authentication](/authentication).
  The same key prefix (`sk_live_` / `sk_test_`) controls live vs test mode.
* For local stdio mode: [`@senderkit/cli`](/cli/installation) installed and on
  your `PATH`.

## Hosted or local?

|                  | Hosted                               | Local stdio                 |
| ---------------- | ------------------------------------ | --------------------------- |
| Endpoint         | `https://mcp.senderkit.com`          | `senderkit mcp` subprocess  |
| Auth             | `Authorization: Bearer <key>` header | `SENDERKIT_API_KEY` env var |
| Network hop      | yes                                  | none                        |
| Requires Node.js | no                                   | yes (via the CLI)           |

The tools and behavior are identical. Pick whichever fits your setup.

## Auto-install with the CLI

If you have the CLI installed, `senderkit mcp install` writes the config for
you. By default it configures the **hosted endpoint** with OAuth — no API key
is stored; your client handles sign-in. Pass `--client <name>` to target a
single client instead of every detected one.

```bash theme={null}
# Hosted OAuth config for every detected client (default — no API key stored)
senderkit mcp install

# Hosted with API key bearer auth instead of OAuth
senderkit mcp install --api-key-auth

# Local stdio subprocess config
senderkit mcp install --local

# Target one client
senderkit mcp install --client cursor

# Print the config to stdout instead of writing
senderkit mcp install --client claude-desktop --print
```

Supported `--client` values: `claude-code`, `claude-desktop`, `cursor`,
`windsurf`, `vscode`, `zed`, `codex`, `opencode`, or `all` (the default).

## Manual configuration

If you'd rather edit configuration files by hand, the tabs below show the exact
block per client.

<Tabs>
  <Tab title="Claude Code">
    Use `claude mcp add` — it writes to `~/.claude.json` under
    `projects.<cwd>.mcpServers.senderkit` (local scope) or the top-level
    `mcpServers.senderkit` (user scope).

    <CodeGroup>
      ```bash Hosted theme={null}
      claude mcp add --transport http --scope user senderkit \
        https://mcp.senderkit.com \
        --header "Authorization: Bearer $SENDERKIT_API_KEY"
      ```

      ```bash Local stdio theme={null}
      claude mcp add --scope user \
        --env SENDERKIT_API_KEY=$SENDERKIT_API_KEY \
        senderkit -- senderkit mcp
      ```
    </CodeGroup>

    Verify with `claude mcp list`, or `/mcp` from inside a Claude Code session.
  </Tab>

  <Tab title="Claude Desktop">
    Edit `claude_desktop_config.json`. Open it via **Claude → Settings →
    Developer → Edit Config**.

    Location:

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

    Claude Desktop only speaks stdio, so the hosted variant bridges through
    [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).

    <CodeGroup>
      ```json Hosted (via mcp-remote) theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "command": "npx",
            "args": [
              "-y",
              "mcp-remote",
              "https://mcp.senderkit.com",
              "--header",
              "Authorization: Bearer ${SENDERKIT_API_KEY}"
            ]
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "command": "senderkit",
            "args": ["mcp"],
            "env": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>

    Fully quit Claude Desktop and reopen it for the change to take effect —
    closing the window isn't enough.
  </Tab>

  <Tab title="Cursor">
    Edit `~/.cursor/mcp.json`.

    <CodeGroup>
      ```json Hosted theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "url": "https://mcp.senderkit.com",
            "headers": {
              "Authorization": "Bearer ${SENDERKIT_API_KEY}"
            }
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "command": "senderkit",
            "args": ["mcp"],
            "env": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Windsurf">
    Edit `~/.codeium/windsurf/mcp_config.json`. Windsurf's native remote MCP
    support is uneven, so the hosted variant bridges through `mcp-remote`.

    <CodeGroup>
      ```json Hosted (via mcp-remote) theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "command": "npx",
            "args": [
              "-y",
              "mcp-remote",
              "https://mcp.senderkit.com",
              "--header",
              "Authorization: Bearer ${SENDERKIT_API_KEY}"
            ]
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "mcpServers": {
          "senderkit": {
            "command": "senderkit",
            "args": ["mcp"],
            "env": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="VS Code">
    Edit `mcp.json` in your VS Code user directory.

    Location:

    * macOS: `~/Library/Application Support/Code/User/mcp.json`
    * Windows: `%APPDATA%\Code\User\mcp.json`
    * Linux: `~/.config/Code/User/mcp.json`

    VS Code uses the top-level key `servers` (not `mcpServers`) and requires a
    `type` field.

    <CodeGroup>
      ```json Hosted theme={null}
      {
        "servers": {
          "senderkit": {
            "type": "http",
            "url": "https://mcp.senderkit.com",
            "headers": {
              "Authorization": "Bearer ${SENDERKIT_API_KEY}"
            }
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "servers": {
          "senderkit": {
            "type": "stdio",
            "command": "senderkit",
            "args": ["mcp"],
            "env": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Zed">
    Edit `~/.config/zed/settings.json` — Zed calls them `context_servers`.

    <CodeGroup>
      ```json Hosted theme={null}
      {
        "context_servers": {
          "senderkit": {
            "url": "https://mcp.senderkit.com",
            "headers": {
              "Authorization": "Bearer ${SENDERKIT_API_KEY}"
            }
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "context_servers": {
          "senderkit": {
            "command": "senderkit",
            "args": ["mcp"],
            "env": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Codex">
    Edit `~/.codex/config.toml`. Codex has native streamable-HTTP MCP support
    with OAuth — sign in with `codex mcp login senderkit` after writing the
    config.

    <CodeGroup>
      ```toml Hosted (OAuth) theme={null}
      [mcp_servers.senderkit]
      url = "https://mcp.senderkit.com"
      ```

      ```toml Hosted (API key) theme={null}
      [mcp_servers.senderkit]
      url = "https://mcp.senderkit.com"
      bearer_token_env_var = "SENDERKIT_API_KEY"
      ```

      ```toml Local stdio theme={null}
      [mcp_servers.senderkit]
      command = "senderkit"
      args = ["mcp"]

      [mcp_servers.senderkit.env]
      SENDERKIT_API_KEY = "sk_test_…"
      ```
    </CodeGroup>
  </Tab>

  <Tab title="opencode">
    Edit `~/.config/opencode/opencode.json`.

    <CodeGroup>
      ```json Hosted theme={null}
      {
        "mcp": {
          "senderkit": {
            "type": "remote",
            "url": "https://mcp.senderkit.com",
            "enabled": true,
            "headers": {
              "Authorization": "Bearer ${SENDERKIT_API_KEY}"
            }
          }
        }
      }
      ```

      ```json Local stdio theme={null}
      {
        "mcp": {
          "senderkit": {
            "type": "local",
            "command": ["senderkit", "mcp"],
            "enabled": true,
            "environment": { "SENDERKIT_API_KEY": "sk_test_…" }
          }
        }
      }
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Self-hosting the HTTP server

If you'd rather not rely on the hosted endpoint, the CLI exposes the same
server over Streamable HTTP. Point your client at it the same way you'd point
at the hosted URL.

```bash theme={null}
# Listens on http://localhost:3000/mcp
senderkit mcp --http --port 3000
```

Each request still needs `Authorization: Bearer <key>`. The server is
stateless: every request authenticates independently, so a single process can
serve multiple users or workspaces.

## Troubleshooting

<AccordionGroup>
  <Accordion title="The server doesn't appear in my client.">
    Most clients only load MCP servers at startup. Fully quit and restart the
    client after editing config. For Claude Code, run `/mcp` to see the live
    list; for Claude Desktop, restart from the menu rather than just closing
    the window.
  </Accordion>

  <Accordion title="The client reports an authentication failure.">
    For **OAuth** clients (Claude web/desktop/mobile, etc.): the connection may
    have been revoked. Go to **Dashboard → Settings → Connected Apps**, revoke
    the entry for your client, and reconnect.

    For **hosted (API key)**, check that the `Authorization` header value is
    exactly `Bearer sk_live_…` or `Bearer sk_test_…` — no extra whitespace, no
    missing `Bearer ` prefix. The server returns `401` for any missing or
    unrecognized key. Revoked keys also return `401`; create a new key in the
    [dashboard](https://senderkit.com/app/dashboard).

    For **local stdio**, the server reads `SENDERKIT_API_KEY` from the
    environment passed to the subprocess (the `env` block in your client
    config, or your shell if you launch the client from a terminal). If the
    key isn't set, `senderkit mcp` exits at startup with
    `No SenderKit API key found`.
  </Accordion>

  <Accordion title="`senderkit: command not found` or `spawn senderkit ENOENT`.">
    The local stdio config calls the `senderkit` binary directly. Install the
    CLI globally (`npm install -g @senderkit/cli`) and confirm it's on your
    `PATH` with `which senderkit`. If your client launches outside your
    shell's `PATH` (Claude Desktop on macOS often does), use the absolute path
    in the `command` field — e.g. `/usr/local/bin/senderkit` — or switch to
    the hosted variant.
  </Accordion>

  <Accordion title="Hosted setup fails through `mcp-remote`.">
    `mcp-remote` requires Node.js 18+. Confirm with `node --version`. If `npx`
    is missing entirely, install Node from
    [nodejs.org](https://nodejs.org/), or switch to a client with native
    remote MCP support (Claude Code, Cursor, VS Code, Zed, Codex, opencode).
  </Accordion>

  <Accordion title="The agent can see tools but every call returns an error.">
    Look at the tool's error text — the server returns structured messages for
    invalid input (`invalid_request: …`), missing templates
    (`template_not_found: …`), rate limits (`rate_limited: …`), and 401s. The
    shape matches the [REST API](/api-reference/introduction), so anything in
    the API troubleshooting guide applies.
  </Accordion>
</AccordionGroup>

<CardGroup cols={2}>
  <Card title="Quickstart" icon="bolt" href="/mcp/quickstart">
    The fastest path: Claude Code, hosted, in five minutes.
  </Card>

  <Card title="Tools" icon="screwdriver-wrench" href="/mcp/tools">
    The full surface, parameter by parameter.
  </Card>
</CardGroup>
