Skip to main content

Documentation Index

Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-mdrxyo-1777658790-7be347c.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

MCP (Model Context Protocol) lets you extend the Deep Agents CLI with tools from external servers—file systems, APIs, databases, and more—without modifying the agent itself. The CLI connects to MCP servers at startup, discovers their tools, and makes them available to the agent alongside the built-in tools.

Quickstart

Create a config file

Create a .mcp.json file at your project root. The format follows the Claude Desktop convention:
.mcp.json
{
    "mcpServers": {
        "docs-langchain": {
        "type": "http",
        "url": "https://docs.langchain.com/mcp"
        }
    }
}

Launch the CLI

deepagents
On startup, the CLI automatically discovers your .mcp.json, spawns each configured server, discovers its tools, and prints a confirmation:
✓ Loaded 3 MCP tools
The agent can now use those tools for the duration of the session. Sessions are kept alive—stdio servers are not restarted between tool calls.

Auto-discovery

The CLI automatically searches for .mcp.json files in standard locations. No flags are needed—just place a config file and it gets picked up.

Discovery locations

Configs are checked in this order (lowest to highest precedence):
PriorityLocationScope
1 (lowest)~/.deepagents/.mcp.jsonUser-level—applies to all projects
2<project>/.deepagents/.mcp.jsonProject-level—.deepagents subdirectory
3 (highest)<project>/.mcp.jsonProject-level—root (Claude Code compatible)
The project root is the nearest parent directory containing a .git folder, falling back to the current working directory. When multiple config files exist, their mcpServers entries are merged. If the same server name appears in more than one file, the higher-precedence config wins.

Flags

FlagBehavior
--mcp-config PATHAdd an explicit config as the highest-precedence source (merged on top of auto-discovered configs)
--no-mcpDisable MCP entirely—no servers are loaded
--mcp-config and --no-mcp are mutually exclusive.

Claude Code compatibility

If you already have a .mcp.json at your project root for Claude Code, the Deep Agents CLI picks it up automatically—no extra setup needed.

Configuration format

Each key under mcpServers is a server name. The server’s fields determine how the CLI connects to it.

stdio servers (default)

stdio servers are spawned as child processes. The CLI communicates with them over stdin/stdout.
mcp-config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
      "env": {}
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "your-token" }
    }
  }
}

SSE and HTTP servers

For remote MCP servers, set type to "sse" or "http" and provide a url:
mcp-config.json
{
  "mcpServers": {
    "remote-api": {
      "type": "sse",
      "url": "https://api.example.com/mcp",
      "headers": { "Authorization": "Bearer your-token" }
    }
  }
}

Field reference

Required: command. Optional: args, env, plus the shared tool-filter fields.
command
string
required
The executable to run.
args
string[]
Arguments passed to the command.
env
object
Environment variables set for the subprocess. Use this to pass API keys and other credentials without exposing them in shell history.
Required: type: "sse", url. Optional: headers, auth, plus the shared tool-filter fields.
type
"sse"
required
Transport type. Use "sse" for Server-Sent Events.
url
string
required
The server endpoint URL.
headers
object
HTTP headers sent with every request. Commonly used for authentication. Values support ${VAR} references to parent-shell environment variables (resolved when the server activates).
auth
"oauth"
Set to "oauth" to drive an OAuth login flow with deepagents mcp login instead of supplying an Authorization header. Cannot be combined with an Authorization header. See OAuth login.
Required: type: "http", url. Optional: headers, auth, plus the shared tool-filter fields.
type
"http"
required
Transport type. Use "http" for streamable HTTP. streamable_http and streamable-http are accepted as aliases.
url
string
required
The server endpoint URL.
headers
object
HTTP headers sent with every request. Commonly used for authentication. Values support ${VAR} references to parent-shell environment variables (resolved when the server activates).
auth
"oauth"
Set to "oauth" to drive an OAuth login flow with deepagents mcp login instead of supplying an Authorization header. Cannot be combined with an Authorization header. See OAuth login.
The type field can also be written as transport for compatibility with other MCP clients.
Server names must match [A-Za-z0-9_-]+. Names are used as on-disk basenames for OAuth token files, so path separators and other shell metacharacters are rejected at config load.

Header environment variables

