# Custom MCP servers

Not every service your agent needs is in the catalog. Any MCP server can give it tools: DeepWiki, for example, answers questions about public GitHub repositories. One command adds the server and connects it for your app.

To find a ready server, search the [official MCP Registry](https://registry.modelcontextprotocol.io). An entry for a hosted server lists its URL and a type. Use a server of type `streamable-http`. A server's own docs also give its URL.

## Add a public MCP server

DeepWiki takes no key, and nobody signs in to it.

1. **Add the server**

   ```sh
   getstream agents connectors add custom_deepwiki https://mcp.deepwiki.com/mcp
   ```

   ```text
   Created connector custom_deepwiki (No authentication)
   Connected: custom_deepwiki / deepwiki (<connection id>)
   ```

   It adds the connector and an app connection to it, labelled `deepwiki`: the id without `custom_`. Set your own with `--label`.

2. **Check that it is connected**

   ```sh
   getstream agents connections list --connector custom_deepwiki
   ```

   ```text
   ID               CONNECTOR        LABEL     OWNER  STATUS
<connection id>  custom_deepwiki  deepwiki  App    Connected
   ```

3. **Use it in an agent**

   >
   > **Warning:** The `blank` template has no `guardrail.md`, so nothing screens the question. If you use another template, delete or change its `guardrail.md` first, see [Guardrails](https://getstream.io/agents/docs/guardrails/).
   >

   ```sh
   getstream agents init assistant --template blank
   ```

   Replace `agents/assistant/agent.yaml` with:

   ```yaml title="agents/assistant/agent.yaml"
   name: assistant # an internal assistant for your team
   mode: text
   llm: llm-fast
   connectors:
     - name: deepwiki
       connector: custom_deepwiki # the connector's id
       connection: deepwiki # the label of its connection
   ```

   ```sh
   getstream agents test assistant
   ```

   Ask: "What is the vercel/next.js repository?" to see the agent call DeepWiki's tools, such as `deepwiki__ask_wiki_question`.

See [Tools](https://getstream.io/agents/docs/connectors/choosing-tools/#offer-only-some-tools) to offer only some of its tools.

## Add an MCP server that needs a key

Exa searches the web, with an API key it reads from the `x-api-key` header.

1. **Add the server**

   `--api-key -` reads the key from stdin, so it never shows in your shell history:

   ```sh
   printenv EXA_API_KEY | getstream agents connectors add custom_exa https://mcp.exa.ai/mcp \
     --auth api-key --header x-api-key --api-key -
   ```

   ```text
   Created connector custom_exa (API key)
   Connected: custom_exa / exa (<connection id>)
   ```

2. **Use it in an agent**

   Add the binding to the same `agent.yaml`:

   ```yaml title="agents/assistant/agent.yaml"
   connectors:
     - name: exa
       connector: custom_exa
       connection: exa
   ```

   Run `getstream agents test assistant`, and ask: "Call exa__web_search_exa to find the Vision Agents page on getstream.io". The agent has a web search of its own, so name the tool to see it call Exa.

See [Sign-in](https://getstream.io/agents/docs/connectors/sign-in/#how-a-connection-signs-in) for the other ways a connection can sign in.

## Remove a server

Take it out of `agent.yaml` and sync your agent, then remove it:

```sh
getstream agents sync assistant
getstream agents connectors remove custom_deepwiki --force
```

```text
Removed connector custom_deepwiki and its connections
```

`--force` deletes its connection with it. Without it, a connector with a connection is not removed.

The CLI can't change a server. Use **Edit** in the Dashboard, or the API below.

## In the Dashboard

1. **Create the connector**

   In **Library > Connectors**, click **Create connector**. Type the **ID**, such as `custom_deepwiki`, a **Name** and the **Endpoint**. Under **Authentication**, pick **No authentication** for a public server or **API key** for one that needs a key. Click **Create connector**.

2. **Connect it**

   On the connector's page, click **Create connection**. Pick **App** as the **Owner**, and type a **Label**, such as `deepwiki`. For a key, type the **Header**, such as `x-api-key`, and the **API key**. Click **Create connection**.

To change a server, open it and click **Edit**. Type the **Endpoint** again, since the Dashboard doesn't show the saved one, and click **Save revision**. A save that changes anything stores the next revision, and each connection stays on its old one. On a public server, changing the **Endpoint** makes the connection's **Definition** show **Outdated**. Open the connection and click **Reconnect** to move it to the new revision. A new **Category** leaves the connection **Current**. Other fields may also make it **Outdated**. For an API key connection, use the API section below.

## With the API

The API changes a connector in place. `$STREAM_ACCELERATION_URL` is your router's URL, and `$SERVER_TOKEN` is a [server token](https://getstream.io/agents/docs/auth/): an HS256 JWT of `{"server": true}` signed with your API secret.

Create the connector again with the same `id`. It stores the next `revision`:

```bash
curl -X POST "$STREAM_ACCELERATION_URL/v1/agents/connectors" \
  -H "api_key: $STREAM_API_KEY" -H "stream-auth-type: jwt" \
  -H "Authorization: Bearer $SERVER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "custom_deepwiki",
    "name": "DeepWiki",
    "description": "Answers questions about public GitHub repositories",
    "endpoint": "https://mcp.deepwiki.com/mcp",
    "schemes": ["none"]
  }'
```

Each connection keeps the old revision until its credentials are saved again. Use the connection's id from `connections list` as `$CONNECTION_ID`. `expected_revision` is the connection's `revision`, as `GET /v1/agents/connections/$CONNECTION_ID` returns it:

```bash
curl -X PUT "$STREAM_ACCELERATION_URL/v1/agents/connections/$CONNECTION_ID/credentials" \
  -H "api_key: $STREAM_API_KEY" -H "stream-auth-type: jwt" \
  -H "Authorization: Bearer $SERVER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"expected_revision": 2}'
```

For a key, send it again in `"values": {"api_key": "...", "header": "x-api-key"}`.

## Build an MCP server for your agent

If you write the server yourself, here is what the agent expects of it.

- It speaks Streamable HTTP. A server that serves only the older HTTP with SSE fails when you add it, and `connectors add` keeps the connector and prints how to connect or remove it:

  ```text
  Error: wiki did not work without a credential: mcp: connect to custom_wiki: calling "initialize": sending "initialize": Method Not Allowed.
  ```

- It answers at a public `https` URL, with no query string or fragment: take the key in a header. To try a server on your laptop, put a tunnel in front of it, such as `cloudflared tunnel --url http://localhost:8000`.
- The agent sees each tool as `<name>__<tool>`, with the `name` from `agent.yaml`, such as `deepwiki__ask_wiki_question`.

>
> **Warning:** - A result over 32 KiB is cut, and ends with `[connector result truncated]` so the model knows it read only part. Return what the model needs, not a whole document.
> - A tool call has 5 seconds. Answer within 5 seconds, and return at once from slow work. A longer call is cut, and the model reads that the tool did not answer in time and may or may not have done what was asked.
>

To test it, add it with `getstream agents connectors add`, put it in an agent's `agent.yaml`, and ask a question only your tool can answer with `getstream agents test`.

## Going further

- [App connection](https://getstream.io/agents/docs/connectors/shared-account/): One account the app owns, for every conversation.
- [Tools](https://getstream.io/agents/docs/connectors/choosing-tools/): See a connection's tools and offer only the ones the agent needs.
- [Creating an agent](https://getstream.io/agents/docs/creating-an-agent/): The agent folder, and every key of agent.yaml.
- [Tool calling and dispatch](https://getstream.io/agents/docs/tool-calling-and-dispatch/): Your own functions, run in your process.
- [Troubleshooting](https://getstream.io/agents/docs/connectors/troubleshooting/): Errors you may see, why, and what to do.

---

For the most recent version of this documentation, visit [https://getstream.io/agents/docs/connectors/mcp/](https://getstream.io/agents/docs/connectors/mcp/).