# Create a custom MCP

import { Steps } from "@astrojs/starlight/components"
import Prereqs from "@docs/Prereqs.astro"
import UiWalkthrough from "@docs/UiWalkthrough.astro"
import ClientTabs from "@docs/ClientTabs.astro"

Connect an [MCP](/docs/deep-dives/concepts/agents/mcps/) (Model Context Protocol) server to an agent so the agent can call external tools at runtime. MCP servers extend what an agent can do: from searching the web to querying databases to managing infrastructure.

<Prereqs>
  - A Ren account and organization - [The CLI installed](/docs/developers/cli/) and paired, or a personal access token
  for API calls - An [agent](/docs/deep-dives/concepts/agents/agents/) version to attach the MCP to
</Prereqs>

## Remote vs. local

MCP servers come in two types:

- **Remote**: the server is hosted at a URL. Ren proxies requests to it. Requires `mcpServerUrl`.
- **Local**: the server runs as a process on the agent's sandbox. Requires `command` (and optional `args`). The sandbox starts the process and communicates over the chosen transport.

Transport options: `streamable-http` (default for remote), `sse` (server-sent events, for legacy remote servers), `stdio` (default for local).

## Authentication

MCP servers declare their auth requirement when you create them. Ren resolves credentials from the agent's vault at runtime. They are never stored inline on the MCP object.

| Auth type | When to use                                          | What Ren does                                                                |
| --------- | ---------------------------------------------------- | ---------------------------------------------------------------------------- |
| `none`    | Public or no-auth servers (default)                  | No credential lookup                                                         |
| `api_key` | Servers that expect an API key header or query param | Reads the named credential from the vault and injects it                     |
| `bearer`  | Servers that expect a `Bearer` token                 | Reads the named credential and sends it as a Bearer header                   |
| `oauth`   | Servers that require OAuth 2.0                       | Starts an OAuth flow, stores the token in the vault, refreshes automatically |

For `api_key` and `bearer`, declare `requiredCredentials` on the MCP so Ren knows which vault entries to resolve. See [Store and share files](/docs/guides/build-and-run/store-and-share-files/) for vault setup.

## In the UI

<UiWalkthrough>
  {/* TODO(demo): screen recording – creating an MCP server and attaching it to an agent version, ~10s loop */}
</UiWalkthrough>

<Steps>

1. Open **MCPs** in the sidebar and click **New MCP**.

2. Choose **Remote** (enter the server URL) or **Local** (enter the command and args), then pick the auth type.

3. Open the agent you want to extend, select a version, and add the MCP under **MCPs**.

4. Save. The next session on that agent version can call the MCP's tools.

</Steps>

## Create and attach programmatically

<ClientTabs clients={["cli", "api"]}>
  <Fragment slot="cli">
    <Steps>
      1. Create a remote MCP server:

         ```bash
         ren mcps create \
           --name "web-search" \
           --mcp-server-url "https://search.example.com/mcp" \
           --auth none
         ```

         Or create a local MCP server:

         ```bash
         ren mcps create \
           --name "local-tools" \
           --type local \
           --command "npx" \
           --args '["-y","@example/mcp-server"]' \
           --transport stdio
         ```

         The response includes the MCP `id` (e.g. `mcp_abc123`).

      2. Attach the MCP to an agent version:

         ```bash
         ren agents versions mcps add agt_abc123 1.2.0 \
           --mcp-id mcp_abc123
         ```
    </Steps>

    For servers requiring an API key, declare the credential and store it in a vault:

    ```bash
    ren mcps create \
      --name "paid-api" \
      --mcp-server-url "https://api.example.com/mcp" \
      --auth api_key \
      --required-credentials '[{"name":"EXAMPLE_API_KEY","description":"API key for Example"}]'
    ```

    Then store the key in a vault and attach the vault to the agent's pod.

  </Fragment>
  <Fragment slot="api">
    <Steps>
      1. Create a remote MCP server with `POST /api/mcps`:

         ```bash
         curl -X POST https://api.renai.build/api/mcps \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{
             "name": "web-search",
             "mcpServerUrl": "https://search.example.com/mcp",
             "type": "remote",
             "transport": "streamable-http",
             "auth": "none"
           }'
         ```

         Or create a local MCP server:

         ```bash
         curl -X POST https://api.renai.build/api/mcps \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{
             "name": "local-tools",
             "type": "local",
             "command": "npx",
             "args": ["-y", "@example/mcp-server"],
             "transport": "stdio"
           }'
         ```

      2. Attach the MCP to an agent version with `POST /api/agents/{id}/versions/{version}/mcps`:

         ```bash
         curl -X POST https://api.renai.build/api/agents/agt_abc123/versions/1.2.0/mcps \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"mcpId": "mcp_abc123"}'
         ```
    </Steps>

    For OAuth-authenticated servers, start the OAuth flow after creation:

    ```bash
    curl -X POST https://api.renai.build/api/mcps/mcp_abc123/oauth/connect \
      -H "Authorization: Bearer $REN_PAT_TOKEN"
    ```

    This returns an authorization URL. Complete the flow in a browser, then poll the session endpoint until `status` is `connected`.

  </Fragment>
</ClientTabs>