Header values support ${VAR} substitution from the parent shell, resolved at server activation rather than at config load. One unset variable only fails the server that needs it; the rest still come up.
.mcp.json
{
    "mcpServers": {
        "internal-api": {
            "type": "http",
            "url": "https://api.example.com/mcp",
            "headers": { "Authorization": "Bearer ${INTERNAL_API_TOKEN}" }
        }
    }
}

Multiple servers

You can configure as many servers as you need. Tools from all servers are merged and available to the agent:
mcp-config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "ghp_..." }
    },
    "database": {
      "type": "sse",
      "url": "https://db-mcp.internal:8080/mcp",
      "headers": { "Authorization": "Bearer ..." }
    }
  }
}

Tool filtering

Each server may narrow the tools it exposes to the agent with one of two optional fields:
  • allowedTools: keep only the listed tools; drop everything else.
  • disabledTools: drop the listed tools; keep everything else.
Filtering applies to stdio, HTTP, and SSE servers alike. Both of the following are rejected at config load:
  • Setting allowedTools and disabledTools on the same server.
  • Setting either field to an empty list (would silently strip every tool, or be a no-op). Omit the field instead.
.mcp.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
      "allowedTools": ["read_file", "list_directory"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "disabledTools": ["delete_repository", "delete_*_branch"]
    }
  }
}

Match rules

