---
title: MCP servers
sidebar_position: 7
---

# MCP servers

MCP servers extend the Vibe Code CLI with **external tools** through the [Model Context Protocol](https://modelcontextprotocol.io). You add them with the `vibe mcp add` command, the `/mcp add` slash command, or directly in `config.toml` under `mcp_servers`. Their tools then become available to Vibe like any built-in tool.

MCP servers are **user-configured**. For Mistral-managed integrations, see [Connectors](/vibe/code/cli/connectors) instead.

:::info
Your administrator can block MCP servers with `enable_mcp = false` in [admin config](/vibe/code/cli/admin-config#block-mcp). In that case, Vibe refuses to add, remove, enable, or sign in to MCP servers, and loads no MCP tools.
:::

<SectionTab as="h2" sectionId="transports">Supported transports</SectionTab>

| Transport | Use it when |
|---|---|
| `http` | The server is reachable over standard HTTP. |
| `streamable-http` | The server is reachable over HTTP and supports streaming responses. |
| `stdio` | The server is a local process you start from a command. |

<SectionTab as="h2" sectionId="add-command">Add an MCP server from the command line</SectionTab>

`vibe mcp add` writes the server to your user `config.toml` without starting a session. For a remote server that uses OAuth, pass its name and URL. Vibe opens your browser to sign in:

```bash
vibe mcp add linear --url https://mcp.linear.app/mcp
```

Pass `--no-login` to save the server without signing in, and `--scope` (repeatable) to request specific OAuth scopes.

For a remote server that uses an API key or static headers, pass `--api-key-env` or `--header`:

```bash
vibe mcp add mistralai \
  --url https://api.mistral.ai/mcp \
  --api-key-env MISTRAL_API_KEY
```

For a local server, use the `stdio` transport. Repeat `--arg` for each argument and `--env` for each environment variable:

```bash
vibe mcp add fetch_server --transport stdio --command uvx --arg mcp-server-fetch
```

Remove a server with `vibe mcp remove <name>`. Removing an OAuth server also deletes its stored tokens. Run `vibe mcp add --help` for all options.

You can also add an OAuth server from inside a session with `/mcp add <url>`. It accepts the same `--name`, `--scope`, `--transport`, and `--no-login` options:

```text
/mcp add https://mcp.linear.app/mcp
```

<SectionTab as="h2" sectionId="add">Add an MCP server in `config.toml`</SectionTab>

Append a `[[mcp_servers]]` table to `config.toml`. Required fields depend on the transport.

<ExplorerTabs>
<ExplorerTab value="http" label="HTTP" default>

```toml
[[mcp_servers]]
name = "my_http_server"
transport = "http"
url = "http://localhost:8000"

[mcp_servers.auth]
type = "static"
headers = { "X-Client" = "vibe" }
api_key_env = "MY_API_KEY_ENV_VAR"
api_key_header = "Authorization"
api_key_format = "Bearer {token}"
```

</ExplorerTab>
<ExplorerTab value="streamable" label="Streamable HTTP">

```toml
[[mcp_servers]]
name = "my_streamable_server"
transport = "streamable-http"
url = "http://localhost:8001"

[mcp_servers.auth]
type = "static"
api_key_env = "MY_API_KEY_ENV_VAR"
api_key_header = "X-API-Key"
api_key_format = "{token}"
```

</ExplorerTab>
<ExplorerTab value="oauth" label="OAuth">

```toml
[[mcp_servers]]
name = "linear"
transport = "streamable-http"
url = "https://mcp.linear.app/mcp"

[mcp_servers.auth]
type = "oauth"
scopes = []
```

Sign in with `/mcp login linear` from a session. An empty `scopes` list accepts the server's default scopes. See [Sign in to OAuth servers](#oauth-sign-in) for how sign-in works.

</ExplorerTab>
<ExplorerTab value="stdio" label="Local process (stdio)">

```toml
[[mcp_servers]]
name = "fetch_server"
transport = "stdio"
command = "uvx"
args = ["mcp-server-fetch"]
env = { "DEBUG" = "1", "LOG_LEVEL" = "info" }
```

</ExplorerTab>
</ExplorerTabs>

<SectionTab as="h2" sectionId="fields">Common fields</SectionTab>

| Field | Purpose |
|---|---|
| `name` | Short alias for the server. Used as a prefix in tool names. |
| `transport` | One of `http`, `streamable-http`, or `stdio`. |
| `url` | Base URL for HTTP transports. |
| `command` / `args` | Command and arguments for the stdio transport. |
| `env` | Environment variables passed to the server process (stdio). |
| `startup_timeout_sec` | How long to wait for the server to start. Default: `10` seconds. |
| `tool_timeout_sec` | How long to wait for a tool call to complete. Default: `60` seconds. |
| `[mcp_servers.auth]` | Authentication for HTTP transports: `type = "static"` with `headers` or `api_key_env`, or `type = "oauth"` with `scopes`. |

Vibe still accepts `headers`, `api_key_env`, `api_key_header`, and `api_key_format` directly in `[[mcp_servers]]`, and treats them as static authentication. Don't combine them with an `[mcp_servers.auth]` table. See the [configuration reference](/vibe/code/cli/configuration-reference#mcp-servers) for every field.

<SectionTab as="h2" sectionId="oauth-sign-in">Sign in to OAuth servers</SectionTab>

OAuth works with the `http` and `streamable-http` transports. `stdio` servers run locally and don't use OAuth.

`vibe mcp add` starts the sign-in as soon as it adds an OAuth server, that is, an HTTP server added without `--header` or `--api-key-env`. `/mcp add` only adds OAuth servers and also starts the sign-in. If you skipped it with `--no-login`, or if Vibe reports that a server needs authentication, run `/mcp login <name>` from a session. `/mcp status` shows the sign-in state of each server.

During sign-in, Vibe gives you the authorization URL and can open it in your browser. After you approve access, the browser redirects to `http://127.0.0.1:<redirect_port>/callback`, which is `http://127.0.0.1:47823/callback` by default. This address must reach the machine where Vibe runs. If Vibe runs on a remote machine over SSH, forward the callback port before you sign in, then open the URL in your local browser: `ssh -L 47823:127.0.0.1:47823 <host>`. Use your `redirect_port` instead of `47823` if you changed it.

Vibe stores the tokens in your OS keyring, not in `config.toml`. `/mcp logout <name>` deletes them. If you change the server's `url`, `scopes`, `client_id`, or `client_metadata_url`, Vibe stops using the stored tokens, and you need to run `/mcp login <name>` again.

These optional fields in `[mcp_servers.auth]` control the OAuth client:

| Field | Purpose |
|---|---|
| `client_id` | Pre-registered public client ID. Register `http://127.0.0.1:47823/callback` as its redirect URI, with your `redirect_port` instead of `47823` if you changed it. Without `client_id` or `client_metadata_url`, Vibe registers a client with the server dynamically. |
| `client_metadata_url` | HTTPS URL of a client metadata document, with a path other than `/`. The document must list `http://127.0.0.1:<redirect_port>/callback` in `redirect_uris`. Used only if the server advertises `client_id_metadata_document_supported`. Otherwise, Vibe registers a client dynamically. Can't be combined with `client_id`. |
| `redirect_port` | Local port for the sign-in callback. Default: `47823`. Change it if `47823` is already in use on your machine. |

In headless environments without an OS keyring, such as CI, Vibe can't store OAuth tokens. Use static authentication with `api_key_env` instead.

<SectionTab as="h2" sectionId="permissions">Tool naming and permissions</SectionTab>

MCP tools are exposed under the pattern `{server_name}_{tool_name}`. Configure permissions per tool just like built-in tools:

```toml
[tools.fetch_server_get]
permission = "always"

[tools.my_http_server_query]
permission = "ask"
```

You can also restrict which MCP tools are active using `enabled_tools` and `disabled_tools`:

```toml
# Only enable serena's tools
enabled_tools = ["serena_*"]

# Disable every tool from the fetch_server server
disabled_tools = ["fetch_server_*"]
```

Filters support **exact names**, **glob patterns**, and **regex** with the `re:` prefix.

<SectionTab as="h2" sectionId="loading">How Vibe loads MCP servers</SectionTab>

Vibe keeps the tools of MCP servers and connectors from their last load and refreshes them in the background, so your messages don't wait for servers to start. If a server can't load or needs a sign-in, Vibe shows a warning that names it.

<SectionTab as="h2" sectionId="browse">Browse MCP servers from the CLI</SectionTab>

From a CLI session:

```text
/mcp
```

Pass a server name to list its tools:

```text
/mcp fetch_server
```

`/mcp` also accepts these subcommands:

| Subcommand | Action |
|---|---|
| `/mcp add <url>` | Add an OAuth server and sign in. See [Add an MCP server from the command line](#add-command). |
| `/mcp status` | Show the status of each server. |
| `/mcp login <name>` | Sign in to an OAuth server. |
| `/mcp logout <name>` | Sign out of an OAuth server. |

:::note
`/connectors` is an alias for `/mcp`.
:::