A directory holding exactly one file adds a path level for nothing; cordis-catalog/ keeps its folder because it holds two sibling pages (events.md + services.md), matching config-catalog.md which was born flat. docs/tool-catalog/tools.md -> docs/tool-catalog.md and docs/persistence-catalog/log-events.md -> docs/persistence-catalog.md; their generators' OUT paths and in-page relative links drop one directory level, and every citation repo-wide (docs, RFCs, package READMEs, generator headers) is updated. graph-atlas.md, config-catalog.md, and the doc graphs regenerate with the new paths.
13 KiB
Tool Schema Catalog
Every model-facing tool a shipped plugin contributes to ctx.tools: the name, description, and JSON-Schema parameters the model receives via the system-prompt assembly. It complements the cordis events & services catalogs (the wiring a plugin listens to and calls) and core-data-structures/ (the types those signatures move) — this page is the tools the agent is offered.
This file is GENERATED and verified fresh by pnpm run verify-tool-catalog (part of doc-sync) — do not edit it by hand. Unlike the cordis catalog (a pure source-AST pass), this generator BOOTS each tool plugin on a real context and reads ctx.tools.schemas(), because a tool schema is not statically knowable (runtime-spread enums, concatenated descriptions, config-driven names, raw-JSON-Schema MCP tools). A completeness guard globs packages/*/tool-* and fails if any package is missing from the generator's boot manifest, so a new tool cannot be silently undocumented. See the tool-schema-catalog RFC.
Scope: shipped product tools under packages/*/tool-*, each booted with its DEFAULT config. The registered tool NAME can be a load-time config (e.g. tool-subagent's toolName), so a deployment may surface a package under a different or additional name — a per-package note records those shipped aliases where they exist. The examples/ demo tools (e.g. echo) are excluded, matching the cordis catalog's packages-only scope.
Tool Package Map
This table connects model-visible tool names to the plugin package and service seams behind them. Exact JSON Schemas follow in the package sections below.
| Tool package | Model-visible names | Requires | Writes / affects | Shipped aliases | Deployment note |
|---|---|---|---|---|---|
@deepseek-ai/dsh-tool-bash |
bash, bash_kill, bash_output |
ctx.tools, ctx.bash |
tool/call, tool/result, context/message via agent.inject() for background completion notices |
- | The bash/bash_output/bash_kill tools are model-facing consumers of the bash executor seam. |
@deepseek-ai/dsh-tool-fs |
edit, read, write |
ctx.tools, ctx.fs, ctx.systemPrompt |
tool/call, fs/write-intent or fs/edit-intent for mutations, fs/observed after successful file operations, tool/result |
- | The read-before-write/edit policy is added by @deepseek-ai/dsh-fs-policy (an fs/* event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The tool schemas above are identical with or without the policy plugin. |
@deepseek-ai/dsh-tool-subagent |
subagent |
ctx.tools, ctx.subagents |
tool/call, tool/result, child session events through the chosen provider |
subagent, subagent_fork |
The registered tool name is the load-time toolName config (default subagent); the schema above is that default. The shipped example agents load this package once per subagent backend, so the model additionally sees subagent_fork (bound to the fork backend) with an identical schema — see examples/coding-agent/cordis.yml and examples/acp-agent/cordis.yml. |
@deepseek-ai/dsh-tool-todo |
todo_write |
ctx.tools, owning Agent session |
tool/call, todo/write, tool/result |
- | todo_write is session-owned state; UIs render the latest todo/write event as a checklist or ACP plan. |
@deepseek-ai/dsh-tool-web |
web_fetch, web_search |
ctx.tools, ctx.web, ctx.systemPrompt |
tool/call, tool/result |
- | web_search and web_fetch keep provider selection behind ctx.web so model-visible schemas stay stable across backend swaps. |
@deepseek-ai/dsh-tool-bash
bash
Execute a bash command (bash -c) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass workdir instead of using cd. Non-zero exits are reported as [exit code: N]. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set run_in_background: true for long-running commands: the call returns a task id immediately; poll it with bash_output and stop it with bash_kill.
{
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute."
},
"description": {
"type": "string",
"description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."
},
"timeoutMs": {
"type": "number",
"description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."
},
"workdir": {
"type": "string",
"description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."
},
"run_in_background": {
"type": "boolean",
"description": "Run in the background and return a task id immediately. No timeout applies."
}
},
"required": [
"command",
"description"
]
}
Source: packages/bash/tool-bash/src/index.ts
bash_kill
Ask the executor to kill a running background bash task by task id.
{
"type": "object",
"properties": {
"task_id": {
"type": "string",
"description": "Task id returned by the bash tool."
}
},
"required": [
"task_id"
]
}
Source: packages/bash/tool-bash/src/index.ts
bash_output
Read new output from a background bash task started with bash + run_in_background. Returns only output produced since the previous bash_output call, plus the task status. Tasks keep running while you do other work; poll again later for more output.
{
"type": "object",
"properties": {
"task_id": {
"type": "string",
"description": "Task id returned by the bash tool."
}
},
"required": [
"task_id"
]
}
Source: packages/bash/tool-bash/src/index.ts
The bash/bash_output/bash_kill tools are model-facing consumers of the bash executor seam.
@deepseek-ai/dsh-tool-fs
edit
Edit an existing UTF-8 text file by replacing literal text.
{
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Path to edit, resolved by the filesystem backend."
},
"old_string": {
"type": "string",
"description": "Literal text to replace. Must match exactly."
},
"new_string": {
"type": "string",
"description": "Literal replacement text. Use an empty string to delete the match."
},
"replace_all": {
"type": "boolean",
"description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once."
}
},
"required": [
"file_path",
"old_string",
"new_string"
]
}
Source: packages/fs/tool-fs/src/index.ts
read
Read a UTF-8 text file and return line-numbered content.
{
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Path to read, resolved by the filesystem backend."
},
"offset": {
"type": "number",
"description": "1-based first line to return. Defaults to 1."
},
"limit": {
"type": "number",
"description": "Maximum number of lines to return. Defaults to 2000."
}
},
"required": [
"file_path"
]
}
Source: packages/fs/tool-fs/src/index.ts
write
Create or fully replace a UTF-8 text file.
{
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Path to write, resolved by the filesystem backend."
},
"content": {
"type": "string",
"description": "Full UTF-8 text content to write."
}
},
"required": [
"file_path",
"content"
]
}
Source: packages/fs/tool-fs/src/index.ts
The read-before-write/edit policy is added by @deepseek-ai/dsh-fs-policy (an fs/* event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The tool schemas above are identical with or without the policy plugin.
@deepseek-ai/dsh-tool-subagent
subagent
Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation.
{
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "A short (3-5 word) description of the delegated task, for display."
},
"prompt": {
"type": "string",
"description": "The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."
}
},
"required": [
"description",
"prompt"
]
}
Source: packages/subagent/tool-subagent/src/index.ts
The registered tool name is the load-time toolName config (default subagent); the schema above is that default. The shipped example agents load this package once per subagent backend, so the model additionally sees subagent_fork (bound to the fork backend) with an identical schema — see examples/coding-agent/cordis.yml and examples/acp-agent/cordis.yml.
@deepseek-ai/dsh-tool-todo
todo_write
Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Keep AT MOST ONE todo in_progress at a time; while work remains, exactly one active task should be in_progress. Mark a todo completed the moment it is done (do not batch completions), and allow no in_progress item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: pending (not started), in_progress (being worked on now), completed (finished).
{
"type": "object",
"properties": {
"todos": {
"type": "array",
"description": "The COMPLETE task list, replacing any previous list.",
"items": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "What the task is — a short imperative line."
},
"status": {
"type": "string",
"description": "pending (not started) | in_progress (now) | completed (done).",
"enum": [
"pending",
"in_progress",
"completed"
]
}
},
"required": [
"content",
"status"
]
}
}
},
"required": [
"todos"
]
}
Source: packages/todo/tool-todo/src/index.ts
todo_write is session-owned state; UIs render the latest todo/write event as a checklist or ACP plan.
@deepseek-ai/dsh-tool-web
web_fetch
Fetch the content of a specific HTTP(S) URL and return it decoded to text.
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The HTTP(S) URL to fetch."
},
"timeout_ms": {
"type": "number",
"description": "Optional fetch timeout in milliseconds (capped by the provider)."
}
},
"required": [
"url"
]
}
Source: packages/web/tool-web/src/index.ts
web_search
Search the web for current information. Returns an optional summary answer and a list of source URLs.
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query."
}
},
"required": [
"query"
]
}
Source: packages/web/tool-web/src/index.ts
web_search and web_fetch keep provider selection behind ctx.web so model-visible schemas stay stable across backend swaps.