Skip to main content
MCP (Model Context Protocol) lets you extend Deep Agents Code with tools from external servers—file systems, APIs, databases, and more—without modifying the agent itself. Deep Agents Code connects to MCP servers at startup, discovers their tools, and makes them available to the agent alongside the built-in tools. Add MCP servers by adding a .mcp.json config file to your project for project-level scope, or at user-level to apply to all projects.

Quickstart

This quickstart adds the LangChain MCP servers to every Deep Agents Code session on your machine. We recommend adding docs-langchain for conceptual guides and how-tos, and reference-langchain for API reference.

Create the config file

If it is not already present, create the .mcp.json file at the user level to make the server available to every project on the machine, or at the project level.
Servers in this file (~/.deepagents/.mcp.json) are available in every project on this machine.
See Discovery locations for full precedence rules.

Add the MCP servers

~/.deepagents/.mcp.json
To add more servers, add more entries to mcpServers. See Configuration format for OAuth, stdio, SSE, and HTTP server fields, environment variables, and headers.

Launch Deep Agents Code

On startup, Deep Agents Code auto-discovers the config, connects to each server, discovers its tools, and prints a confirmation:
Run /mcp in an interactive session to see per-server status, transport, and the loaded tool list. The agent can now use those tools for the duration of the session—stdio servers are kept alive between tool calls.

Auto-discovery

Deep Agents Code 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): 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 by server name. Differently named servers are preserved. If the same server name appears in more than one file, the higher-precedence definition replaces the entire earlier server object; nested fields are not deep-merged. This lets a project-level config override a user-level entry (for example, pinning a different version of the same server) without disturbing your other projects.

Flags

--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, Deep Agents Code picks it up automatically—no extra setup needed.

Configuration format

Each key under mcpServers is a server name. The server’s fields determine how Deep Agents Code connects to it.

stdio servers (default)

stdio servers are spawned as child processes. Deep Agents Code communicates with them over stdin/stdout.
mcp-config.json

SSE and HTTP servers

For remote MCP servers, set type to "sse" or "http" and provide a url:
mcp-config.json

Field reference

Required: command. Optional: args, env, plus the shared tool-filter fields.
string
required
The executable to run.
string[]
Arguments passed to the command.
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.
"sse"
required
Transport type. Use "sse" for Server-Sent Events.
string
required
The server endpoint URL.
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).
"oauth"
Set to "oauth" to drive an OAuth login flow with dcode 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.
"http"
required
Transport type. Use "http" for streamable HTTP. streamable_http and streamable-http are accepted as aliases.
string
required
The server endpoint URL.
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).
"oauth"
Set to "oauth" to drive an OAuth login flow with dcode 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

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

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

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:
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.
string[]
Tool names or fnmatch glob patterns to keep. All other tools from this server are dropped. Mutually exclusive with disabledTools.
string[]
Tool names or fnmatch glob patterns to drop. All other tools from this server are kept. Mutually exclusive with allowedTools.

Read-only tool annotations in Auto mode

MCP servers can attach standard ToolAnnotations when advertising a tool. Deep Agents Code lets a tool bypass classifier review in Auto approval mode only when all of the following are true:
  • readOnlyHint is the literal Boolean true.
  • destructiveHint is absent, null, or false.
  • Every supplied standard hint (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) is a Boolean or null, not a string or another type.
Tools that do not pass this check enter the classifier batch in Auto, use the normal approval UI in Manual, and are rejected in headless runtimes because no approval UI is available. The annotation is a server-provided assertion that Deep Agents Code does not independently verify.

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.

Configure the server

.mcp.json
auth: "oauth" is mutually exclusive with an Authorization header on the same entry, and cannot be set on a stdio server. To connect Deep Agents Code to LangSmith, use the LangSmith Remote MCP:
.mcp.json

Run the login flow

What happens depends on the server’s host:
  • Spec-compliant servers (the default): Deep Agents Code 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. Deep Agents Code prints a verification URL and a user code; you enter the code in your browser and Deep Agents Code polls for completion.
By default, dcode mcp login reads the same auto-discovered configs Deep Agents Code uses at runtime (subject to project-level trust gating). Pass --mcp-config <path> to use a specific file:
Project-level configs that have not 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 dcode in the project and choose Allow for this project — until changed to save an approval, or pass --mcp-config <path> explicitly.

Token storage

Tokens are written to:
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), Deep Agents Code 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 dcode mcp login <server> to refresh credentials — your conversation continues without restarting.

Server status

Each configured server lands in one of three states after startup: 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, Deep Agents Code enforces a default-deny policy for project-level entries.
Saved project MCP approvals and the per-server allow and deny policy require deepagents-code>=0.1.40.

How it works

  • Interactive mode: Deep Agents Code prompts for approval before activating project servers, showing each stdio command and remote URL. Choose Allow once to activate every prompted server for the current session. Choose Allow for this project — until changed to activate every prompted server for the session and select which approvals to save for future sessions.
  • Saved approvals: Deep Agents Code writes selected server approvals to the user-level ~/.deepagents/config.toml. Each approval is scoped to the resolved project root, the server name, and a SHA-256 fingerprint of that server definition. If the server command, URL, headers, or other config fields change, Deep Agents Code prompts again.
  • Non-interactive mode (-n): Project servers without a matching saved or environment approval are silently skipped unless --trust-project-mcp is passed. Explicit denies still apply.
  • 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 through headers, so Deep Agents Code gates them the same way as stdio servers.
  • User-level configs (~/.deepagents/.mcp.json) are always trusted, following the same trust model as config.toml and hooks.json.
  • dcode 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

Saved approvals

Saved approvals are stored in ~/.deepagents/config.toml:
~/.deepagents/config.toml
To revoke an approval, remove its entry from enabled_project_server_approvals. To force a re-approval without editing config.toml, change the server definition in the project’s .mcp.json; the saved fingerprint no longer matches. The legacy flat [mcp].enabled_project_servers list is ignored in config.toml. Use enabled_project_server_approvals for saved approvals.

Advanced allow and deny policy

Use [mcp].disabled_project_servers in ~/.deepagents/config.toml, or DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS in your shell or global ~/.deepagents/.env, to always reject project MCP servers by name. Denies win over saved approvals and over the --trust-project-mcp flag. For automation that must pre-approve project MCP servers by name, set DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS in your shell or global ~/.deepagents/.env to a comma-separated list of server names. This is a process-wide escape hatch: A different project, command change, or URL change under the same server name still matches. When this variable is set, Deep Agents Code ignores saved approvals for that process. Prefer saved approvals or --trust-project-mcp unless you need name-based approval across projects and server-definition changes. deepagents-code>=0.1.40 ignores the former DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS variable. Replace it with DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS if you need the same name-based behavior.
A trusted stdio MCP server runs with the permissions of your user account. Approving a remote server allows Deep Agents Code to contact its URL during pre-flight and send its configured headers. Only approve servers from repositories you trust, and review the commands and URLs shown in the approval prompt.

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 Deep Agents Code:
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.
Deep Agents Code 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 dcode 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 — Deep Agents Code 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_CODE_DEBUG=1 and inspect the per-session log path printed to stderr on shutdown.

Further reading