# AI Tools
Three modules provide the tools an LLM can call: `mcp_tools` exposes a
large built-in tool set over MCP, `rpc_tools` turns `@rpc`-registered app
methods into tools on demand, and `ai/subagent` runs isolated subagent
sessions with restricted tools. The AI orchestrator merges them
into the tool loop.
import "deft/stdext/mcp_tools" as mcp-tools import "deft/stdext/rpc_tools" as rpc-tools import "deft/stdext/ai/subagent" as subagent
## MCP Tools
`mcp_tools` is the MCP tool server. Tools are plain typed functions with
`@doc`; `register-tools` creates the `:deft` MCP server and adds them,
and `start-mcp-server` serves `/mcp` over HTTP.
| Group | Tools |
|---|---|
| Help / discovery | `help-lookup`, `list-help-topics`, `list-stdext`, `list-apps` |
| Codebase | `read-source`, `grep-codebase`, `search-codebase`, `find-files`, `find-references`, `rename-symbol` |
| Editor bridge | `editor-context`, `editor-open-file`, `editor-insert`, `editor-replace-selection`, `editor-replace-buffer`, `editor-goto-line`, `editor-get-selection`, `editor-get-buffer`, `editor-get-buffer-range` |
| Git / process | `git-log`, `git-diff`, `run-command`, `run-tests`, `run-diff`, `run-patch`, `write-patch` |
| Files | `create-file` |
| Metadata | `symbol-lookup`, `fts-search`, `recently-changed` |
| Runtime | `eval-dft`, `web-fetch` |
| Plumbing | `call-tool`, `get-tools-openai`, `get-tools-anthropic`, `register-tools`, `start-mcp-server` |
[mcp-tools/register-tools] # idempotent set port [mcp-tools/start-mcp-server 7433] # /mcp endpoint, tries 7433..7441 set r [mcp-tools/call-tool "help-lookup" %{ "topic" "syntax" }]
`call-tool` is the in-TUI dispatcher used by chat; the HTTP endpoint
speaks the MCP protocol. The metadata tools open `.deft/meta.db`
lazily — see Meta.
## RPC Tools
`rpc_tools` is the complementary, opt-in source: it converts methods
registered with `@rpc` into provider-format tool schemas and dispatches
calls through `[rpc runtime method …]`. Exposure is per app
(runtime), never per method.
Config shape (delivered by the chat app):
:chat/rpc-tools %{ :include @{ "editor" "diff" } :exclude @{} }
The shipped default include is empty, so nothing is exposed until the
user opts in. Tool names are `runtime__method` (collision-free).
| Def | Description |
|---|---|
| `list-methods` | Registered methods filtered by the enabled apps |
| `get-tools-openai` / `get-tools-anthropic` | Schemas in provider format |
| `describe` | JSON string of the OpenAI-format tools |
| `call-tool` | Dispatch a call, coercing string args to declared types |
| `config-filter` | Read the `:chat/rpc-tools` config |
[rpc-tools/get-tools-openai %{ :include @{ "editor" } }]
[rpc-tools/call-tool "editor__cmd-open-file" %{ "path" "app.dft" }]
## Subagents
`ai/subagent` runs isolated sessions with their own system prompt and a
restricted tool allow-list, exposed to the parent model as the
`run-subagent` MCP tool. Built-ins:
| Name | Focus | Max iterations |
|---|---|---|
| `code-explorer` | read/search tools | 8 |
| `code-reviewer` | review-focused tools | 5 |
| `code-writer` | create/edit/test tools | 12 |
| `fast-responder` | no tools, fast model | 1 |
| Def | Description |
|---|---|
| `run-named` | Run a built-in subagent; inherits the parent cfg |
| `run-adhoc` | Custom system prompt + tool allow-list |
| `register-tool` | Idempotently add `run-subagent` to the `:deft` MCP server |
| `list-names` / `list-all` / `lookup` | Registry introspection |
| `set-provider-cfg` | Stash provider/cfg for the MCP handler (called by chat) |
Subagents return `[subagent:<name>] <answer>`.
## See Also
- AI — provider registry and orchestration
- MCP — the protocol and `mcp/*` stdlib primitives
- RPC — `@rpc` method registration
- Chat app help — the primary consumer