---
title: "MCP Configuration"
description: "How to add, configure, and manage MCP servers"
icon: "gear"
---

## Adding MCP Servers

### Via Command Line

The quickest way to add an MCP server:

```bash
# stdio server — just pass the command after --
devin mcp add <name> -- <command> [args...]

# HTTP server — pass the URL as a positional argument
devin mcp add <name> <URL>

# HTTP server — or use the --url flag
devin mcp add <name> --url <URL>
```

The transport type is inferred automatically: a URL implies HTTP (Streamable HTTP), and trailing args (or `--command`) imply stdio.

<Note>Remote MCP servers use Streamable HTTP by default. If the server responds with an HTTP 4xx error, the CLI falls back to SSE on the same URL. Set `"transport": "sse"` explicitly if needed — see [Legacy SSE fallback](#legacy-sse-fallback) below.</Note>

By default, servers are saved to **local** scope (`.devin/config.local.json`, gitignored). Use `-s`/`--scope` to change:

```bash
devin mcp add -s project <name> <URL>   # shared via .devin/config.json
devin mcp add -s user <name> <URL>      # global (~/.config/devin/config.json; %APPDATA%\devin\config.json on Windows)
```

You can also manage servers from the command line:

```bash
devin mcp list              # List all configured servers
devin mcp get <name>        # Show details for a specific server
devin mcp remove <name>     # Remove a configured server
devin mcp login <name>      # Authenticate with a server via OAuth
devin mcp logout <name>     # Remove stored OAuth credentials
```

### Via Config File

Add servers directly to your config file's `mcpServers` section:

<Tabs>
  <Tab title="Project config">
    ```json
    // .devin/config.json
    {
      "mcpServers": {
        "server-name": {
          "command": "npx",
          "args": ["-y", "@company/mcp-server"],
          "env": {
            "API_KEY": "your-key"
          }
        }
      }
    }
    ```
    <Note>Project-level servers are shared with your team via version control.</Note>
  </Tab>
  <Tab title="User config">
    ```json
    // ~/.config/devin/config.json
    {
      "mcpServers": {
        "my-server": {
          "command": "node",
          "args": ["/path/to/my-server.js"],
          "env": {}
        }
      }
    }
    ```
    <Note>User-level servers apply to all your projects.</Note>
  </Tab>
  <Tab title="Local override">
    ```json
    // .devin/config.local.json
    {
      "mcpServers": {
        "server-name": {
          "command": "npx",
          "args": ["-y", "@company/mcp-server"],
          "env": {
            "API_KEY": "my-personal-key"
          }
        }
      }
    }
    ```
    <Note>Local configs are gitignored — use these for personal API keys.</Note>
  </Tab>
</Tabs>

---

## Server Configuration Options

MCP servers can be configured in two ways: as a **local command** (stdio transport) or as a **remote server** (HTTP transport).

### Local Command (stdio)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `command` | string | Yes | The executable to run |
| `args` | string[] | No | Command-line arguments |
| `env` | object | No | Environment variables to set |

### Remote Server (Streamable HTTP)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `url` | string | Yes | The URL of the MCP server endpoint |
| `transport` | string | No | `"http"` (Streamable HTTP, default for URL-based servers) or `"sse"` (legacy SSE). When set to `"http"` or omitted, the CLI tries Streamable HTTP first and falls back to SSE on 4xx errors ([per spec](https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/#backwards-compatibility)). Set `"sse"` explicitly if the server's SSE endpoint is at a different path. |
| `headers` | object | No | Custom HTTP headers to include in requests |

### Examples

<AccordionGroup>
  <Accordion title="GitHub (stdio)" icon="github">
    ```json
    {
      "mcpServers": {
        "github": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-github"],
          "env": {
            "GITHUB_TOKEN": "ghp_..."
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Notion (HTTP with OAuth)" icon="book">
    ```json
    {
      "mcpServers": {
        "notion": {
          "url": "https://mcp.notion.com/mcp",
          "transport": "http"
        }
      }
    }
    ```
    <Note>After adding an OAuth-based server, run `devin mcp login notion` to authenticate. See [Authentication](#authentication) below.</Note>
  </Accordion>

  <Accordion title="Linear (HTTP with OAuth)" icon="diagram-project">
    ```json
    {
      "mcpServers": {
        "linear": {
          "url": "https://mcp.linear.app/mcp",
          "transport": "http"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Atlassian / Jira (HTTP with OAuth)" icon="jira">
    ```json
    {
      "mcpServers": {
        "atlassian": {
          "url": "https://mcp.atlassian.com/v1/mcp",
          "transport": "http"
        }
      }
    }
    ```
    <Note>After adding, run `devin mcp login atlassian` to authenticate. Each MCP client (Windsurf, Claude Code, Devin CLI) maintains its own OAuth session, so you must log in separately even if you've already authenticated in another tool.</Note>
  </Accordion>

  <Accordion title="Custom server (stdio)" icon="code">
    ```json
    {
      "mcpServers": {
        "my-tools": {
          "command": "python",
          "args": ["./scripts/mcp-server.py"],
          "env": {
            "DB_URL": "postgres://localhost/mydb"
          }
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

---

## Authentication

Some remote MCP servers require OAuth authentication. After adding an OAuth-based server to your config, authenticate using the `login` command:

```bash
devin mcp login <server-name>
```

For example:

```bash
devin mcp login notion    # Authenticate with Notion
devin mcp login linear    # Authenticate with Linear
```

This opens a browser window where you can authorize access. The OAuth tokens are stored locally and refreshed automatically.

You can optionally request specific OAuth scopes:

```bash
devin mcp login notion --scopes read,write
```

To remove stored OAuth credentials for a server:

```bash
devin mcp logout <server-name>
```

<Note>
If the server supports OAuth, you will also be prompted to authenticate automatically when the server is first used.
</Note>

---

## Managing Secrets

<Warning>
Never commit API keys or secrets to version control. Use `.devin/config.local.json` for sensitive values.
</Warning>

For team projects, the recommended pattern is:

1. Define the server in `.devin/config.json` with placeholder or no env vars
2. Each team member adds their personal keys in `.devin/config.local.json`

The local config file is automatically excluded from git.

---

## MCP Permissions

You can pre-approve, deny, or force-ask for specific MCP tools in your permissions config:

```json
{
  "permissions": {
    "allow": [
      "mcp__github__list_issues",
      "mcp__github__create_issue"
    ],
    "deny": [
      "mcp__github__delete_repo"
    ],
    "ask": [
      "mcp__linear__*"
    ]
  }
}
```

**Permission matcher patterns:**

| Pattern | Matches |
|---------|---------|
| `mcp__server__tool` | A specific tool on a specific server |
| `mcp__server__*` | All tools on a specific server |
| `mcp__*` | All MCP tools on all servers |

---

## Troubleshooting

<AccordionGroup>
  <Accordion title="Auth required / OAuth errors with remote servers">
    If you see errors like `Auth required` or `AuthRequired` when connecting to a remote MCP server, the server requires OAuth authentication.

    Run:
    ```bash
    devin mcp login <server-name>
    ```

    Each MCP client authenticates independently. Even if you've already authenticated in Windsurf or Claude Code, you need to run `devin mcp login` separately for Devin CLI.

    To verify your auth status, try removing and re-adding credentials:
    ```bash
    devin mcp logout <server-name>
    devin mcp login <server-name>
    ```
  </Accordion>

  <Accordion title="Server won't start">
    Verify the command works outside Devin CLI:
    ```bash
    npx -y @modelcontextprotocol/server-github
    ```
    Check that all required environment variables are set.
  </Accordion>

  <Accordion title="Tools not appearing">
    Ask the agent to list MCP servers and tools. The server may need a moment to initialize.
  </Accordion>

  <Accordion title="Permission denied">
    Check your permissions config. MCP tools default to prompting for approval. Add them to `permissions.allow` to auto-approve.
  </Accordion>

  <Accordion title="Legacy SSE fallback">
    When connecting to an HTTP server, Devin CLI tries **Streamable HTTP** first. If the server responds with an HTTP 4xx error (e.g. 404 or 405), it automatically falls back to **legacy SSE** on the **same configured URL**. This follows the [MCP spec's backwards-compatibility guidance](https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/#backwards-compatibility).

    The fallback only triggers on 4xx responses — connection errors, timeouts, and 5xx responses are reported directly without attempting SSE.

    If your server's SSE endpoint is at a different path (e.g. `/sse` instead of `/mcp`), set `"transport": "sse"` with the SSE URL to connect directly without the Streamable HTTP attempt.

    If both transports fail, the error message includes details from both attempts to help with troubleshooting.
  </Accordion>
</AccordionGroup>
