{
"_note": "Redacted snapshot of OpenRouter chat-completions request captured via openclaw 2026.4.26 debug proxy. messages[] removed; tools[] preserved verbatim (the bug is the absence of MCP-server tools from this array).",
"_messages_redacted": {
"count": 91,
"role_counts": {
"system": 1,
"user": 31,
"assistant": 37,
"tool": 22
}
},
"model": "google/gemini-2.5-pro",
"stream": true,
"max_completion_tokens": 32000,
"reasoning": {
"effort": "minimal"
},
"tools_count": 15,
"tools": [
{
"type": "function",
"function": {
"name": "edit",
"description": "Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",
"parameters": {
"type": "object",
"required": [
"path",
"edits"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the file to edit (relative or absolute)"
},
"edits": {
"type": "array",
"items": {
"type": "object",
"required": [
"oldText",
"newText"
],
"properties": {
"oldText": {
"type": "string",
"description": "Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call."
},
"newText": {
"type": "string",
"description": "Replacement text for this targeted edit."
}
},
"additionalProperties": false
},
"description": "One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead."
}
},
"additionalProperties": false
}
}
},
{
"type": "function",
"function": {
"name": "exec",
"description": "Execute shell commands with background continuation for work that starts now. Use yieldMs/background to continue later via process tool. For long-running work started now, rely on automatic completion wake when it is enabled and the command emits output or fails; otherwise use process to confirm completion. Use process whenever you need logs, status, input, or intervention. Use pty=true for TTY-required commands (terminal UIs, coding agents).",
"parameters": {
"type": "object",
"required": [
"command"
],
"properties": {
"command": {
"type": "string",
"description": "Shell command to execute"
},
"workdir": {
"type": "string",
"description": "Working directory (defaults to cwd)"
},
"env": {
"type": "object",
"patternProperties": {
"^.*$": {
"type": "string"
}
}
},
"yieldMs": {
"type": "number",
"description": "Milliseconds to wait before backgrounding (default 10000)"
},
"background": {
"type": "boolean",
"description": "Run in background immediately"
},
"timeout": {
"type": "number",
"description": "Timeout in seconds (optional, kills process on expiry)"
},
"pty": {
"type": "boolean",
"description": "Run in a pseudo-terminal (PTY) when available (TTY-required CLIs, coding agents)"
},
"elevated": {
"type": "boolean",
"description": "Run on the host with elevated permissions (if allowed)"
},
"host": {
"type": "string",
"description": "Exec host/target (auto|sandbox|gateway|node)."
},
"security": {
"type": "string",
"description": "Exec security mode (deny|allowlist|full)."
},
"ask": {
"type": "string",
"description": "Exec ask mode (off|on-miss|always)."
},
"node": {
"type": "string",
"description": "Node id/name for host=node."
}
}
}
}
},
{
"type": "function",
"function": {
"name": "image",
"description": "Analyze one or more images with a vision model. Use image for a single path/URL, or images for multiple (up to 20). Only use this tool when images were NOT already provided in the user's message. Images mentioned in the prompt are automatically visible to you.",
"parameters": {
"type": "object",
"properties": {
"prompt": {
"type": "string"
},
"image": {
"type": "string",
"description": "Single image path or URL."
},
"images": {
"type": "array",
"items": {
"type": "string"
},
"description": "Multiple image paths or URLs (up to maxImages, default 20)."
},
"model": {
"type": "string"
},
"maxBytesMb": {
"type": "number"
},
"maxImages": {
"type": "number"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "process",
"description": "Manage running exec sessions for commands already started: list, poll, log, write, send-keys, submit, paste, kill. Use poll/log when you need status, logs, quiet-success confirmation, or completion confirmation when automatic completion wake is unavailable. Use write/send-keys/submit/paste/kill for input or intervention.",
"parameters": {
"type": "object",
"required": [
"action"
],
"properties": {
"action": {
"type": "string",
"description": "Process action"
},
"sessionId": {
"type": "string",
"description": "Session id for actions other than list"
},
"data": {
"type": "string",
"description": "Data to write for write"
},
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "Key tokens to send for send-keys"
},
"hex": {
"type": "array",
"items": {
"type": "string"
},
"description": "Hex bytes to send for send-keys"
},
"literal": {
"type": "string",
"description": "Literal string for send-keys"
},
"text": {
"type": "string",
"description": "Text to paste for paste"
},
"bracketed": {
"type": "boolean",
"description": "Wrap paste in bracketed mode"
},
"eof": {
"type": "boolean",
"description": "Close stdin after write"
},
"offset": {
"type": "number",
"description": "Log offset"
},
"limit": {
"type": "number",
"description": "Log length"
},
"timeout": {
"type": "number",
"description": "For poll: wait up to this many milliseconds before returning",
"minimum": 0
}
}
}
}
},
{
"type": "function",
"function": {
"name": "read",
"description": "Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, output is truncated to 2000 lines or 50KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.",
"parameters": {
"type": "object",
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the file to read (relative or absolute)"
},
"offset": {
"type": "number",
"description": "Line number to start reading from (1-indexed)"
},
"limit": {
"type": "number",
"description": "Maximum number of lines to read"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "session_status",
"description": "Show a /status-equivalent session status card for the current or another visible session, including usage, time, cost when available, and linked background task context. Use `sessionKey=\"current\"` for the current session; do not use UI/client labels such as `openclaw-tui` as session keys. Optional `model` sets a per-session model override; `model=default` resets overrides. Use this for questions like what model is active or how a session is configured.",
"parameters": {
"type": "object",
"properties": {
"sessionKey": {
"type": "string"
},
"model": {
"type": "string"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "sessions_history",
"description": "Fetch sanitized message history for a visible session. Supports limits and optional tool messages; use this to inspect another session before replying, debugging, or resuming work.",
"parameters": {
"type": "object",
"required": [
"sessionKey"
],
"properties": {
"sessionKey": {
"type": "string"
},
"limit": {
"type": "number",
"minimum": 1
},
"includeTools": {
"type": "boolean"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "sessions_list",
"description": "List visible sessions with optional filters for kind, label, agentId, search, recent activity, derived titles, and last-message previews. Use this to discover a target session before calling sessions_history or sessions_send.",
"parameters": {
"type": "object",
"properties": {
"kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"limit": {
"type": "number",
"minimum": 1
},
"activeMinutes": {
"type": "number",
"minimum": 1
},
"messageLimit": {
"type": "number",
"minimum": 0
},
"label": {
"type": "string",
"minLength": 1
},
"agentId": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"search": {
"type": "string",
"minLength": 1
},
"includeDerivedTitles": {
"type": "boolean"
},
"includeLastMessage": {
"type": "boolean"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "sessions_send",
"description": "Send a message into another visible session by sessionKey or label. Use this to delegate follow-up work to an existing session; waits for the target run and returns the updated assistant reply when available.",
"parameters": {
"type": "object",
"required": [
"message"
],
"properties": {
"sessionKey": {
"type": "string"
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"agentId": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"message": {
"type": "string"
},
"timeoutSeconds": {
"type": "number",
"minimum": 0
}
}
}
}
},
{
"type": "function",
"function": {
"name": "sessions_spawn",
"description": "Spawn a clean isolated session by default with the native subagent runtime. `mode=\"run\"` is one-shot and `mode=\"session\"` is persistent or thread-bound. Subagents inherit the parent workspace directory automatically. For native subagents only, set `context=\"fork\"` when the child needs the current transcript context; otherwise omit it or use `context=\"isolated\"`. Use this when the work should happen in a fresh child session instead of the current one.",
"parameters": {
"type": "object",
"required": [
"task"
],
"properties": {
"task": {
"type": "string"
},
"label": {
"type": "string"
},
"runtime": {
"type": "string",
"enum": [
"subagent"
]
},
"agentId": {
"type": "string"
},
"model": {
"type": "string"
},
"thinking": {
"type": "string"
},
"cwd": {
"type": "string"
},
"runTimeoutSeconds": {
"type": "number",
"minimum": 0
},
"timeoutSeconds": {
"type": "number",
"minimum": 0
},
"thread": {
"type": "boolean"
},
"mode": {
"type": "string",
"enum": [
"run",
"session"
]
},
"cleanup": {
"type": "string",
"enum": [
"delete",
"keep"
]
},
"sandbox": {
"type": "string",
"enum": [
"inherit",
"require"
]
},
"context": {
"type": "string",
"enum": [
"isolated",
"fork"
],
"description": "Native subagent context mode. Omit or use \"isolated\" for a clean child session; use \"fork\" only when the child needs the requester transcript context."
},
"lightContext": {
"type": "boolean",
"description": "When true, spawned subagent runs use lightweight bootstrap context. Only applies to runtime='subagent'."
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"content"
],
"properties": {
"name": {
"type": "string"
},
"content": {
"type": "string"
},
"encoding": {
"type": "string",
"enum": [
"utf8",
"base64"
]
},
"mimeType": {
"type": "string"
}
}
},
"maxItems": 50
},
"attachAs": {
"type": "object",
"properties": {
"mountPath": {
"type": "string"
}
}
}
}
}
}
},
{
"type": "function",
"function": {
"name": "sessions_yield",
"description": "End your current turn. Use after spawning subagents to receive their results as the next message.",
"parameters": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "subagents",
"description": "List, kill, or steer spawned sub-agents for this requester session. Use this for sub-agent orchestration.",
"parameters": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"list",
"kill",
"steer"
]
},
"target": {
"type": "string"
},
"message": {
"type": "string"
},
"recentMinutes": {
"type": "number",
"minimum": 1
}
}
}
}
},
{
"type": "function",
"function": {
"name": "web_fetch",
"description": "Fetch and extract readable content from a URL (HTML \u2192 markdown/text). Use for lightweight page access without browser automation.",
"parameters": {
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "HTTP or HTTPS URL to fetch."
},
"extractMode": {
"type": "string",
"enum": [
"markdown",
"text"
],
"description": "Extraction mode (\"markdown\" or \"text\").",
"default": "markdown"
},
"maxChars": {
"type": "number",
"description": "Maximum characters to return (truncates when exceeded).",
"minimum": 100
}
}
}
}
},
{
"type": "function",
"function": {
"name": "web_search",
"description": "Search the web using DuckDuckGo. Returns titles, URLs, and snippets with no API key required.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query string."
},
"count": {
"type": "number",
"description": "Number of results to return (1-10).",
"minimum": 1,
"maximum": 10
},
"region": {
"type": "string",
"description": "Optional DuckDuckGo region code such as us-en, uk-en, or de-de."
},
"safeSearch": {
"type": "string",
"description": "SafeSearch level: strict, moderate, or off."
}
},
"additionalProperties": false
}
}
},
{
"type": "function",
"function": {
"name": "write",
"description": "Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.",
"parameters": {
"type": "object",
"required": [
"path",
"content"
],
"properties": {
"path": {
"type": "string",
"description": "Path to the file to write (relative or absolute)"
},
"content": {
"type": "string",
"description": "Content to write to the file"
}
}
}
}
}
]
}```
</details>
MCP server tools missing from agent's request body in 2026.4.26
Summary
Configured MCP servers (
gmail,outlook) spawn correctly and respond to direct stdio JSON-RPC probes with their full tool catalog, but their tools never appear in thetools[]array of the request body that the gateway sends to the LLM provider. Only the bundled OpenClaw tools (read,write,exec,sessions_*,web_search,web_fetch, etc.) are present. Result: the agent reports "I don't have access to those tools" while the underlying MCP servers are healthy and serving tools on stdio.This worked in 2026.4.15 and broke at some point between then and 2026.4.26 (we upgraded straight from 4.15 to 4.26, so we cannot identify the specific intermediate release).
Environment
2026.4.26 (be8c246)v22.22.226.4.1npm i -g openclawConfiguration
Relevant
~/.openclaw/openclaw.jsonexcerpt:openclaw mcp listconfirms both are registered:Tool profile:
coding. Configuredtools.alsoAllow:["web_search", "web_fetch"](these DO get through to the agent — confirmingalsoAllowworks in general; just not for MCP tools).Expected behavior
The agent's outbound request to the LLM provider (here, OpenRouter) should include all bundled tools plus the tools advertised by configured MCP servers (
outlook__*,gmail__*).Actual behavior
The outbound request body's
tools[]array contains exactly 15 entries — all of them OpenClaw bundled tools. No MCP tools. The agent then reports the MCP-backed capability as unavailable.Reproduction steps
mcp.servers(any working stdio MCP server will do).tools/listcleanly.body.tools[]— MCP tools are absent.Captured evidence
The 15 tool names that actually appeared in
body.tools[]:No
outlook__*, nogmail__*.The full redacted request body (
messages[]stripped, all other request-shape preserved) is inlined at the bottom of this issue under "Redacted request body" if you want to feed it to a unit test or compare against your own capture.For comparison, a direct stdio probe of the same
outlookMCP server returns 50+ tools (outlook_list_inbox,outlook_search_mail,outlook_read_message,outlook_send_message,outlook_list_events, etc.) and successfultools/callinvocations:{ "jsonrpc": "2.0", "id": 2, "result": { "content": [{"type": "text", "text": "{\"display_name\": ..., \"email\": ..., ...}"}], "isError": false } }So the MCP server is healthy and serving tools; the gateway just isn't including them in the request to the model.
What I ruled out
Confirmed via testing that none of these are the cause:
tools.profilecoding,messaging,fulltools.alsoAllow: ["outlook__*", "gmail__*"]tools.sandbox.toolsplugins.allowcontaining"outlook","gmail","mcp"mcp.sessionIdleTtlMs: 0(prevent idle eviction)openclaw doctoropenclaw doctorreports the gateway, plugins (7 loaded, 0 errors), and channel as healthy. The bug is invisible to its checks.Last known working version
2026.4.15 — pre-upgrade gateway logs show
outlook__*andgmail__*tool names being registered and exposed to the agent. We upgraded directly from2026.4.15to2026.4.26, so the specific regressing release is somewhere in4.16…4.26. Candidate suspects from the changelog:api.registerEmbeddedExtensionFactory(...)compatibility path." (Note: our two custom non-bundled plugins do NOT use that API; bundled-MCP loading might.)Diagnostic data — how I captured the evidence
For maintainers reproducing on their end:
~/.openclaw/debug-proxy/blobs/<blob_id>.bin.gz(gunzip → JSON), or query~/.openclaw/debug-proxy/capture.sqlite:OPENCLAW_CACHE_TRACE=1 OPENCLAW_CACHE_TRACE_PROMPT=1writes pipeline-stage snapshots to~/.openclaw/logs/cache-trace.jsonlbut does not capture the final outbound request body — the debug proxy is the right tool for this.Impact
For users who rely on configured MCP servers to extend agent capability (Outlook/Gmail/etc.), the agent appears unable to use those capabilities even though every other layer (config, server process,
openclaw mcp list) reports healthy. The failure mode is silent — no warnings or errors ingateway.logorgateway.err.log, andopenclaw doctorreports the system clean.Workarounds
None we found. Options for affected users:
2026.4.15(last known working version on this stack).Redacted request body (click to expand — full
tools[]array, messages stripped){ "_note": "Redacted snapshot of OpenRouter chat-completions request captured via openclaw 2026.4.26 debug proxy. messages[] removed; tools[] preserved verbatim (the bug is the absence of MCP-server tools from this array).", "_messages_redacted": { "count": 91, "role_counts": { "system": 1, "user": 31, "assistant": 37, "tool": 22 } }, "model": "google/gemini-2.5-pro", "stream": true, "max_completion_tokens": 32000, "reasoning": { "effort": "minimal" }, "tools_count": 15, "tools": [ { "type": "function", "function": { "name": "edit", "description": "Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.", "parameters": { "type": "object", "required": [ "path", "edits" ], "properties": { "path": { "type": "string", "description": "Path to the file to edit (relative or absolute)" }, "edits": { "type": "array", "items": { "type": "object", "required": [ "oldText", "newText" ], "properties": { "oldText": { "type": "string", "description": "Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call." }, "newText": { "type": "string", "description": "Replacement text for this targeted edit." } }, "additionalProperties": false }, "description": "One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead." } }, "additionalProperties": false } } }, { "type": "function", "function": { "name": "exec", "description": "Execute shell commands with background continuation for work that starts now. Use yieldMs/background to continue later via process tool. For long-running work started now, rely on automatic completion wake when it is enabled and the command emits output or fails; otherwise use process to confirm completion. Use process whenever you need logs, status, input, or intervention. Use pty=true for TTY-required commands (terminal UIs, coding agents).", "parameters": { "type": "object", "required": [ "command" ], "properties": { "command": { "type": "string", "description": "Shell command to execute" }, "workdir": { "type": "string", "description": "Working directory (defaults to cwd)" }, "env": { "type": "object", "patternProperties": { "^.*$": { "type": "string" } } }, "yieldMs": { "type": "number", "description": "Milliseconds to wait before backgrounding (default 10000)" }, "background": { "type": "boolean", "description": "Run in background immediately" }, "timeout": { "type": "number", "description": "Timeout in seconds (optional, kills process on expiry)" }, "pty": { "type": "boolean", "description": "Run in a pseudo-terminal (PTY) when available (TTY-required CLIs, coding agents)" }, "elevated": { "type": "boolean", "description": "Run on the host with elevated permissions (if allowed)" }, "host": { "type": "string", "description": "Exec host/target (auto|sandbox|gateway|node)." }, "security": { "type": "string", "description": "Exec security mode (deny|allowlist|full)." }, "ask": { "type": "string", "description": "Exec ask mode (off|on-miss|always)." }, "node": { "type": "string", "description": "Node id/name for host=node." } } } } }, { "type": "function", "function": { "name": "image", "description": "Analyze one or more images with a vision model. Use image for a single path/URL, or images for multiple (up to 20). Only use this tool when images were NOT already provided in the user's message. Images mentioned in the prompt are automatically visible to you.", "parameters": { "type": "object", "properties": { "prompt": { "type": "string" }, "image": { "type": "string", "description": "Single image path or URL." }, "images": { "type": "array", "items": { "type": "string" }, "description": "Multiple image paths or URLs (up to maxImages, default 20)." }, "model": { "type": "string" }, "maxBytesMb": { "type": "number" }, "maxImages": { "type": "number" } } } } }, { "type": "function", "function": { "name": "process", "description": "Manage running exec sessions for commands already started: list, poll, log, write, send-keys, submit, paste, kill. Use poll/log when you need status, logs, quiet-success confirmation, or completion confirmation when automatic completion wake is unavailable. Use write/send-keys/submit/paste/kill for input or intervention.", "parameters": { "type": "object", "required": [ "action" ], "properties": { "action": { "type": "string", "description": "Process action" }, "sessionId": { "type": "string", "description": "Session id for actions other than list" }, "data": { "type": "string", "description": "Data to write for write" }, "keys": { "type": "array", "items": { "type": "string" }, "description": "Key tokens to send for send-keys" }, "hex": { "type": "array", "items": { "type": "string" }, "description": "Hex bytes to send for send-keys" }, "literal": { "type": "string", "description": "Literal string for send-keys" }, "text": { "type": "string", "description": "Text to paste for paste" }, "bracketed": { "type": "boolean", "description": "Wrap paste in bracketed mode" }, "eof": { "type": "boolean", "description": "Close stdin after write" }, "offset": { "type": "number", "description": "Log offset" }, "limit": { "type": "number", "description": "Log length" }, "timeout": { "type": "number", "description": "For poll: wait up to this many milliseconds before returning", "minimum": 0 } } } } }, { "type": "function", "function": { "name": "read", "description": "Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, output is truncated to 2000 lines or 50KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.", "parameters": { "type": "object", "required": [ "path" ], "properties": { "path": { "type": "string", "description": "Path to the file to read (relative or absolute)" }, "offset": { "type": "number", "description": "Line number to start reading from (1-indexed)" }, "limit": { "type": "number", "description": "Maximum number of lines to read" } } } } }, { "type": "function", "function": { "name": "session_status", "description": "Show a /status-equivalent session status card for the current or another visible session, including usage, time, cost when available, and linked background task context. Use `sessionKey=\"current\"` for the current session; do not use UI/client labels such as `openclaw-tui` as session keys. Optional `model` sets a per-session model override; `model=default` resets overrides. Use this for questions like what model is active or how a session is configured.", "parameters": { "type": "object", "properties": { "sessionKey": { "type": "string" }, "model": { "type": "string" } } } } }, { "type": "function", "function": { "name": "sessions_history", "description": "Fetch sanitized message history for a visible session. Supports limits and optional tool messages; use this to inspect another session before replying, debugging, or resuming work.", "parameters": { "type": "object", "required": [ "sessionKey" ], "properties": { "sessionKey": { "type": "string" }, "limit": { "type": "number", "minimum": 1 }, "includeTools": { "type": "boolean" } } } } }, { "type": "function", "function": { "name": "sessions_list", "description": "List visible sessions with optional filters for kind, label, agentId, search, recent activity, derived titles, and last-message previews. Use this to discover a target session before calling sessions_history or sessions_send.", "parameters": { "type": "object", "properties": { "kinds": { "type": "array", "items": { "type": "string" } }, "limit": { "type": "number", "minimum": 1 }, "activeMinutes": { "type": "number", "minimum": 1 }, "messageLimit": { "type": "number", "minimum": 0 }, "label": { "type": "string", "minLength": 1 }, "agentId": { "type": "string", "minLength": 1, "maxLength": 64 }, "search": { "type": "string", "minLength": 1 }, "includeDerivedTitles": { "type": "boolean" }, "includeLastMessage": { "type": "boolean" } } } } }, { "type": "function", "function": { "name": "sessions_send", "description": "Send a message into another visible session by sessionKey or label. Use this to delegate follow-up work to an existing session; waits for the target run and returns the updated assistant reply when available.", "parameters": { "type": "object", "required": [ "message" ], "properties": { "sessionKey": { "type": "string" }, "label": { "type": "string", "minLength": 1, "maxLength": 512 }, "agentId": { "type": "string", "minLength": 1, "maxLength": 64 }, "message": { "type": "string" }, "timeoutSeconds": { "type": "number", "minimum": 0 } } } } }, { "type": "function", "function": { "name": "sessions_spawn", "description": "Spawn a clean isolated session by default with the native subagent runtime. `mode=\"run\"` is one-shot and `mode=\"session\"` is persistent or thread-bound. Subagents inherit the parent workspace directory automatically. For native subagents only, set `context=\"fork\"` when the child needs the current transcript context; otherwise omit it or use `context=\"isolated\"`. Use this when the work should happen in a fresh child session instead of the current one.", "parameters": { "type": "object", "required": [ "task" ], "properties": { "task": { "type": "string" }, "label": { "type": "string" }, "runtime": { "type": "string", "enum": [ "subagent" ] }, "agentId": { "type": "string" }, "model": { "type": "string" }, "thinking": { "type": "string" }, "cwd": { "type": "string" }, "runTimeoutSeconds": { "type": "number", "minimum": 0 }, "timeoutSeconds": { "type": "number", "minimum": 0 }, "thread": { "type": "boolean" }, "mode": { "type": "string", "enum": [ "run", "session" ] }, "cleanup": { "type": "string", "enum": [ "delete", "keep" ] }, "sandbox": { "type": "string", "enum": [ "inherit", "require" ] }, "context": { "type": "string", "enum": [ "isolated", "fork" ], "description": "Native subagent context mode. Omit or use \"isolated\" for a clean child session; use \"fork\" only when the child needs the requester transcript context." }, "lightContext": { "type": "boolean", "description": "When true, spawned subagent runs use lightweight bootstrap context. Only applies to runtime='subagent'." }, "attachments": { "type": "array", "items": { "type": "object", "required": [ "name", "content" ], "properties": { "name": { "type": "string" }, "content": { "type": "string" }, "encoding": { "type": "string", "enum": [ "utf8", "base64" ] }, "mimeType": { "type": "string" } } }, "maxItems": 50 }, "attachAs": { "type": "object", "properties": { "mountPath": { "type": "string" } } } } } } }, { "type": "function", "function": { "name": "sessions_yield", "description": "End your current turn. Use after spawning subagents to receive their results as the next message.", "parameters": { "type": "object", "properties": { "message": { "type": "string" } } } } }, { "type": "function", "function": { "name": "subagents", "description": "List, kill, or steer spawned sub-agents for this requester session. Use this for sub-agent orchestration.", "parameters": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "list", "kill", "steer" ] }, "target": { "type": "string" }, "message": { "type": "string" }, "recentMinutes": { "type": "number", "minimum": 1 } } } } }, { "type": "function", "function": { "name": "web_fetch", "description": "Fetch and extract readable content from a URL (HTML \u2192 markdown/text). Use for lightweight page access without browser automation.", "parameters": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string", "description": "HTTP or HTTPS URL to fetch." }, "extractMode": { "type": "string", "enum": [ "markdown", "text" ], "description": "Extraction mode (\"markdown\" or \"text\").", "default": "markdown" }, "maxChars": { "type": "number", "description": "Maximum characters to return (truncates when exceeded).", "minimum": 100 } } } } }, { "type": "function", "function": { "name": "web_search", "description": "Search the web using DuckDuckGo. Returns titles, URLs, and snippets with no API key required.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query string." }, "count": { "type": "number", "description": "Number of results to return (1-10).", "minimum": 1, "maximum": 10 }, "region": { "type": "string", "description": "Optional DuckDuckGo region code such as us-en, uk-en, or de-de." }, "safeSearch": { "type": "string", "description": "SafeSearch level: strict, moderate, or off." } }, "additionalProperties": false } } }, { "type": "function", "function": { "name": "write", "description": "Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.", "parameters": { "type": "object", "required": [ "path", "content" ], "properties": { "path": { "type": "string", "description": "Path to the file to write (relative or absolute)" }, "content": { "type": "string", "description": "Content to write to the file" } } } } } ] }``` </details>