Files
cursor-byok/prompt/cursor/tools.json
T

897 lines
71 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"tools": [
{
"type": "function",
"function": {
"name": "AskQuestion",
"description": "Collect structured multiple-choice answers from the user. Use this tool only when you are blocked on a decision that is genuinely the user's to make: one you cannot resolve from the request, the code, or sensible defaults.\n\nUsage notes:\n- Each question should have at least 2 options for the user to choose from\n- Users will always be able to select \"Other\" to provide custom text input\n- Use allow_multiple: true to allow multiple answers to be selected for a question\n- If you recommend a specific option, make that the first option in the list and add \"(Recommended)\" at the end of the label\n\nPrefer this tool over listing options in your final response text (as letters, numbers, bullet points, etc).",
"parameters": {
"type": "object",
"properties": {
"questions": {
"description": "Array of questions to present to the user (minimum 1 required)",
"items": {
"properties": {
"allow_multiple": {
"description": "If true, user can select multiple options. Defaults to false.",
"type": "boolean"
},
"id": {
"description": "Unique identifier for this question",
"type": "string"
},
"options": {
"description": "Array of answer options (minimum 2 required)",
"items": {
"properties": {
"id": {
"description": "Unique identifier for this option",
"type": "string"
},
"label": {
"description": "Display text for this option",
"type": "string"
}
},
"required": [
"id",
"label"
],
"type": "object"
},
"minItems": 2,
"type": "array"
},
"prompt": {
"description": "The question text to display to the user, without the options.",
"type": "string"
}
},
"required": [
"id",
"prompt",
"options"
],
"type": "object"
},
"minItems": 1,
"type": "array"
},
"title": {
"description": "Optional title for the questions form",
"type": "string"
}
},
"required": [
"questions"
]
}
}
},
{
"type": "function",
"function": {
"name": "AwaitShell",
"description": "Check or poll a backgrounded shell job. For work that does not have a shell id, you can omit the shell_id arg to sleep for the full `block_until_ms` duration (prefer this over sleeping in the shell, because it renders nicely to the user). At the end of your turn, you will be notified about any unawaited jobs that completed. If you think a job completed (e.g. because you killed it), observe it with AwaitShell to skip the notification, because stale notifications can confuse the user.\n\nPrefer NOT to poll reflexively with AwaitShell. Multitask on independent work while backgrounded jobs run, or finish your turn and rely on the end-of-turn completion notification. Poll with AwaitShell only when one of the following is true:\n- Your very next step is blocked on this specific job's result and you have no other productive work to do, OR\n- The task requires close monitoring (see shell guidance below).\n- Never poll a task whose tool result says it was \"manually backgrounded by the user\".\n- NEVER USE THIS TO POLL OR WAIT VACUOUSLY FOR A SUBAGENT LAUNCHED WITH THE Task TOOL — rely on the end-of-turn completion notification instead (it is delivered as soon as the subagent finishes; guessing a wait time is inefficient).\n- Shell: only poll with AwaitShell when the command requires close monitoring. Close monitoring means a long-running job that can silently hang, degrade, or need a course correction before it completes — e.g. training runs, eval runs, deployments, long builds, datagen pipelines, DB migrations, large data transfers. For fire-and-forget commands (tests, installs, dev servers/watchers, short scripts, etc.) the completion notification is enough — start them, keep working, and only poll with AwaitShell later if you end up blocked on the result.\n- Shell sanity check (regardless of close monitoring): when you spawn a command directly into the background (`block_until_ms: 0`), do a single status check by reading the output file to confirm the command didn't fail to start. This is a one-shot smoke check, not a polling loop.\n- Shell close-monitoring guidance (only applies in the close-monitoring case above):\n - HARD STOPPING CONSTRAINT: once you've decided to actively poll, don't stop until (a) the job terminates, (b) the command reaches a healthy steady state (only for non-terminating commands, e.g. dev server/watcher), or (c) the command is hung — follow the hang guidance below.\n - Waiting until a regex matches the output can be useful for e.g. known startup/status/error logs.\n - Size `block_until_ms` to the command's expected runtime. When waiting further, avoid waiting 1h or more: prefer slices of 60s-59m (keeps prompt cache warm). Size slices based on expected progress; when progress is unclear, exponential backoff is useful.\n - Output file header has `pid` and `running_for_ms` (updated every 5000ms).\n - When finished, footer with `exit_code` and `elapsed_ms` appears (regex only matches the body, not header/footer).\n - If the command is taking longer than expected and appears hung (use judgment based on command type), kill the process if safe to do so using the pid in the header. If possible, fix the hang and proceed.",
"parameters": {
"type": "object",
"properties": {
"block_until_ms": {
"description": "Max sleep time to block before returning (in milliseconds). Defaults to 30000ms. Set to 0 for non-blocking status check. Must not exceed 7140000 (119 minutes).",
"maximum": 7140000,
"type": "number"
},
"pattern": {
"description": "Block until the regex matches stdout/stderr stream (or task completes). Matches anywhere in the shell output, not just new output. Will not match terminal file headers or footers, e.g. exit_code. Accepts JavaScript regex patterns (compiled with the multiline `m` flag).",
"type": "string"
},
"shell_id": {
"description": "Optional shell id to poll. If omitted, this tool sleeps for the full block_until_ms duration and then returns. Required when block_until_ms is 0.",
"type": "string"
},
"waiting_for_subagent": {
"description": "Set this to true if you are waiting for subagent(s) to complete. Remember you should NOT be doing this and instead end your turn or do parallel work.",
"type": "boolean"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "CallMcpTool",
"description": "Call an MCP tool by server identifier and tool name with arbitrary JSON arguments. IMPORTANT: Always call GetMcpTools for this server/tool before calling to ensure correct parameters.\n\nExample:\n{\n \"server\": \"my-mcp-server\",\n \"toolName\": \"search\",\n \"description\": \"Search the public docs for the example API\",\n \"arguments\": { \"query\": \"example\", \"limit\": 10 }\n}",
"parameters": {
"type": "object",
"properties": {
"arguments": {
"description": "Arguments to pass to the MCP tool, as described in the tool descriptor.",
"type": "object"
},
"description": {
"description": "Short plain-language description of what this call will do. One sentence naming the outcome and where it applies (channel, page, file, or service) when known. Do not include tool names, argument keys, or JSON.",
"type": "string"
},
"requestSmartModeApproval": {
"description": "Set to true when immediately retrying the exact same MCP call after Auto-review blocks it and you decide the user should approve it through the native approval card.",
"type": "boolean"
},
"server": {
"description": "Identifier of the MCP server hosting the tool.",
"type": "string"
},
"smartModeBlockReason": {
"description": "Provide the exact block reason returned by Auto-review in the prior rejection. Required when requestSmartModeApproval is true so the approval card shows the original classifier reason without re-running the classifier.",
"type": "string"
},
"toolName": {
"description": "Name of the MCP tool to invoke.",
"type": "string"
}
},
"required": [
"server",
"toolName"
]
}
}
},
{
"function": {
"description": "Use this tool to create or revise a concise plan for accomplishing the user's request. This tool should be called at the end of the planning phase to finalize and store the plan.\n\nThe plan you create should be properly formatted in markdown, using appropriate sections and headers. The plan should be very concise and actionable, providing the minimum amount of detail for the user to understand and action the plan. It may be helpful to identify the most important couple files you will change, and existing code you will leverage. Cite specific file paths and essential snippets of code. IMPORTANT: Do NOT use markdown tables in plan content (they cannot be rendered for the user); use bullet lists instead. The first line MUST BE A TITLE for the plan formatted as a level 1 markdown heading.\n\nTASK ORGANIZATION:\n\nUse 'todos' for organizing implementation tasks:\n- Each todo should be a clear, specific, and actionable task\n- Each todo needs a unique ID (e.g., \"setup-auth\") and descriptive content\n- If the plan is simple, provide just a few high-level todos or none at all\n\nUPDATING THE PLAN:\n- The plan file URI will be returned in the tool result\n- If a current plan already exists, call this tool with the complete revised plan and omit the name field\n- Only the first CreatePlan call may include name; later calls must not include name and must not use name to rename or create a separate plan\n- If the user asks for a separate new plan while a current plan exists, explain the limitation or ask how to proceed before calling CreatePlan again\n\nAdditional guidelines:\n- Avoid asking clarifying questions in the plan itself. Ask them before calling this tool. Present these to the user using the AskQuestion tool.\n- Todos help break down complex plans into manageable, trackable tasks\n- Focus on high-level meaningful decisions rather than low-level implementation details\n- A good plan is glanceable, not a wall of text.",
"name": "CreatePlan",
"parameters": {
"properties": {
"name": {
"description": "A short 3-4 word name for the plan. IMPORTANT: Provide this only on the first CreatePlan call when no current plan exists. If a current plan already exists, omit this field entirely; do not use it to rename or create a separate plan.",
"type": "string"
},
"overview": {
"description": "A 1-2 sentence high-level description of the plan that summarizes what will be accomplished",
"type": "string"
},
"plan": {
"description": "A detailed, concrete plan for accomplishing the user's request",
"type": "string"
},
"todos": {
"description": "Array of implementation todos",
"items": {
"properties": {
"content": {
"description": "Description of the todo task",
"type": "string"
},
"id": {
"description": "Unique identifier for the todo",
"type": "string"
}
},
"required": [
"id",
"content"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"type": "function"
},
{
"type": "function",
"function": {
"name": "Delete",
"description": "Deletes a file at the specified path. The operation will fail gracefully if:\n - The file doesn't exist\n - The operation is rejected for security reasons\n - The file cannot be deleted",
"parameters": {
"type": "object",
"properties": {
"path": {
"description": "The absolute path of the file to delete",
"type": "string"
}
},
"required": [
"path"
]
}
}
},
{
"type": "function",
"function": {
"name": "EditNotebook",
"description": "Use this tool to edit a jupyter notebook cell.\nCell indices are 0-based. 'old_string' and 'new_string' should be a valid cell content, i.e. WITHOUT any JSON syntax that notebook files use under the hood. If you need to create a new notebook, just set 'is_new_cell' to true and cell_idx to 0.",
"parameters": {
"type": "object",
"properties": {
"cell_idx": {
"description": "The index of the cell to edit (0-based)",
"type": "number"
},
"cell_language": {
"description": "The language of the cell to edit. Should be STRICTLY one of these: 'python', 'markdown', 'javascript', 'typescript', 'r', 'sql', 'shell', 'raw' or 'other'.",
"type": "string"
},
"is_new_cell": {
"description": "If true, a new cell will be created at the specified cell index. If false, the cell at the specified cell index will be edited.",
"type": "boolean"
},
"new_string": {
"description": "The edited text to replace the old_string or the content for the new cell.",
"type": "string"
},
"old_string": {
"description": "The text to replace (must be unique within the cell, and must match the cell contents exactly, including all whitespace and indentation).",
"type": "string"
},
"target_notebook": {
"description": "The path to the notebook file you want to edit. You can use either a relative path in the workspace or an absolute path. If an absolute path is provided, it will be preserved as is.",
"type": "string"
}
},
"required": [
"target_notebook",
"cell_idx",
"is_new_cell",
"cell_language",
"old_string",
"new_string"
]
}
}
},
{
"type": "function",
"function": {
"name": "FetchMcpResource",
"description": "Reads a specific resource from an MCP server, identified by server name and resource URI. Optionally, set downloadPath (relative to the workspace) to save the resource to disk; when set, the resource will be downloaded and not returned to the model.",
"parameters": {
"type": "object",
"properties": {
"downloadPath": {
"description": "Optional relative path in the workspace to save the resource to. When set, the resource is written to disk and is not returned to the model.",
"type": "string"
},
"requestSmartModeApproval": {
"description": "Set to true when immediately retrying the exact same resource fetch after Auto-review blocks it and you decide the user should approve it through the native approval card.",
"type": "boolean"
},
"server": {
"description": "The MCP server identifier",
"type": "string"
},
"smartModeBlockReason": {
"description": "Provide the exact block reason returned by Auto-review in the prior rejection. Required when requestSmartModeApproval is true so the approval card shows the original classifier reason without re-running the classifier.",
"type": "string"
},
"uri": {
"description": "The resource URI to read",
"type": "string"
}
},
"required": [
"server",
"uri"
]
}
}
},
{
"type": "function",
"function": {
"name": "GenerateImage",
"description": "Generate an image file from a text description.\n\nSTRICT INVOCATION RULES (must follow):\n- Only use this tool when the user explicitly asks for an image. Do not generate images \"just to be helpful\".\n- Do not use this tool for data heavy visualizations such as charts, plots, tables.\n\nGeneral guidelines:\n- Provide a concrete description first: subject(s), layout, style, colors, text (if any), and constraints.\n- If the user requests an aspect ratio, set `aspect_ratio` to one of \"1:1\", \"4:3\", \"3:4\", \"16:9\", or \"9:16\".\n- If the user provides reference images, include them in `reference_image_paths`.\n- Do not repeat generated images as Markdown in your response; the client displays tool-generated images automatically.\n\nExamples that should call this tool:\n- user: \"Generate an app icon for a note-taking app, minimal flat vector style.\" (explicitly requests an image asset)\n- user: \"Make a UI mockup of a settings screen with a dark mode toggle.\" (explicitly requests a UI mockup)\n- user: \"Generate an asset of a game character with a sword.\" (explicitly requests a visual asset)\n\nExamples that should not call this tool:\n- user: \"Create a plan to refactor this module.\" (planning request; respond in text or mermaid diagram)\n- user: \"Generate a chart of sales and revenue using data.csv.\" (data visualization; generate via code)\n",
"parameters": {
"type": "object",
"properties": {
"aspect_ratio": {
"description": "Optional aspect ratio for the generated image. Supported values are \"1:1\", \"4:3\", \"3:4\", \"16:9\", and \"9:16\".",
"enum": [
"1:1",
"4:3",
"3:4",
"16:9",
"9:16"
],
"type": "string"
},
"description": {
"description": "A detailed description of the image.",
"type": "string"
},
"filename": {
"description": "Optional filename for the generated image (e.g., 'diagram.png'). Do not include a directory path - the tool automatically handles where to save and how to display the image. If not provided, a timestamped filename will be generated.",
"type": "string"
},
"reference_image_paths": {
"description": "Optional array of file paths to reference images as additional inputs.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"description"
]
}
}
},
{
"type": "function",
"function": {
"name": "GetMcpTools",
"description": "Discover and inspect MCP tools. There are 5 ways to call this tool. Prefer fetching by server or pattern over listing the full catalog.\n\n1. {\"server\":\"<id>\"}: returns full input schemas and full descriptions for every tool on that server. Preferred when you know the server.\n2. {\"server\":\"<id>\",\"toolName\":\"<name>\"}: returns the full schema and full description for one tool.\n3. {\"pattern\":\"<regex>\"}: searches tool and server names across all servers using RE2 syntax.\n4. {\"server\":\"<id>\",\"pattern\":\"<regex>\"}: searches tool names on that server using RE2 syntax.\n5. No arguments: returns a catalog of all servers with tool names and short descriptions. Use only as a last resort.\n\nPattern-search and catalog results shorten long descriptions to 200 characters, ending with \"... [truncated]\". Server and single-tool lookups always return the complete description, so fetch the tool directly when you need the full text.\nThe response includes each server's serverStatus; do not treat servers in \"needsAuth\", \"error\", or \"loading\" states as usable.\nAlways call this tool to discover a tool's schema before calling it with CallMcpTool.\n\nMCP authentication: If a relevant server has serverStatus \"needsAuth\", or if an MCP tool call fails with an authentication/authorization error, authenticate it by calling mcp_auth (via CallMcpTool, with empty arguments), then inspect that server again and retry the original request if appropriate. Do not call mcp_auth just because it is listed, and do not repeatedly call it if authentication did not fix the failure.",
"parameters": {
"type": "object",
"properties": {
"pattern": {
"description": "RE2 regex pattern to search server and tool names (max 256 chars). Optionally combine with server to scope the search.",
"type": "string"
},
"server": {
"description": "MCP server identifier to inspect.",
"type": "string"
},
"toolName": {
"description": "Tool name within the server. Requires server to be set.",
"type": "string"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "Glob",
"description": "\nTool to search for files matching a glob pattern\n\n- Works fast with codebases of any size\n- Returns matching file paths sorted by modification time\n- Use this tool when you need to find files by name patterns\n- You have the capability to call multiple tools in a single response. It is always better to speculatively perform multiple searches that are potentially useful as a batch.\n",
"parameters": {
"type": "object",
"properties": {
"glob_pattern": {
"description": "The glob pattern to match files against.\nPatterns not starting with \"**/\" are automatically prepended with \"**/\" to enable recursive searching.\n\nExamples:\n\t- \"*.js\" (becomes \"**/*.js\") - find all .js files\n\t- \"**/node_modules/**\" - find all node_modules directories\n\t- \"**/test/**/test_*.ts\" - find all test_*.ts files in any test directory",
"type": "string"
},
"target_directory": {
"description": "Absolute path to directory to search for files in. If not provided, defaults to Cursor workspace root.",
"type": "string"
}
},
"required": [
"glob_pattern"
]
}
}
},
{
"type": "function",
"function": {
"name": "Grep",
"description": "A search tool built on ripgrep. Results are capped to several thousand output lines for responsiveness; when truncation occurs, the results report \"at least\" counts, but are otherwise accurate.",
"parameters": {
"type": "object",
"properties": {
"-A": {
"description": "Number of lines to show after each match (rg -A). Requires output_mode: \"content\", ignored otherwise.",
"type": "number"
},
"-B": {
"description": "Number of lines to show before each match (rg -B). Requires output_mode: \"content\", ignored otherwise.",
"type": "number"
},
"-C": {
"description": "Number of lines to show before and after each match (rg -C). Requires output_mode: \"content\", ignored otherwise.",
"type": "number"
},
"-i": {
"description": "Case insensitive search (rg -i) Defaults to false",
"type": "boolean"
},
"glob": {
"description": "Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\") - maps to rg --glob",
"type": "string"
},
"head_limit": {
"description": "Limit output size. For \"content\" mode: limits total matches shown. For \"files_with_matches\" and \"count\" modes: limits number of files.",
"minimum": 0,
"type": "number"
},
"multiline": {
"description": "Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.",
"type": "boolean"
},
"offset": {
"description": "Skip first N entries. For \"content\" mode: skips first N matches. For \"files_with_matches\" and \"count\" modes: skips first N files. Use with head_limit for pagination.",
"minimum": 0,
"type": "number"
},
"output_mode": {
"description": "Output mode: \"content\" shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), \"files_with_matches\" shows file paths (supports head_limit), \"count\" shows match counts (supports head_limit). Defaults to \"content\".",
"enum": [
"content",
"files_with_matches",
"count"
],
"type": "string"
},
"path": {
"description": "File or directory to search in (rg pattern -- PATH). Defaults to Cursor workspace root.",
"type": "string"
},
"pattern": {
"description": "The regular expression pattern to search for in file contents",
"type": "string"
},
"type": {
"description": "File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types.",
"type": "string"
}
},
"required": [
"pattern"
]
}
}
},
{
"type": "function",
"function": {
"name": "Read",
"description": "Reads a file from the local filesystem. This tool can also read image files when called with the appropriate path. Formats supported: jpeg/jpg, png, gif, webp.",
"parameters": {
"type": "object",
"properties": {
"limit": {
"description": "The number of lines to read. Only provide if the file is too large to read at once.",
"type": "integer"
},
"offset": {
"description": "The line number to start reading from. Positive values are 1-indexed from the start of the file. Negative values count backwards from the end (e.g. -1 is the last line). Only provide if the file is too large to read at once.",
"type": "integer"
},
"path": {
"description": "The absolute path of the file to read.",
"type": "string"
}
},
"required": [
"path"
]
}
}
},
{
"type": "function",
"function": {
"name": "ReadLints",
"description": "Read and display linter errors from the current workspace. You can provide paths to specific files or directories, or omit the argument to get diagnostics for all files.",
"parameters": {
"type": "object",
"properties": {
"paths": {
"description": "Optional. An array of paths to files or directories to read linter errors for. You can use either relative paths in the workspace or absolute paths. If provided, returns diagnostics for the specified files/directories only. If not provided, returns diagnostics for all files in the workspace.",
"items": {
"type": "string"
},
"type": "array"
}
}
}
}
},
{
"type": "function",
"function": {
"name": "Shell",
"description": "Executes a given command in a shell session, waiting for output for `block_until_ms` millis.\nYou can monitor commands by configuring `notify_on_output`. You will be notified at the end of your turn whenever stdout/stderr output matches the regex `pattern`. Output redirected only to a file will not trigger it. Configure a 5-or-fewer-word `reason` explaining what you are watching for, and optionally configure `debounce_ms`.",
"parameters": {
"type": "object",
"properties": {
"block_until_ms": {
"description": "How long to block and wait for the command to complete before moving it to background (in milliseconds). Defaults to 30000ms (30 seconds). Set to 0 to immediately run the command in the background. For a long-lived process, keep the command itself in the foreground and use `block_until_ms: 0`; do not combine it with `nohup`, `&`, `disown`, or another self-backgrounding wrapper, because Cursor must manage the real process. Make sure to set `block_until_ms` to higher than the command's expected runtime. Add some buffer since block_until_ms includes shell startup time; increase buffer next time based on previous elapsed times if you chose too low. E.g. if you sleep for 40s, recommended `block_until_ms` is 45s. Do not specify a 'timeout' parameter; no such param exists.",
"type": "number"
},
"command": {
"description": "The command to execute",
"type": "string"
},
"description": {
"description": "Clear, concise description of what this command does in 5-10 words. Examples:\nInput: ls\nOutput: Lists files in current directory\n\nInput: git status\nOutput: Shows working tree status\n\nInput: npm install\nOutput: Installs package dependencies\n\nInput: mkdir foo\nOutput: Creates directory 'foo'",
"type": "string"
},
"notify_on_output": {
"description": "Optional output notification config. Each terminal output which matches the pattern will notify you. ONLY set this when the user explicitly requests monitoring.",
"properties": {
"debounce_ms": {
"description": "Milliseconds that must elapse between notifications. The harness enforces a minimum of 5000ms.",
"type": "number"
},
"pattern": {
"description": "Regex pattern matched against stdout/stderr output. Output redirected only to a file will not trigger it. Do not match all outputs.",
"type": "string"
},
"reason": {
"description": "5 or less words describing why you are watching for this output. The UI (only visible to user) will prefix it as 'Monitored `reason`'.",
"type": "string"
}
},
"required": [
"pattern",
"reason"
],
"type": "object"
},
"request_smart_mode_approval": {
"description": "Set to true when immediately retrying the exact same command after Auto-review blocks it and you decide the user should approve it through the native approval card.",
"type": "boolean"
},
"smart_mode_block_reason": {
"description": "Provide the exact block reason returned by Auto-review in the prior rejection. Required when request_smart_mode_approval is true so the approval card shows the original classifier reason without re-running the classifier.",
"type": "string"
},
"working_directory": {
"description": "The absolute path to the working directory to execute the command in (defaults to current directory)",
"type": "string"
}
},
"required": [
"command"
]
}
}
},
{
"type": "function",
"function": {
"name": "StrReplace",
"description": "Performs exact string replacements in files.",
"parameters": {
"type": "object",
"properties": {
"new_string": {
"description": "The text to replace it with (must be different from old_string)",
"type": "string"
},
"old_string": {
"description": "The text to replace",
"type": "string"
},
"path": {
"description": "The absolute path to the file to modify",
"type": "string"
},
"replace_all": {
"description": "Replace all occurrences of old_string (default false)",
"type": "boolean"
}
},
"required": [
"path",
"old_string",
"new_string"
]
}
}
},
{
"type": "function",
"function": {
"name": "SwitchMode",
"description": "Switch the interaction mode to better match the current task. Each mode is optimized for a specific type of work.\n\n## When to Switch Modes\n\nSwitch modes proactively when:\n1. **Task type changes** - User shifts from asking questions to requesting implementation, or vice versa\n2. **Complexity emerges** - What seemed simple reveals architectural decisions or multiple approaches\n3. **Debugging needed** - An error, bug, or unexpected behavior requires investigation\n4. **Planning needed** - The task is large, ambiguous, or has significant trade-offs to discuss\n5. **You're stuck** - Multiple attempts without progress suggest a different approach is needed\n\n## When NOT to Switch\n\nDo NOT switch modes for:\n- Simple, clear tasks that can be completed quickly in current mode\n- Mid-implementation when you're making good progress\n- Minor clarifying questions (just ask them)\n- Tasks where the current mode is working well\n\n## Available Modes\n\n### Agent Mode [switchable]\nDefault implementation mode with full access to all tools for making changes.\n\n**Switch to Agent when:**\n- You have a clear understanding of what to implement\n- Planning/debugging is complete and you're ready to code\n- The task is straightforward with an obvious implementation\n- You've gathered enough context and are ready to execute\n\n**Examples:**\n- After planning: \"I've designed the approach, ready to implement\" → Switch to Agent\n- After debugging: \"Found the bug, it's a null check issue\" → Switch to Agent\n- Simple task: User asks to \"Add a comment to this function\" → Stay in Agent (no switch needed)\n\n### Plan Mode [switchable]\nRead-only collaborative mode for designing implementation approaches before coding.\n\n**Switch to Plan when:**\n- The task has multiple valid approaches with significant trade-offs\n- Architectural decisions are needed (e.g., \"Add caching\" - Redis vs in-memory vs file-based)\n- The task touches many files or systems (large refactors, migrations)\n- Requirements are unclear and you need to explore before understanding scope\n- You would otherwise ask multiple clarifying questions\n\n**Examples:**\n- User: \"Add user authentication\" → Switch to Plan (session vs JWT, storage, middleware decisions)\n- User: \"Refactor the database layer\" → Switch to Plan (large scope, architectural impact)\n- User: \"Make the app faster\" → Switch to Plan (need to profile, multiple optimization strategies)\n\n### Debug Mode (cannot switch to this mode)\nSystematic troubleshooting mode for investigating bugs, failures, and unexpected behavior with runtime evidence.\n\n### Ask Mode (cannot switch to this mode)\nRead-only mode for exploring code and answering questions without making changes.\n\n## Important Notes\n\n- **Be proactive**: Don't wait for the user to ask you to switch modes\n- **Explain briefly**: When switching, briefly explain why in your `explanation` parameter\n- **Don't over-switch**: If the current mode is working, stay in it\n- **User approval required**: Mode switches require user consent",
"parameters": {
"type": "object",
"properties": {
"explanation": {
"description": "Optional explanation for why the mode switch is requested. This helps the user understand why you're switching modes.",
"type": "string"
},
"target_mode_id": {
"description": "The mode to switch to. Allowed values: 'plan', 'agent'.",
"type": "string"
}
},
"required": [
"target_mode_id"
]
}
}
},
{
"type": "function",
"function": {
"name": "Task",
"description": "Launch a new agent to handle complex, multi-step tasks autonomously.\n\nThe Task tool launches specialized subagents (subprocesses) that autonomously handle complex tasks. Each subagent_type has specific capabilities and tools available to it.\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\nVERY IMPORTANT: When broadly exploring the codebase to gather context for a large task, it is recommended that you use the Task tool with subagent_type=\"explore\" instead of running search commands directly.\n\nIf the query is a narrow or specific question, you should NOT use the Task and instead address the query directly using the other tools available to you.\n\nExamples:\n- user: \"Where is the ClientError class defined?\" assistant: [Uses Grep directly - this is a needle query for a specific class]\n- user: \"Run this query using my database API\" assistant: [Calls the MCP directly - this is not a broad exploration task]\n- user: \"What is the codebase structure?\" assistant: [Uses the Task tool with subagent_type=\"explore\"]\n\nIf it is possible to explore different areas of the codebase in parallel, you should launch multiple agents concurrently.\n\nWhen NOT to use the Task tool:\n- Simple, single or few-step tasks that can be performed by a single agent (using parallel or sequential tool calls) -- just call the tools directly instead.\n- For example:\n - If you want to read a specific file path, use the Read or Glob tool instead of the Task tool, to find the match more quickly\n - If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Task tool, to find the match more quickly\n - If you are searching for a specific class definition like \"class Foo\", use the Glob tool instead, to find the match more quickly\n\nUsage notes:\n- Always include a short description (3-5 words) summarizing what the agent will do\n- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple Task tool use content blocks.\n- When the agent is done, it will return a single message back to you. Specify exactly what information the agent should return back in its final response to you.\n- Agents can be resumed using the `resume` parameter by passing the agent ID from a previous invocation. This sends a follow-up message after the agent has completed, preserving existing context. If the agent is still running, the request fails unless `interrupt` is true. Set `interrupt` to true only when the user explicitly wants to interrupt the running agent. You can also set `resume` to \"self\" to fork the current parent agent into a new child subagent. When NOT resuming, each invocation starts fresh and you should provide a detailed task description with all necessary context for the agent to perform its task autonomously.\n- If you mention an agent or subagent in your response, link it with the `[Name](id)` Don't use generic label such as `[agent]`, `[worker]`, or `[subagent]`. For cloud subagents, when the agent has edited code, link to `[Review](bc-id#changes)`, or, if you know the exact added and deleted line counts, `[Review +A D](bc-id#changes)`, replacing A and D with those counts. Never write A or D literally. Use `[Try Live](bc-id#desktop)` only when the agent used computer use.\n- When using the Task tool, the subagent invocation does not have access to the user's message or prior assistant steps. Therefore, you should provide a highly detailed task description with all necessary context for the agent to perform its task autonomously.\n- The subagent's outputs should generally be trusted\n- Clearly tell the subagent which tasks you want it to perform, since it is not aware of the user's intent or your prior assistant steps.\n- If the subagent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n- If the user specifies that they want you to run subagents \"in parallel\", you MUST send a single message with multiple Task tool use content blocks. For example, if you need to launch both a code-reviewer subagent and a test-runner subagent in parallel, send a single message with both tool calls.\n- Avoid delegating the full query to the Task tool and returning the result. In these cases, you should address the query using the other tools available to you.\n\nAvailable subagent_types and a quick description of what they do:\n- generalPurpose: General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. Use when searching for a keyword or file and not confident you'll find the match quickly.\n- explore: Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. \"src/components/**/*.tsx\"), search code for keywords (eg. \"API endpoints\"), or answer questions about the codebase (eg. \"how do API endpoints work?\"). When calling this agent, specify the desired thoroughness level: \"quick\" for basic searches, \"medium\" for moderate exploration, or \"very thorough\" for comprehensive analysis across multiple locations and naming conventions.\n- shell: Command execution specialist for running bash commands. Use this for git operations, command execution, and other terminal tasks.\n- cursor-guide: Read Cursor product documentation to answer questions about how Cursor Desktop, IDE, CLI, Cloud Agents, Bugbot, and other features work. Use when the user asks 'In Cursor, how do I...?' or similar questions about Cursor products.\n- ci-investigator: Investigate a single failing PR CI check and return a short root-cause summary. Use when the user asks to summarize, explain, diagnose, or investigate a specific failed check from a pull request.\n- bugbot: Use only when the user *explicitly* asks for a Bugbot-like review of local code changes. When launching this subagent, set the Task description to exactly \"Bugbot\". Launch exactly one Bugbot subagent with `run_in_background: false` unless the user explicitly asks to run in background. Use this fixed prompt form: \"Full Repository Path: ...\\nDiff: <one of: \"branch changes\", \"uncommitted changes\", \"natural language\">\\nChange Description: ...\\nCustom Instructions: ...\"; default to `Diff: branch changes`; include `Change Description` only when `Diff` is `natural language`, formatting it as one block per changed file (a `<path> (added|modified|deleted|renamed)` header followed by bullets of what changed, mentioning line numbers or ranges inline where helpful), and only use `natural language` as a last resort after a regular diff-based review failed because the diff could not be computed; include `Custom Instructions` only when the user gave specific review instructions. This subagent is single-shot and does not support `resume`; always launch a fresh subagent instead.\n- security-review: Use only when the user *explicitly* asks for a security review of local code changes. When launching this subagent, set the Task description to exactly \"Security Review\". Launch exactly one security-review subagent with `run_in_background: false` unless the user explicitly asks to run in background. Use this fixed prompt form: \"Full Repository Path: ...\\nDiff: <one of: \"branch changes\", \"uncommitted changes\">\\nCustom Instructions: ...\"; default to `Diff: branch changes`; include `Custom Instructions` only when the user gave specific review instructions. This subagent is single-shot and does not support `resume`; always launch a fresh subagent instead.\n- best-of-n-runner: Run a task in an isolated git worktree. Each best-of-n-runner gets its own branch and working directory. Use for best-of-N parallel attempts or isolated experiments.\n- test-subagent: Describe when Agent should delegate to this subagent.\n\nIf the user explicitly asks for the model of a subagent/task, you may ONLY use model slugs from this list:\n- inherit (default; required unless the user explicitly requested another model)\n- claude-opus-5-thinking-high\n- composer-2.5-fast\n- cursor-grok-4.5-low\n- cursor-grok-4.6-high-fast\n- gpt-5.6-sol-medium\n\nIf the user isn't asking for a specific version, prefer the latest version of the model family. As an example, if the user just says \"gpt\" or \"claude\", use the latest available version of GPT or Claude.\n\nIMPORTANT: If the user requests a model that is NOT in the list above, do NOT substitute a different model or guess. Instead, skip launching the subagent with that model and tell the user which model was unavailable and which models are available.\n\nWhen speaking to the USER about which model you selected for a subagent, do NOT use the kebab-case model names unless the user requested the model using that format. Ue the same naming scheme the user used to discuss the model when they requested it.\n\nWhen an agent runs in the background, you will be automatically notified when it completes after you end your own turn - do NOT AwaitShell, poll, or proactively check on its progress. Continue with other work or end your turn instead.",
"parameters": {
"type": "object",
"properties": {
"cloud_base_branch": {
"description": "Base branch for the cloud subagent's branch to start from. Default is current branch. Uses remote version of branch; uncommitted or un-pushed branches will fail. Only specify this parameter if environment equals cloud.",
"type": "string"
},
"description": {
"description": "A short, user-friendly title for the subagent. This appears in the UI as the subagent's name. Make it concrete and distinct, consider recent titles to avoid reuse. For resumed subagents which you are prompting to work on a separate task, give an updated description based on the latest work the subagent is performing. (Do not rename if the subagent is continuing work on the same high-level task.)",
"type": "string"
},
"environment": {
"description": "Optional execution environment for the subagent. Use \"local\" (default) for normal local subagents, or \"cloud\" to run the subagent as a cloud agent (i.e. in its own separate worktree). ONLY set to cloud if the user explicitly requests a cloud subagent. DO NOT set to cloud if user does not request cloud. Cloud subagents will work on their own git branch on their own VM. After subagent completion, follow user instructions on whether to merge that branch into your own branch, check it out, or neither. If you mention an agent or subagent in your response, link it with the `[Name](id)` Don't use generic label such as `[agent]`, `[worker]`, or `[subagent]`. For cloud subagents, when the agent has edited code, link to `[Review](bc-id#changes)`, or, if you know the exact added and deleted line counts, `[Review +A D](bc-id#changes)`, replacing A and D with those counts. Never write A or D literally. Use `[Try Live](bc-id#desktop)` only when the agent used computer use.",
"enum": [
"local",
"cloud"
],
"type": "string"
},
"file_attachments": {
"description": "Optional array of file paths to images or videos to pass to video-review subagents. Files are read and attached to the subagent's context. Use to forward relevant media (e.g. images sent by user) to subagents.",
"items": {
"type": "string"
},
"type": "array"
},
"interrupt": {
"description": "If true and `resume` targets a running async agent, interrupt the current run and send this prompt immediately. Only use when the user explicitly asks to interrupt or change what the running agent is doing.",
"type": "boolean"
},
"model": {
"description": "Optional model slug for this agent. If provided, it must resolve to one of the available model slugs. If omitted, the subagent uses the same model as the parent agent. Do not pass if resume field is set (prior model will be used). Use \"inherit\" unless the user explicitly requested another listed model.",
"type": "string"
},
"prompt": {
"description": "The task for the agent to perform",
"type": "string"
},
"resume": {
"description": "Optional agent ID to resume from. If provided, sends a follow-up message to the agent after it has completed. Requests to a currently running asynchronous agent fail unless `interrupt` is true; set `interrupt` to true only when you intend to interrupt the running agent. Use \"self\" to start a new agent with your own entire conversation history as a starting point (aka 'self-fork').",
"type": "string"
},
"run_in_background": {
"description": "Run the agent in the background (returns output_file path to check later). If this is false, you will be blocked until the agent completes. If the user is currently in Multitask Mode, always set this parameter to True. When true, the background subagent will send a notification when it completes.",
"type": "boolean"
},
"subagent_type": {
"description": "Subagent type to use for this task. Must be one of: generalPurpose, explore, shell, cursor-guide, ci-investigator, bugbot, security-review, best-of-n-runner, test-subagent.",
"enum": [
"generalPurpose",
"explore",
"shell",
"cursor-guide",
"ci-investigator",
"bugbot",
"security-review",
"best-of-n-runner",
"test-subagent"
],
"type": "string"
}
},
"required": [
"description",
"prompt"
]
}
}
},
{
"type": "function",
"function": {
"name": "TodoWrite",
"description": "Use this tool to create and manage a structured task list for your current coding session.",
"parameters": {
"type": "object",
"properties": {
"merge": {
"description": "Whether to merge the todos with the existing todos. If true, the todos will be merged into the existing todos based on the id field. You can leave unchanged properties undefined. If false, the new todos will replace the existing todos.",
"type": "boolean"
},
"todos": {
"description": "Array of TODO items to update or create",
"items": {
"properties": {
"content": {
"description": "The description/content of the TODO item",
"type": "string"
},
"id": {
"description": "Unique identifier for the TODO item",
"type": "string"
},
"status": {
"description": "The current status of the TODO item",
"enum": [
"pending",
"in_progress",
"completed",
"cancelled"
],
"type": "string"
}
},
"required": [
"id",
"content",
"status"
],
"type": "object"
},
"minItems": 2,
"type": "array"
}
},
"required": [
"todos",
"merge"
]
}
}
},
{
"type": "function",
"function": {
"name": "UpdateCurrentStep",
"description": "Record a concise (6 words or less), user-friendly update of the major step or phase you are working on for the parent timeline. Update when the subtask changes. Set `final_summary` and `completed_subtitle` ONCE per response as your last action before the final response. ALWAYS use in parallel with at least one other tool. ALWAYS start the update with a descriptive verb.",
"parameters": {
"properties": {
"completed_subtitle": {
"$ref": "#/properties/current_step",
"description": "4-6 word, past-tense, final summary of the work you have completed. Will be used as your agent subtitle in the UI. Keep the text concise, high-level, and user-friendly. Set this field ONCE per turn, as the last thing you do before your final response, at the same time that you set the final_summary field."
},
"current_step": {
"description": "Major step or phase you are on. Update when the subtask changes. Keep the text concise, high-level, and user-friendly.",
"minLength": 1,
"type": "string"
},
"final_summary": {
"$ref": "#/properties/current_step",
"description": "User-facing executive summary succinctly reporting on your work / responding to the user's message; write this as a concise message speaking back to the user, not as a status tag. Typically 1-3 sentences, or a brief lead-in plus bullet points when there are multiple distinct takeaways, decisions, test results, etc. When using bullets, make them pleasant and easy to scan: 2-5 bullets when possible, one useful idea per bullet, ordered by importance to the user, concise but not cryptic, and no nested bullets unless the user requested detail. Use prose instead of bullets when there is only one main takeaway. Include the most relevant takeaways for the user, as implied by the user's original request. No unnecessary details. When answering questions by the user, include the full answer that the user is seeking. Examples of what to include: full answer(s) to user's question(s), high-level root cause while debugging, status update of completed (or in-progress) work, test results for specifically requested testing, blocking questions the user must answer before you can continue, links to newly created PRs, etc. Examples of what NOT to include (unless implicitly or explicitly requested by the user): tool calls / results, code / log / shell command excerpts, long file paths, line numbers, low-level implementation details, etc. Set this field just ONCE per turn, as the last thing you do before your final response, at the same time that you set the completed_subtitle field."
}
},
"type": "object"
}
}
},
{
"type": "function",
"function": {
"name": "WebFetch",
"description": "Fetch content from a specified URL and return its contents in a readable markdown format. Use this tool when you need to retrieve and analyze web content.",
"parameters": {
"type": "object",
"properties": {
"requestSmartModeApproval": {
"description": "Set to true when immediately retrying the exact same fetch after Auto-review blocks it and you decide the user should approve it through the native approval card.",
"type": "boolean"
},
"smartModeBlockReason": {
"description": "Provide the exact block reason returned by Auto-review in the prior rejection. Required when requestSmartModeApproval is true so the approval card shows the original classifier reason without re-running the classifier.",
"type": "string"
},
"url": {
"description": "The URL to fetch. The content will be converted to a readable markdown format.",
"type": "string"
}
},
"required": [
"url"
]
}
}
},
{
"type": "function",
"function": {
"name": "WebSearch",
"description": "Search web for real-time info on any topic; use for up-to-date facts not in training data, like current events or tech updates. Results include snippets and URLs.",
"parameters": {
"type": "object",
"properties": {
"explanation": {
"description": "One sentence explanation as to why this tool is being used, and how it contributes to the goal.",
"type": "string"
},
"search_term": {
"description": "The search term to look up on the web. Be specific and include relevant keywords for better results. For technical queries, include version numbers or dates if relevant.",
"type": "string"
}
},
"required": [
"search_term"
]
}
}
},
{
"type": "function",
"function": {
"name": "Write",
"description": "Writes a file to the local filesystem.",
"parameters": {
"type": "object",
"properties": {
"contents": {
"description": "The contents to write to the file",
"type": "string"
},
"path": {
"description": "The absolute path to the file to modify",
"type": "string"
}
},
"required": [
"path",
"contents"
]
}
}
}
],
"variants": {
"Task.subagent": {
"type": "function",
"function": {
"name": "Task",
"description": "Launch a new agent to handle complex, multi-step tasks autonomously.\n\nThe Task tool launches specialized subagents (subprocesses) that autonomously handle complex tasks. Each subagent_type has specific capabilities and tools available to it.\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\nVERY IMPORTANT: When broadly exploring the codebase to gather context for a large task, it is recommended that you use the Task tool with subagent_type=\"explore\" instead of running search commands directly.\n\nIf the query is a narrow or specific question, you should NOT use the Task and instead address the query directly using the other tools available to you.\n\nExamples:\n- user: \"Where is the ClientError class defined?\" assistant: [Uses Grep directly - this is a needle query for a specific class]\n- user: \"Run this query using my database API\" assistant: [Calls the MCP directly - this is not a broad exploration task]\n- user: \"What is the codebase structure?\" assistant: [Uses the Task tool with subagent_type=\"explore\"]\n\nIf it is possible to explore different areas of the codebase in parallel, you should launch multiple agents concurrently.\n\nWhen NOT to use the Task tool:\n- Simple, single or few-step tasks that can be performed by a single agent (using parallel or sequential tool calls) -- just call the tools directly instead.\n- For example:\n - If you want to read a specific file path, use the Read or Glob tool instead of the Task tool, to find the match more quickly\n - If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Task tool, to find the match more quickly\n - If you are searching for a specific class definition like \"class Foo\", use the Glob tool instead, to find the match more quickly\n\nUsage notes:\n- Always include a short description (3-5 words) summarizing what the agent will do\n- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple Task tool use content blocks.\n- When the agent is done, it will return a single message back to you. Specify exactly what information the agent should return back in its final response to you.\n- Agents can be resumed using the `resume` parameter by passing the agent ID from a previous invocation. This sends a follow-up message after the agent has completed, preserving existing context. If the agent is still running, the request fails unless `interrupt` is true. Set `interrupt` to true only when the user explicitly wants to interrupt the running agent. You can also set `resume` to \"self\" to fork the current parent agent into a new child subagent. When NOT resuming, each invocation starts fresh and you should provide a detailed task description with all necessary context for the agent to perform its task autonomously.\n- If you mention an agent or subagent in your response, link it with the `[Name](id)` Don't use generic label such as `[agent]`, `[worker]`, or `[subagent]`. For cloud subagents, when the agent has edited code, link to `[Review](bc-id#changes)`, or, if you know the exact added and deleted line counts, `[Review +A D](bc-id#changes)`, replacing A and D with those counts. Never write A or D literally. Use `[Try Live](bc-id#desktop)` only when the agent used computer use.\n- When using the Task tool, the subagent invocation does not have access to the user's message or prior assistant steps. Therefore, you should provide a highly detailed task description with all necessary context for the agent to perform its task autonomously.\n- The subagent's outputs should generally be trusted\n- Clearly tell the subagent which tasks you want it to perform, since it is not aware of the user's intent or your prior assistant steps.\n- If the subagent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n- If the user specifies that they want you to run subagents \"in parallel\", you MUST send a single message with multiple Task tool use content blocks. For example, if you need to launch both a code-reviewer subagent and a test-runner subagent in parallel, send a single message with both tool calls.\n- Avoid delegating the full query to the Task tool and returning the result. In these cases, you should address the query using the other tools available to you.\n\nAvailable subagent_types and a quick description of what they do:\n- generalPurpose: General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. Use when searching for a keyword or file and not confident you'll find the match quickly.\n- explore: Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. \"src/components/**/*.tsx\"), search code for keywords (eg. \"API endpoints\"), or answer questions about the codebase (eg. \"how do API endpoints work?\"). When calling this agent, specify the desired thoroughness level: \"quick\" for basic searches, \"medium\" for moderate exploration, or \"very thorough\" for comprehensive analysis across multiple locations and naming conventions.\n- shell: Command execution specialist for running bash commands. Use this for git operations, command execution, and other terminal tasks.\n- cursor-guide: Read Cursor product documentation to answer questions about how Cursor Desktop, IDE, CLI, Cloud Agents, Bugbot, and other features work. Use when the user asks 'In Cursor, how do I...?' or similar questions about Cursor products.\n- ci-investigator: Investigate a single failing PR CI check and return a short root-cause summary. Use when the user asks to summarize, explain, diagnose, or investigate a specific failed check from a pull request.\n- bugbot: Use only when the user *explicitly* asks for a Bugbot-like review of local code changes. When launching this subagent, set the Task description to exactly \"Bugbot\". Launch exactly one Bugbot subagent with `run_in_background: false` unless the user explicitly asks to run in background. Use this fixed prompt form: \"Full Repository Path: ...\\nDiff: <one of: \"branch changes\", \"uncommitted changes\", \"natural language\">\\nChange Description: ...\\nCustom Instructions: ...\"; default to `Diff: branch changes`; include `Change Description` only when `Diff` is `natural language`, formatting it as one block per changed file (a `<path> (added|modified|deleted|renamed)` header followed by bullets of what changed, mentioning line numbers or ranges inline where helpful), and only use `natural language` as a last resort after a regular diff-based review failed because the diff could not be computed; include `Custom Instructions` only when the user gave specific review instructions. This subagent is single-shot and does not support `resume`; always launch a fresh subagent instead.\n- security-review: Use only when the user *explicitly* asks for a security review of local code changes. When launching this subagent, set the Task description to exactly \"Security Review\". Launch exactly one security-review subagent with `run_in_background: false` unless the user explicitly asks to run in background. Use this fixed prompt form: \"Full Repository Path: ...\\nDiff: <one of: \"branch changes\", \"uncommitted changes\">\\nCustom Instructions: ...\"; default to `Diff: branch changes`; include `Custom Instructions` only when the user gave specific review instructions. This subagent is single-shot and does not support `resume`; always launch a fresh subagent instead.\n- best-of-n-runner: Run a task in an isolated git worktree. Each best-of-n-runner gets its own branch and working directory. Use for best-of-N parallel attempts or isolated experiments.\n- test-subagent: Describe when Agent should delegate to this subagent.\n\nIf the user explicitly asks for the model of a subagent/task, you may ONLY use model slugs from this list:\n- inherit (default; required unless the user explicitly requested another model)\n- claude-opus-5-thinking-high\n- composer-2.5-fast\n- cursor-grok-4.5-low\n- cursor-grok-4.6-high-fast\n- gpt-5.6-sol-medium\n\nIf the user isn't asking for a specific version, prefer the latest version of the model family. As an example, if the user just says \"gpt\" or \"claude\", use the latest available version of GPT or Claude.\n\nIMPORTANT: If the user requests a model that is NOT in the list above, do NOT substitute a different model or guess. Instead, skip launching the subagent with that model and tell the user which model was unavailable and which models are available.\n\nWhen speaking to the USER about which model you selected for a subagent, do NOT use the kebab-case model names unless the user requested the model using that format. Ue the same naming scheme the user used to discuss the model when they requested it.\n\nWhen an agent runs in the background, you will be automatically notified when it completes after you end your own turn - do NOT AwaitShell, poll, or proactively check on its progress. Continue with other work or end your turn instead.",
"parameters": {
"type": "object",
"properties": {
"description": {
"description": "A short, user-friendly title for the subagent. This appears in the UI as the subagent's name. Make it concrete and distinct, consider recent titles to avoid reuse. For resumed subagents which you are prompting to work on a separate task, give an updated description based on the latest work the subagent is performing. (Do not rename if the subagent is continuing work on the same high-level task.)",
"type": "string"
},
"file_attachments": {
"description": "Optional array of file paths to images or videos to pass to video-review subagents. Files are read and attached to the subagent's context. Use to forward relevant media (e.g. images sent by user) to subagents.",
"items": {
"type": "string"
},
"type": "array"
},
"interrupt": {
"description": "If true and `resume` targets a running async agent, interrupt the current run and send this prompt immediately. Only use when the user explicitly asks to interrupt or change what the running agent is doing.",
"type": "boolean"
},
"model": {
"description": "Optional model slug for this agent. If provided, it must resolve to one of the available model slugs. If omitted, the subagent uses the same model as the parent agent. Do not pass if resume field is set (prior model will be used). Use \"inherit\" unless the user explicitly requested another listed model.",
"type": "string"
},
"prompt": {
"description": "The task for the agent to perform",
"type": "string"
},
"resume": {
"description": "Optional agent ID to resume from. If provided, sends a follow-up message to the agent after it has completed. Requests to a currently running asynchronous agent fail unless `interrupt` is true; set `interrupt` to true only when you intend to interrupt the running agent. Use \"self\" to start a new agent with your own entire conversation history as a starting point (aka 'self-fork').",
"type": "string"
},
"run_in_background": {
"description": "Run the agent in the background (returns output_file path to check later). If this is false, you will be blocked until the agent completes. If the user is currently in Multitask Mode, always set this parameter to True. When true, the background subagent will send a notification when it completes.",
"type": "boolean"
},
"subagent_type": {
"description": "Subagent type to use for this task. Must be one of: generalPurpose, explore, shell, cursor-guide, ci-investigator, bugbot, security-review, best-of-n-runner, test-subagent.",
"enum": [
"generalPurpose",
"explore",
"shell",
"cursor-guide",
"ci-investigator",
"bugbot",
"security-review",
"best-of-n-runner",
"test-subagent"
],
"type": "string"
}
},
"required": [
"description",
"prompt"
]
}
}
}
}
}