Each entry is a literal tool name or an fnmatch-style glob (any entry containing *, ?, or [ is treated as a pattern). Entries are matched against both the bare MCP tool name and the server-prefixed form ({server}_{tool}), so either form works:
{
  "allowedTools": ["read_file", "fs_list_*"]
}
Entries that match no loaded tool are logged as a warning, not an error — the underlying MCP server can evolve its tool list across versions without breaking your config.
allowedTools
string[]
Tool names or fnmatch glob patterns to keep. All other tools from this server are dropped. Mutually exclusive with disabledTools.
disabledTools
string[]
Tool names or fnmatch glob patterns to drop. All other tools from this server are kept. Mutually exclusive with allowedTools.

OAuth login

For remote MCP servers that require OAuth (Slack, GitHub, Notion, Linear, and other hosted MCP endpoints), set "auth": "oauth" on the server entry and run the login subcommand once. Tokens are persisted to disk and refreshed automatically.
OAuth login requires deepagents-cli>=0.0.46.

Configure the server

.mcp.json
{
    "mcpServers": {
        "linear": {
            "type": "http",
            "url": "https://mcp.linear.app/mcp",
            "auth": "oauth"
        }
    }
}
auth: "oauth" is mutually exclusive with an Authorization header on the same entry, and cannot be set on a stdio server.

Run the login flow

deepagents mcp login linear
What happens depends on the server’s host:
  • Spec-compliant servers (the default): the CLI performs Dynamic Client Registration, opens an Authorization Code + PKCE flow in your browser, and asks you to paste the redirected URL back into the terminal.
  • Slack (slack.com, *.slack.com): same paste-back flow, but with Slack’s public client preseeded. You’re prompted for an optional team ID (e.g., T01234567) so the app installs into the right workspace.
  • GitHub (api.githubcopilot.com): RFC 8628 Device Authorization Grant. The CLI prints a verification URL and a user code; you enter the code in your browser and the CLI polls for completion.
By default, deepagents mcp login reads the same auto-discovered configs the CLI uses at runtime (subject to project-level trust gating). Pass --config <path> to use a specific file:
deepagents mcp login linear --config ./mcp-config.json
Project-level configs that haven’t been trusted (see Project-level trust) are skipped during mcp login to prevent attacker-controlled headers entries from exfiltrating local secrets through ${VAR} interpolation. Run deepagents in the project once to approve the config, or pass --config <path> explicitly.

Token storage

Tokens are written to:
~/.deepagents/mcp-tokens/<server>-<sha256-16(url)>.json
The <sha256-16(url)> segment is the first 16 hex characters of the SHA-256 of the server URL. The directory is locked to mode 0700 and each token file is mode 0600. Files include the OAuth access token, refresh token, and the dynamically registered client info, all in a schema-versioned payload that’s written atomically (write-to-temp + rename).
Hashing the URL into the filename means the same server name pointing at different URLs (for example, dev vs. prod) gets independent token files and can’t trample each other.

Re-authentication

When refresh fails at runtime (the refresh token expired or was revoked), the CLI marks the server as unauthenticated instead of crashing the agent. The welcome banner shows the count of unauthenticated servers, and /mcp reports the reason per server. Re-run deepagents mcp login <server> to refresh credentials — your conversation continues without restarting.

Server status

Each configured server lands in one of three states after startup:
StatusMeaning
okConnected; tools are loaded and available to the agent
unauthenticatedOAuth login required or refresh failed — run deepagents mcp login <server>
errorPre-flight, discovery, or transport setup failed; an error message is attached
A single failing server no longer aborts startup. The agent runs with whichever servers came up cleanly, and the welcome banner surfaces counts of unauthenticated and errored servers next to the tool count. Open /mcp in an interactive session to see per-server status, transport, tool list, and the failure reason for non-ok entries. The viewer live-updates as servers connect and supports tab/shift+tab navigation.

Project-level trust

Project-level configs can contain stdio servers that execute local commands and remote servers whose headers may interpolate ${VAR} from your environment. To prevent untrusted repositories from running arbitrary code or exfiltrating local secrets on CLI startup, the CLI enforces a default-deny policy for project-level entries.

How it works

  • Interactive mode: The CLI prompts for approval before activating project servers, showing each stdio command and remote URL. Approval is persisted using a SHA-256 content fingerprint—if the config changes, you are prompted again.
  • Non-interactive mode (-n): Project servers are silently skipped unless --trust-project-mcp is passed.
  • Trust covers stdio and remote entries alike — remote servers can SSRF into localhost or cloud-metadata endpoints during the pre-flight probe and exfiltrate ${VAR} values via headers, so they’re gated the same way as stdio.
  • User-level configs (~/.deepagents/.mcp.json) are always trusted—the same trust model as config.toml and hooks.json.
  • deepagents mcp login also honors project trust: an untrusted project-level config is skipped during login discovery so an attacker-controlled remote entry cannot pull secrets into the OAuth handshake.

Flags

FlagBehavior
--trust-project-mcpTrust all project-level stdio servers without prompting (for CI and automation)
# Skip the approval prompt
deepagents --trust-project-mcp

# Non-interactive: explicitly trust project servers
deepagents -n "run tests" --trust-project-mcp

Trust store

Trust decisions are stored in ~/.deepagents/config.toml:
[mcp_trust.projects]
"/Users/you/myproject" = "sha256:abc123..."
Each key is an absolute project root path. The value is a SHA-256 digest of the concatenated project-level config contents. To revoke trust, delete the entry or modify the project’s .mcp.json (which invalidates the fingerprint automatically).
A trusted stdio MCP server has the same permissions as your user account. Only approve servers from repositories you trust. Review the commands shown in the approval prompt before accepting.

System prompt awareness

Connected MCP servers and their tools are automatically listed in the agent’s system prompt, grouped by server name and transport type. This helps the model reason about tool provenance and failure domains without requiring manual context.

Troubleshooting

Verify the command works outside the CLI:
npx -y @modelcontextprotocol/server-filesystem /tmp
Common causes: the package isn’t installed, npx isn’t on PATH, or required environment variables are missing.
Check that the remote server is running and the URL is correct. If the server requires authentication, make sure headers includes the correct credentials.
The CLI prints the number of tools loaded at startup (e.g., ✓ Loaded 3 MCP tools). If you see 0, the server started successfully but didn’t advertise any tools—check the server’s own logs or documentation.
Either you haven’t run deepagents mcp login <server> yet, or the persisted refresh token expired or was revoked server-side. Run the login command again — your session keeps running and the server will re-attach once tokens are refreshed.
A pre-flight validation rejected --mcp-config (or an auto-discovered .mcp.json). Common causes: an unsupported server name (must match [A-Za-z0-9_-]+), auth: oauth on a stdio server, both command and url set on the same entry, or a header value that isn’t a string. Fix the highlighted reason and relaunch — the CLI no longer dumps a multi-page subprocess trace for config errors.
Header interpolation runs at activation time, so an unset variable only fails the server that needs it. Export the variable in the parent shell or add it to ~/.deepagents/.env. To debug, set DEEPAGENTS_CLI_DEBUG=1 and inspect the per-session log path printed to stderr on shutdown.

Further reading

  • LangChain MCP guide: protocol details, building custom servers, and using langchain-mcp-adapters programmatically
  • MCP specification: the official protocol spec and server registry