Restrict filesystem tools with --allow-fs-tools
By default, Deep Agents Code exposes all filesystem tools. To expose only a subset, pass a comma-separated list to `--allow-fs-tools`. Valid names are `ls`, `read_file`, `write_file`, `edit_file`, `delete`, `glob`, `grep`, and `execute`. Explicit lists must include `read_file`. The allowlist applies to the main agent and synchronous subagents in every session mode, but not to async subagents or non-filesystem tools. Example: `dcode -n "Audit this repository" --allow-fs-tools ls,read_file,glob,grep`.
Relationship between --allow-fs-tools and -S/--shell-allow-list
`--allow-fs-tools` and `-S`/`--shell-allow-list` control different layers of shell access. `--allow-fs-tools` controls which filesystem tools are available; shell access requires `execute`. `-S`/`--shell-allow-list` controls which shell commands are permitted through `execute`; it does not affect other filesystem tools. In non-interactive mode, pass both to enable commands without a human to approve them: `dcode -n "Fix the failing tests" --allow-fs-tools execute -S "pytest,git,make"`.
MCP auto-discovery requires no flags
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 on startup.
MCP stdio server configuration format
Stdio servers are spawned as child processes and communicate with Deep Agents Code over stdin/stdout. Required field: `command` (the executable to run). Optional fields: `args` (string array of arguments passed to the command), `env` (object of environment variables set for the subprocess, used to pass API keys and credentials without exposing them in shell history), and tool-filter fields (`allowedTools` and `disabledTools`). Example: {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], "env": {}}
MCP SSE server configuration format
For SSE (Server-Sent Events) remote MCP servers, set `type` to `"sse"` and provide a `url`. Required fields: `type: "sse"` and `url` (the server endpoint URL). Optional fields: `headers` (object of HTTP headers sent with every request, commonly used for authentication), `auth` (set to `"oauth"` to drive an OAuth login flow instead of supplying an Authorization header), and tool-filter fields. Values in `headers` support `${VAR}` references to parent-shell environment variables resolved when the server activates.
MCP HTTP server configuration format
For HTTP remote MCP servers, set `type` to `"http"` and provide a `url`. Required fields: `type: "http"` and `url` (the server endpoint URL). Optional fields: `headers` (object of HTTP headers sent with every request, commonly used for authentication), `auth` (set to `"oauth"` to drive an OAuth login flow instead of supplying an Authorization header), and tool-filter fields. Values in `headers` support `${VAR}` references to parent-shell environment variables resolved when the server activates. The aliases `streamable_http` and `streamable-http` are accepted for `type: "http"`.
MCP header environment variable substitution
Header values in MCP server configuration 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. Example: {"headers": {"Authorization": "Bearer ${INTERNAL_API_TOKEN}"}}
MCP tool filtering with allowedTools and disabledTools
Each MCP server can narrow the tools it exposes to the agent with two optional fields: `allowedTools` (keep only the listed tools; drop everything else) or `disabledTools` (drop the listed tools; keep everything else). Both fields apply to stdio, HTTP, and SSE servers. You cannot set both `allowedTools` and `disabledTools` on the same server. Neither field can be set to an empty list (omit the field instead). Each entry is a literal tool name or an fnmatch-style glob pattern (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}`). Entries that match no loaded tool are logged as a warning, not an error.
MCP read-only tool annotations in Auto approval 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`, and 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.
MCP OAuth configuration for remote servers
For remote MCP servers that require OAuth (Slack, GitHub, Notion, Linear, and other hosted MCP endpoints), set `"auth": "oauth"` on the server entry. The `auth: "oauth"` setting is mutually exclusive with an `Authorization` header on the same entry and cannot be set on a stdio server. Tokens are persisted to disk and refreshed automatically.
MCP OAuth login command
Run `dcode mcp login <server>` to authenticate with an OAuth-required MCP server. Behavior depends on the server's host: Spec-compliant servers perform Dynamic Client Registration and open an Authorization Code + PKCE flow in the browser, asking you to paste the redirected URL back into the terminal. Slack uses the same paste-back flow but with Slack's public client preseeded and an optional team ID prompt. GitHub uses RFC 8628 Device Authorization Grant, printing a verification URL and user code for entry in the browser. By default, `dcode mcp login` reads the same auto-discovered configs Deep Agents Code uses at runtime. Pass `--mcp-config <path>` to use a specific file.
MCP OAuth token storage location and format
OAuth tokens are written to `~/.deepagents/.state/mcp-tokens/<server>-<sha256-16(url)>.json` where `<sha256-16(url)>` 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 written atomically (write-to-temp + `rename`). Hashing the URL into the filename means the same server name pointing at different URLs gets independent token files and cannot trample each other.
MCP server status states after startup
Each configured MCP server lands in one of three states after startup: `ok` (connected; tools are loaded and available to the agent), `unauthenticated` (OAuth login required or refresh failed — run `dcode mcp login <server>`), or `error` (pre-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.
MCP server names must match specific pattern
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.
MCP startup confirmation and tool count
On startup, Deep Agents Code auto-discovers the MCP config, connects to each server, discovers its tools, and prints a confirmation like `✓ Loaded 3 MCP tools`. Run `/mcp` in an interactive session to see per-server status, transport, and the loaded tool list. The agent can use those tools for the duration of the session—stdio servers are kept alive between tool calls.
MCP multiple servers configuration example
Multiple MCP servers can be configured simultaneously. Tools from all servers are merged and available to the agent. Example configuration with filesystem stdio server, github stdio server with token, and SSE database server: {"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 ..."}}}}
MCP type field compatibility: transport alias
The `type` field in MCP server configuration can also be written as `transport` for compatibility with other MCP clients.
LangChain MCP servers quickstart
Two LangChain MCP servers are recommended for quickstart: `docs-langchain` at `https://docs.langchain.com/mcp` covers conceptual guides, how-tos, and tutorials; `reference-langchain` at `https://reference.langchain.com/mcp` provides canonical API reference including classes, methods, and parameters. Both servers use HTTP transport type.
MCP re-authentication when refresh fails
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 — the conversation continues without restarting.
MCP servers configuration file locations
Deep Agents Code automatically discovers `.mcp.json` files in three standard locations with the following precedence (lowest to highest): 1) `~/.deepagents/.mcp.json` (user-level, applies to all projects), 2) `<project>/.deepagents/.mcp.json` (project-level subdirectory), 3) `<project>/.mcp.json` (project-level root, Claude Code compatible). When multiple config files exist, their `mcpServers` entries are merged by server name. If the same server name appears in multiple files, the higher-precedence definition replaces the entire earlier server object; nested fields are not deep-merged. The project root is the nearest parent directory containing a `.git` folder, falling back to the current working directory.
Filesystem backend - agent artifact storage and safety
The filesystem backend can read, write, and delete files under root_dir. For Python, generated artifacts are written under a system temporary directory (typically /tmp/ on macOS and Linux), not next to project files. For JavaScript, artifacts are written under the project root in the example directory. Run the filesystem backend only in a dedicated directory and review generated content before publishing.
Tavily search tool implementation for deep research
The tavily_search tool uses Tavily for URL discovery, then fetches full webpage content so the agent can analyze complete sources instead of summaries.
Download files directly from backend without external tools
Files can be downloaded directly from a backend sandbox without using external tools by calling backend.download_files(list_of_filepaths). This is an alternative to using custom tools for artifact retrieval.
File-mutating tools requiring real-time sync
The file-mutating tools that trigger real-time sync are: write_file, edit_file, and execute. In Python, the execute tool is also included. These tool names should be tracked in a Set like FILE_MUTATING_TOOLS to identify which ToolMessages require file refreshes.
Seed project files with uploadFiles before agent runs
Before the agent runs, upload starter files with uploadFiles (JavaScript) or upload_files (Python). For LangSmith sandboxes, pass templateName from a sandbox snapshot when creating the container. After uploading package.json, run sandbox.execute("cd /app && npm install") so dependencies are ready before the first agent turn.
Sandbox file transfer with upload_files and download_files
Sandboxes are isolated containers, so application code can't directly access files inside them. Use `upload_files()` and `download_files()` to move data across the sandbox boundary. Seed the sandbox before the agent runs by uploading user files, skill scripts, configuration, or persistent memories so the agent has what it needs from the start. Retrieve results after the agent finishes by downloading generated artifacts (reports, plots, exports) and syncing updated memories back for future conversations.
Supported multimodal file extensions
The read_file tool supports the following file types: Image files (.png, .jpg, .jpeg, .gif, .webp, .heic, .heif), Video files (.mp4, .mpeg, .mov, .avi, .flv, .mpg, .webm, .wmv, .3gpp), Audio files (.wav, .mp3, .aiff, .aac, .ogg, .flac), and File types (.pdf, .ppt, .pptx).
Built-in read_file tool multimodal support
The harness read_file tool returns standard content blocks for supported multimodal files instead of plain text. The agent can inspect images, documents, and media stored in its filesystem when the selected model supports the corresponding modality. Check the provider's documentation for your model's supported MIME types.
Permissions scope: built-in filesystem tools only
Permissions only apply to the built-in filesystem tools (ls, read_file, glob, grep, write_file, edit_file, delete for Python; ls, read_file, glob, grep, write_file, edit_file for JavaScript). Custom tools and MCP tools that access the filesystem are not covered. Permissions also do not apply to sandbox backends, which support arbitrary command execution via the execute tool.
FilesystemPermission rule structure (Python)
Each FilesystemPermission has three fields: operations (list["read" | "write"] - Operations this rule applies to. "read" covers ls, read_file, glob, grep. "write" covers write_file, edit_file, delete.), paths (list[str] - Glob patterns for matching file paths such as ["/workspace/**"]. Supports ** for recursive matching and {a,b} for alternation.), mode ("allow" | "deny" | "interrupt" - Whether to allow, deny, or pause for human approval on matching operations. Defaults to "allow"). Rules use first-match-wins evaluation: the first rule whose operations and paths match the current call determines the outcome. If no rule matches, the call is allowed (permissive default).
FilesystemPermission rule structure (JavaScript)
Each FilesystemPermission has three fields: operations (("read" | "write")[]) - Operations this rule applies to. "read" covers ls, read_file, glob, grep. "write" covers write_file, edit_file.), paths (string[] - Glob patterns for matching file paths such as ["/workspace/**"]. Supports ** for recursive matching and {a,b} for alternation.), mode ("allow" | "deny" - Whether to allow or deny matching operations. Defaults to "allow"). Paths must be absolute (start with "/") and cannot contain ".." or "~". Invalid paths throw at agent construction time. Rules use first-match-wins evaluation: the first rule whose operations and paths match the current call determines the outcome. If no rule matches, the call is allowed (permissive default).
Delete operation permission checking behavior
Deleting a directory is all-or-nothing: delete checks the write permission on the target and every descendant path, and refuses the entire operation if any of them is denied, rather than removing part of the tree. delete applies this same conservative check to an existing empty directory, since it is still a directory rather than a confirmed leaf target. Deleting a plain file is an exact-match case instead: delete resolves the target the same way write_file and edit_file do, using first-match-wins evaluation, so an earlier, narrower allow rule wins over a later catch-all deny. deepagents>=0.7.3 is required for this exact-match behavior.
Permissions basic usage
Pass a list of FilesystemPermission rules to create_deep_agent (Python) or createDeepAgent (JavaScript). Rules are evaluated in declaration order. The first matching rule wins. If no rule matches, the operation is allowed.
Filesystem tools available in Deep Agents
The virtual filesystem in Deep Agents provides these tools: ls (list files with metadata), read_file (read contents with line numbers, supports offset/limit for large files, multimodal content blocks for non-text files), write_file (create new file or overwrite existing), edit_file (perform exact string replacements with global replace mode), delete (delete file or directory recursively, requires deepagents>=0.7), glob (find files matching patterns), grep (search file contents with multiple output modes), and execute (run shell commands in sandbox backends only).
Supported multimodal file extensions
Deep Agents filesystem tools support multimodal content for the following extensions: Image (.png, .jpg, .jpeg, .gif, .webp, .heic, .heif), Video (.mp4, .mpeg, .mov, .avi, .flv, .mpg, .webm, .wmv, .3gpp), Audio (.wav, .mp3, .aiff, .aac, .ogg, .flac), and File (.pdf, .ppt, .pptx).
Virtual filesystem tools provided by Deep Agents
Deep Agents provide filesystem tools including write_file and read_file. These tools allow agents to offload large search results and manage context.
Filesystem backend for offloading retrieved chunks
When using the retrieve, offload, and delegate pattern, the search_documentation tool writes retrieved chunks to the agent backend using backend.upload_files(). The same backend instance is passed to create_deep_agent (or createDeepAgent in JavaScript) so built-in filesystem tools such as read_file and grep can read the saved paths. Retrieved chunks are written to the agent filesystem under /retrieved/{batch_id}/ directory paths.
Sandbox scripts for code execution in skills
Skills can include scripts in scripts/ directory. Reference scripts in SKILL.md so the agent knows they exist and when to run them. The agent can read scripts from any backend, but to execute them, the agent needs access to a shell, which only sandbox backends provide. Sandbox backends run in isolated containers where skill files stored outside the sandbox are not available unless transferred in first.
Sync skills with sandboxes using custom middleware
When using sandbox backends, skill files outside the container are not available until copied in. Use custom middleware to handle this transfer: before_agent hook reads skill files from the backend and uploads them into the sandbox so the agent can execute scripts from the start; after_agent hook downloads any updated or newly created skill files from the sandbox and writes them back to the backend so changes persist across runs.
Scripts directory guidance for skill resources
The scripts/ directory holds executable code the agent can run, such as API clients, data transforms, or validation checks. Scripts should be self-contained or clearly document dependencies, include helpful error messages, and handle edge cases gracefully. Supported languages depend on agent setup; common options include Python, Bash, and JavaScript or TypeScript. To execute scripts rather than only read them, use sandbox backends.
References directory guidance for skill resources
The references/ directory holds supplementary documentation the agent reads on demand. Use it for material too detailed for SKILL.md but still task-specific, such as: REFERENCE.md for detailed technical reference, FORMS.md for form templates or structured data formats, domain-specific guides (finance.md, legal.md). Keep individual reference files focused since the agent loads them only when needed, so smaller files use less context.
Assets directory guidance for skill resources
The assets/ directory holds static resources the agent uses but does not need to read as instructions, such as: document or configuration templates, images (diagrams, examples), data files (lookup tables, schemas). Describe in SKILL.md when the agent should open or copy each asset.
Reference supporting files from SKILL.md with relative paths
When referencing supporting files from SKILL.md, use paths relative to the skill root, e.g., 'references/api-patterns.md' or 'scripts/extract.py'. For each file referenced, state what it contains and when the agent should use it. Keep references one level deep from SKILL.md and avoid deeply nested reference chains that force the agent through multiple reads to reach information.
Troubleshoot: Supporting files not found
If agent reads SKILL.md but cannot access scripts, references, or assets: (1) Reference files from SKILL.md - agent does not auto-discover supporting files, state what each contains and when to use it, use relative paths from skill root; (2) Keep paths within skill directory - file paths resolve against backend, confirm supporting files exist at referenced paths; (3) Sync skills into sandboxes - if using sandbox backends, skill files outside container are not available until copied in.
Troubleshoot: Scripts fail to run
If agent reads a script but cannot run it: The agent can read scripts from any backend, but running them requires a sandbox backend. See Execute code with skills section for sandbox setup.
Code execution through sandbox scripts in skills
Without code execution, skills are passive - the agent reads instructions and follows them using available tools. Code execution turns skills into active capabilities. A skill can ship a tested script that calls an API, transforms data, validates output, or runs a pipeline - and the agent executes it deterministically rather than regenerating logic from instructions each time. This is valuable for workflows requiring exact behavior (data transformations, API integrations, compliance checks) or depending on libraries inaccessible through tool calls.
Filesystem tools and read_file multimodal support
Deep Agents expose a filesystem surface to the agent via tools: ls, read_file, write_file, edit_file, delete, glob, and grep. These tools operate through a pluggable backend. The read_file tool natively supports image files (.png, .jpg, .jpeg, .gif, .webp) in Python across all backends, returning them as multimodal content blocks. In JavaScript, read_file supports binary files (images, PDFs, audio, video) across all backends, returning a ReadResult with typed content and mimeType.
Execute tool availability
Sandboxes and LocalShellBackend provide an execute tool in addition to filesystem tools.
Permissions control filesystem access
Use permissions to declaratively control which files and directories the agent can read or write. Permissions apply to the built-in filesystem tools and are evaluated before the backend is called.
Two planes of file access in sandboxes
There are two distinct ways files move in and out of a sandbox: Agent filesystem tools (read_file, write_file, edit_file, delete, ls, glob, grep, execute) are the tools the LLM calls during execution, which go through execute() inside the sandbox. File transfer APIs (uploadFiles/upload_files and downloadFiles/download_files) are methods your application code calls using the provider's native file transfer APIs (not shell commands) and are designed for moving files between your host environment and the sandbox.
Use upload_files to seed the sandbox before agent runs
Use upload_files() to populate the sandbox before the agent runs. File contents are provided as bytes and paths must be absolute. This is used to seed the sandbox with source code, configuration, or data before the agent runs.
Use download_files to retrieve artifacts after agent finishes
Use download_files() to retrieve files from the sandbox after the agent finishes. This is used to retrieve artifacts such as generated code, build outputs, and reports after the agent completes its work.
All standard filesystem tools provided in sandboxes
When you configure a sandbox backend, the agent gets all standard filesystem tools including ls, read_file, write_file, edit_file, delete, glob, and grep, plus the execute tool for running arbitrary shell commands.
Built-in harness tools for Python
Every Deep Agent in Python comes with these built-in tools: ls (list files in a directory), read_file (read file contents with pagination and multimodal support), write_file (create a new file or overwrite an existing one), edit_file (perform exact string replacements in files), delete (delete a file or directory and its contents recursively; requires deepagents>=0.7), glob (find files matching a glob pattern), grep (search file contents), execute (run shell commands on sandbox backends only), and task (spawn a subagent to handle a delegated task).
Built-in harness tools for JavaScript
Every Deep Agent in JavaScript comes with these built-in tools: ls (list files in a directory), read_file (read file contents with pagination and multimodal support), write_file (create new files), edit_file (perform exact string replacements in files), glob (find files matching a glob pattern), grep (search file contents), execute (run shell commands on sandbox backends only), and task (spawn a subagent to handle a delegated task).