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

# Set up the MCP server

> Install the Node or Python client, set credentials, wire the server into Claude Code, Claude Desktop or Cursor, or call the JSON-RPC endpoint directly.

Install the client, set your credentials, and connect the server to your agent. Covers the Node and Python clients, wiring into Claude Code, Claude Desktop and Cursor, and calling the backend endpoint directly.

## Install the client

The client ships for both Node.js and Python. Both expose the same `gateway-mcp serve` command.

<Tabs>
  <Tab title="Node.js">
    Install the npm package. Use `npx` to run it without a global install, or install globally for a persistent `gateway-mcp` command.

    ```bash theme={null}
    npm install @withgateway/mcp
    ```
  </Tab>

  <Tab title="Python">
    Install the PyPI package with the `server` extra. The base package is a client library; the extra adds the MCP server.

    ```bash theme={null}
    pip install "gateway-mcp[server]"
    ```
  </Tab>
</Tabs>

## Set your credentials

The server reads credentials from environment variables and picks its authentication mode from which ones are present.

| Variable | Required | Description |
| - | - | - |
| `GATEWAY_URL` | No | Your Surface Area instance URL. Defaults to `https://withgateway.ai` (v0.3.1+). |
| `GATEWAY_API_TOKEN` | PAT mode | Personal access token, starts with `pat_`. |
| `GATEWAY_PROJECT_ID` | No | PAT mode: the project a tool acts on when it omits `project_id`. |
| `GATEWAY_PUBLIC_KEY` | BasicAuth mode | Project public key, starts with `pk-lf-`. |
| `GATEWAY_SECRET_KEY` | BasicAuth mode | Project secret key, starts with `sk-lf-`. |

When both keys and a token are set, the server uses the key pair (BasicAuth). Set only the variables for the mode you want.

PAT access is per-project: the server exposes your accessible projects and scopes every request to `/api/public/mcp` with a `?project_id=<id>` query parameter, which it adds automatically. Access is checked on every call, so a project you are invited to later works without restarting the server. Calling the HTTP endpoint directly with a PAT (without the npm server) means passing `?project_id=` yourself — the endpoint rejects PAT requests without it.

<Info>
  Never hardcode keys or tokens in your code or commit them to source control. Keep them in environment variables or a secrets manager.
</Info>

## Run the server over stdio

The `serve` command starts the server on stdio, the transport every MCP client speaks. Prefix the command with the credentials for your mode.

<Tabs>
  <Tab title="Node.js">
    ```bash theme={null}
    # PAT mode (multi-project)
    GATEWAY_API_TOKEN=pat_... npx @withgateway/mcp serve

    # BasicAuth mode (single project)
    GATEWAY_PUBLIC_KEY=pk-lf-... GATEWAY_SECRET_KEY=sk-lf-... npx @withgateway/mcp serve

    # Point at a self-hosted or local instance
    GATEWAY_URL=http://localhost:3000 GATEWAY_API_TOKEN=pat_... npx @withgateway/mcp serve
    ```
  </Tab>

  <Tab title="Python">
    ```bash theme={null}
    # PAT mode (multi-project)
    GATEWAY_API_TOKEN=pat_... gateway-mcp serve

    # BasicAuth mode (single project)
    GATEWAY_PUBLIC_KEY=pk-lf-... GATEWAY_SECRET_KEY=sk-lf-... gateway-mcp serve

    # Point at a self-hosted or local instance
    GATEWAY_URL=http://localhost:3000 GATEWAY_API_TOKEN=pat_... gateway-mcp serve
    ```
  </Tab>
</Tabs>

On startup the server prints, to standard error, which projects it can reach and how many tools it registered. In PAT mode it lists every accessible project; in BasicAuth mode it reports the single project scoped by the keys.

## Wire it into your MCP client

MCP clients launch the server as a subprocess defined in an `mcpServers` block. Point the `command` at the client you installed and pass credentials through `env`.

<Tabs>
  <Tab title="Node.js">
    Add a `gateway` entry to your client config (`claude_desktop_config.json` for Claude Desktop, `.mcp.json` for Claude Code, `.cursor/mcp.json` for Cursor):

    ```json theme={null}
    {
      "mcpServers": {
        "gateway": {
          "command": "npx",
          "args": ["@withgateway/mcp", "serve"],
          "env": {
            "GATEWAY_API_TOKEN": "pat_..."
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    Add a `gateway` entry to your client config (`claude_desktop_config.json` for Claude Desktop, `.mcp.json` for Claude Code, `.cursor/mcp.json` for Cursor):

    ```json theme={null}
    {
      "mcpServers": {
        "gateway": {
          "command": "gateway-mcp",
          "args": ["serve"],
          "env": {
            "GATEWAY_API_TOKEN": "pat_..."
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

To scope the server to a single project instead, replace `GATEWAY_API_TOKEN` with `GATEWAY_PUBLIC_KEY` and `GATEWAY_SECRET_KEY`. Add `GATEWAY_URL` to the `env` block when you target a self-hosted or local instance.

<Info>
  Restart your MCP client after editing its config so it relaunches the server. Then ask the agent to list its tools, or run `describe_project`, to confirm the connection.
</Info>

## Call the backend endpoint directly

The local proxy is optional. The backend exposes one JSON-RPC 2.0 endpoint, `POST /api/public/mcp`, callable with any HTTP client. Set the `Accept` header to `application/json, text/event-stream` -- the endpoint may answer with plain JSON or a server-sent-events stream.

<Steps>
  <Step title="Build the BasicAuth header">
    Base64-encode `public_key:secret_key` and send it as a `Basic` authorization header.

    ```bash theme={null}
    echo -n "pk-lf-...:sk-lf-..." | base64
    ```
  </Step>

  <Step title="List the available tools">
    Send a JSON-RPC `tools/list` request. The response contains every tool the instance currently exposes, with its input schema.

    ```bash theme={null}
    curl https://withgateway.ai/api/public/mcp \
      -H "Authorization: Basic $(echo -n 'pk-lf-...:sk-lf-...' | base64)" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
    ```
  </Step>
</Steps>

For personal access token auth, send `Authorization: Bearer pat_...` instead of the Basic header and append the project to the URL as `?project_id=<id>`. Call a tool with `tools/call`, passing the tool name and arguments in `params`.

## Next steps

* [Tool Reference](./tools) -- every tool the server exposes and its key inputs.
* [Getting started with worlds](/worlds/getting-started) -- the world-building workflow, with each step's MCP twin named.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.