Skip to content

fix: Claude model compatibility for Antigravity proxy#365

Closed
anilcancakir wants to merge 1 commit intoOpencode-DCP:masterfrom
anilcancakir:master
Closed

fix: Claude model compatibility for Antigravity proxy#365
anilcancakir wants to merge 1 commit intoOpencode-DCP:masterfrom
anilcancakir:master

Conversation

@anilcancakir
Copy link

@anilcancakir anilcancakir commented Feb 7, 2026

This PR fixes three bugs that cause 400 Invalid Request and Invalid IDs provided errors when using DCP with Claude models through the Antigravity proxy.


Fix 1: Context Injection Tool Pairing (inject.ts + config.ts)

Problem: DCP injected context information into the last message as a synthetic tool part. Claude's VALIDATED mode requires every tool_use block to have a matching tool_result block — since the synthetic tool part has no tool_result, the API returns a 400 error.

Solution: Added textPartModels config setting. When the model ID matches any of these patterns (default: ["antigravity-claude"]), DCP injects a text part instead of a tool part, which doesn't require tool pairing.

Changed files:

  • lib/config.tstextPartModels setting, validation, defaults, merge logic
  • lib/messages/inject.ts — Model detection + text/tool part routing
  • README.md — Config documentation

Fix 2: pruneFullTool Tool Pairing (prune.ts)

Problem: pruneFullTool was completely removing edit/write tool parts from messages. In Claude's VALIDATED mode, the remaining functionCall blocks had no matching functionResponse, causing a 400 error. (Fix 1 alone was not sufficient — this was identified through debug logging.)

Solution: Instead of removing tool parts entirely, their content is replaced with placeholders. The tool part structure is preserved, so functionCall/functionResponse pairing remains intact. Token savings are ~95% preserved since the bulk of tokens come from file contents, not tool metadata.

Changed file: lib/messages/prune.ts


Fix 3: Distill/Prune Invalid IDs (prune-shared.ts)

Problem: executePruneOperation() calls ensureSessionInitialized(), which resets toolIdList to [] on session change. Then syncToolCache() only rebuilds toolParameters but does not rebuild toolIdList. The subsequent ID validation runs against an empty list, causing all numeric IDs to fail with "Invalid IDs provided".

Solution: Added a buildToolIdList() call after syncToolCache() in executePruneOperation(), following the same established pattern already used in hooks.ts.

Changed file: lib/tools/prune-shared.ts

- Add textPartModels config: configurable model patterns that use text
  parts instead of synthetic tool parts for context injection, preventing
  Claude VALIDATED mode tool_use/tool_result pairing errors (default:
  ['antigravity-claude'])

- Fix pruneFullTool: replace edit/write tool part content with
  placeholders instead of removing parts entirely, preserving tool
  pairing integrity required by Claude's VALIDATED mode

- Fix distill/prune Invalid IDs: rebuild toolIdList after
  syncToolCache in executePruneOperation to prevent stale/empty
  ID list after session reinitialization
Copilot AI review requested due to automatic review settings February 7, 2026 14:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves compatibility with Claude “VALIDATED” tool semantics by adjusting how DCP injects context and how full-tool pruning preserves tool part structure, while also fixing stale tool ID handling during prune operations.

Changes:

  • Add tools.settings.textPartModels to force context injection via text parts for specific model patterns.
  • Update full-tool pruning to preserve tool parts (replace content with placeholders) instead of removing parts, preventing tool pairing errors.
  • Rebuild state.toolIdList after session (re)initialization + tool cache sync to avoid invalid/stale numeric IDs.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
lib/tools/prune-shared.ts Rebuilds tool ID list during prune execution after cache sync.
lib/messages/prune.ts Changes full-tool pruning to keep tool parts and replace content with placeholders.
lib/messages/inject.ts Adds model-pattern-based switch to inject context via text parts.
lib/config.ts Adds/merges/validates new textPartModels config option with defaults.
README.md Documents the new configuration option in the default config example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +55
await ensureSessionInitialized(ctx.client, state, sessionId, logger, messages)
await syncToolCache(state, config, logger, messages)
buildToolIdList(state, messages, logger)

const currentParams = getCurrentParams(state, messages, logger)
const currentParams = getCurrentParams(state, messages, logger)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new lines are indented inconsistently (extra leading space before await/buildToolIdList), which will likely fail linting/formatting checks and makes the block harder to read. Align indentation with the surrounding code (4 spaces).

Copilot uses AI. Check for mistakes.
Comment on lines +51 to +55
if (part.state?.input && typeof part.state.input === "object") {
for (const key of Object.keys(part.state.input)) {
if (typeof part.state.input[key] === "string") {
part.state.input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT
}
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pruneFullTool replaces successful edit/write tool inputs with PRUNED_TOOL_ERROR_INPUT_REPLACEMENT ("failed tool call"), which is misleading when the tool status is completed. Use a neutral replacement string for successful tool inputs (and reserve the error-specific placeholder for errored tool calls).

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +59
if (part.state?.status === "completed") {
part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For pruned edit/write tool parts, only status === "completed" outputs are replaced; for status === "error", part.state.error (and any output) are left intact. Previously this code removed the entire tool part, so this change can leave large error payloads in context and reduce token savings. Consider also replacing state.error/state.output with placeholders for non-completed statuses when the tool is being fully pruned.

Suggested change
if (part.state?.status === "completed") {
part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT
if (part.state) {
// When fully pruning a tool call, scrub outputs and errors regardless of status
if ("output" in part.state) {
part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT
}
if ("error" in part.state) {
part.state.error = PRUNED_TOOL_OUTPUT_REPLACEMENT
}

Copilot uses AI. Check for mistakes.
Comment on lines +308 to +316
if (
tools.settings.textPartModels !== undefined &&
!Array.isArray(tools.settings.textPartModels)
) {
errors.push({
key: "tools.settings.textPartModels",
expected: "string[]",
actual: typeof tools.settings.textPartModels,
})
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

textPartModels is only validated as an array, but insertPruneToolContext calls pattern.toLowerCase(). If the config contains non-string entries, this will throw at runtime. Extend validation to ensure every element in tools.settings.textPartModels is a string (or coerce/filter invalid entries).

Suggested change
if (
tools.settings.textPartModels !== undefined &&
!Array.isArray(tools.settings.textPartModels)
) {
errors.push({
key: "tools.settings.textPartModels",
expected: "string[]",
actual: typeof tools.settings.textPartModels,
})
if (tools.settings.textPartModels !== undefined) {
if (!Array.isArray(tools.settings.textPartModels)) {
errors.push({
key: "tools.settings.textPartModels",
expected: "string[]",
actual: typeof tools.settings.textPartModels,
})
} else if (
!tools.settings.textPartModels.every(
(model) => typeof model === "string"
)
) {
errors.push({
key: "tools.settings.textPartModels",
expected: "string[]",
actual: JSON.stringify(tools.settings.textPartModels),
})
}

Copilot uses AI. Check for mistakes.
const modelID = userInfo.model?.modelID || ""
const lowerModelID = modelID.toLowerCase()
const useTextPart = config.tools.settings.textPartModels.some(
(pattern) => lowerModelID.includes(pattern.toLowerCase()),
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pattern.toLowerCase() assumes every entry in config.tools.settings.textPartModels is a string. Even with config validation, it would be safer to guard here (e.g., skip non-string patterns) to avoid a runtime crash on malformed configs.

Suggested change
(pattern) => lowerModelID.includes(pattern.toLowerCase()),
(pattern) =>
typeof pattern === "string" &&
lowerModelID.includes(pattern.toLowerCase()),

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +117
> // Model name patterns that should use text parts instead of tool parts
> // for DCP context injection. Prevents 400 errors with providers that use
> // strict tool call/result pairing (e.g., Antigravity Claude models).
> // Uses case-insensitive substring matching against the model ID.
> "textPartModels": ["antigravity-claude"],
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README documents the new tools.settings.textPartModels option, but the referenced JSON schema (dcp.schema.json) does not currently include this property. Update the schema to keep editor validation/autocomplete in sync with the documented config.

Suggested change
> // Model name patterns that should use text parts instead of tool parts
> // for DCP context injection. Prevents 400 errors with providers that use
> // strict tool call/result pairing (e.g., Antigravity Claude models).
> // Uses case-insensitive substring matching against the model ID.
> "textPartModels": ["antigravity-claude"],

Copilot uses AI. Check for mistakes.
@Tarquinen
Copy link
Collaborator

This is interesting, I'm a bit busy this weekend so I might need some patience on getting this reviewed, but I have a couple questions.

  1. is this due to opus 4.6 changes in antigravity? I don't have any errors running opus 4.5 right now. I think every tool use block should already have a matching tool result block, the injections add both parts which the ai sdk in opencode converts to the necessary provider structure. I don't want to do these injections as text parts because this causes UI bugs in opencode
  2. for edit and write tools, we can't remove just their input content this also causes really weird bugs, see New file write failures #215 . Our options are either removing pruning functionality for those tools or do it this way as far as I know. I also haven't seen antigravity errors with this either. Which antigravity auth method do you use?
  3. I'm on my phone so I can't review the code easily now, but isn't the tool id list build in the hook handler at the same time as the parameter cache? Might be remembering wrong or missing something

I haven't looked at the code yet I'll do a more thorough review later, but thank you very much for helping!

@Tarquinen
Copy link
Collaborator

Tarquinen commented Feb 9, 2026

I did end up adding buildToolIDList to prune-shared as your bot suggested in 20bae81, but for different reasons. Still don't understand 1 and 2, can you check my questions above?

@neavo
Copy link

neavo commented Feb 9, 2026

I also encountered the situation described in the PR when using claude-opus-4.5 provided by antig

@Tarquinen
Copy link
Collaborator

Which antigravity auth method do you use? The current architecture in DCP works with every other provider and model as far as I know, including opus 4.5 through claude sub, api, and antigravity using https://github.com/Mirrowel/LLM-API-Key-Proxy. I'm definitely not changing the entire injection architecture for this provider because they do something different than everyone else, and I don't even want to add custom settings and flaky string matching that require maintenance. Can you raise an issue in whatever auth method is causing this instead?

@neavo
Copy link

neavo commented Feb 9, 2026

CPA https://github.com/router-for-me/CLIProxyAPI

I'm not very familiar with the details of how to implement a reverse proxy

However, CPA has been very stable for me in other scenarios, with only the issue mentioned in the PR. I'm not entirely sure where the actual problem lies

Whether to fix it and how to fix it is, of course, up to you to decide

@neavo
Copy link

neavo commented Feb 9, 2026

image

just triggered a fresh sample

@Mirrowel
Copy link

Mirrowel commented Feb 9, 2026

Clearly must be due to incomplete implementations, cliproxyapi or others

@Tarquinen
Copy link
Collaborator

Yea my problem is this PR isn't good enough due to the reasons above, and I don't want to start adding edge case code that will require maintenance for 1 auth service. I also don't think it's this plugins responsibility to fix auth service issues when only one is exerperiencing these issues, and there is at least 2 other third party providers for antigravity that work fine...

@Lynricsy
Copy link

Yea my problem is this PR isn't good enough due to the reasons above, and I don't want to start adding edge case code that will require maintenance for 1 auth service. I also don't think it's this plugins responsibility to fix auth service issues when only one is exerperiencing these issues, and there is at least 2 other third party providers for antigravity that work fine...

Could I ask which third-party providers for antigravity are working fine?

@Tarquinen
Copy link
Collaborator

@Lynricsy
Copy link

The two i've tried that work fine are NoeFabris/opencode-antigravity-auth and Mirrowel/LLM-API-Key-Proxy

When using CliProxyAPI, my requests trigger the following error: {"error":{"code":400,"message":"Request contains an invalid argument.","status":"INVALID_ARGUMENT"}}. I switched to opencode-antigravity-auth to test it, but the error persists.

@Lynricsy
Copy link

Request contains an invalid argument.

[Debug Info]

Requested Model: antigravity-claude-opus-4-6-thinking

Effective Model: claude-opus-4-6-thinking

Project: risin**1fc

Endpoint: https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:streamGenerateContent?alt=sse

Status: 400

Request ID: N/A

Tool Debug Missing: 6

Tool Debug Summary: decl=question,src=functionDeclarations,hasSchema=y | decl=bash,src=functionDeclarations,hasSchema=y | decl=read,src=functionDeclarations,hasSchema=y | decl=glob,src=functionDeclarations,hasSchema=y | decl=grep,src=functionDeclarations,hasSchema=y | decl=edit,src=functionDeclarations,hasSchema=y | decl=write,src=functionDeclarations,hasSchema=y | decl=task,src=functionDeclarations,hasSchema=y | decl=webfetch,src=functionDeclarations,hasSchema=y | decl=todowrite,src=functionDeclarations,hasSchema=y | decl=skill,src=functionDeclarations,hasSchema=y | decl=google_search,src=functionDeclarations,hasSchema=y | decl=pty_spawn,src=functionDeclarations,hasSchema=y | decl=pty_write,src=functionDeclarations,hasSchema=y | decl=pty_read,src=functionDeclarations,hasSchema=y | decl=pty_list,src=functionDeclarations,hasSchema=n | decl=pty_kill,src=functionDeclarations,hasSchema=y | decl=lsp_goto_definition,src=functionDeclarations,hasSchema=y | decl=lsp_find_references,src=functionDeclarations,hasSchema=y | decl=lsp_symbols,src=functionDeclarations,hasSchema=y

Tool Debug Payload: [{"functionDeclarations":[{"name":"question","description":"Use this tool when you need to ask the user questions during execution. This allows you to:\n1. Gather user preferences or requirements\n2. Clarify ambiguous instructions\n3. Get decisions on implementation choices as you work\n4. Offer choices to the user about what direction to take.\n\nUsage notes:\n- When `custom` is enabled (default), a \"Type your own answer\" option is added automatically; don't include \"Other\" or catch-all options\n- Answers are returned as arrays of labels; set `multiple: true` to allow selecting more than one\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","parameters":{"required":["questions"],"type":"object","properties":{"questions":{"description":"Questions to ask","type":"array","items":{"required":["question","header","options"],"type":"object","properties":{"question":{"description":"Complete question","type":"string"},"header":{"description":"Very short label (max 30 chars)","type":"string"},"options":{"description":"Available choices","type":"array","items":{"required":["label","description"],"type":"object","properties":{"label":{"description":"Display text (1-5 words, concise)","type":"string"},"description":{"description":"Explanation of choice","type":"string"}}}},"multiple":{"description":"Allow selecting multiple choices","type":"boolean"}}}}}}},{"name":"bash","description":"Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.\n\nAll commands run in /root/Projects/SuperMap/PrototypeMaker by default. Use the `workdir` parameter if you need to run a command in a different directory. AVOID using `cd <directory> && <command>` patterns - use `workdir` instead.\n\nIMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead.\n\nBefore executing the command, please follow these steps:\n\n1. Directory Verification:\n   - If the command will create new directories or files, first use `ls` to verify the parent directory exists and is the correct location\n   - For example, before running \"mkdir foo/bar\", first use `ls foo` to check that \"foo\" exists and is the intended parent directory\n\n2. Command Execution:\n   - Always quote file paths that contain spaces with double quotes (e.g., rm \"path with spaces/file.txt\")\n   - Examples of proper quoting:\n     - mkdir \"/Users/name/My Documents\" (correct)\n     - mkdir /Users/name/My Documents (incorrect - will fail)\n     - python \"/path/with spaces/script.py\" (correct)\n     - python /path/with spaces/script.py (incorrect - will fail)\n   - After ensuring proper quoting, execute the command.\n   - Capture the output of the command.\n\nUsage notes:\n  - The command argument is required.\n  - You can specify an optional timeout in milliseconds. If not specified, commands will time out after 120000ms (2 minutes).\n  - It is very helpful if you write a clear, concise description of what this command does in 5-10 words.\n  - If the output exceeds 2000 lines or 51200 bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Because of this, you do NOT need to use `head`, `tail`, or other truncation commands to limit output - just run the command directly.\n\n  - Avoid using Bash with the `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:\n    - File search: Use Glob (NOT find or ls)\n    - Content search: Use Grep (NOT grep or rg)\n    - Read files: Use Read (NOT cat/head/tail)\n    - Edit files: Use Edit (NOT sed/awk)\n    - Write files: Use Write (NOT echo >/cat <<EOF)\n    - Communication: Output text directly (NOT echo/printf)\n  - When issuing multiple commands:\n    - If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run \"git status\" and \"git diff\", send a single message with two Bash tool calls in parallel.\n    - If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., `git add . && git commit -m \"message\" && git push`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead.\n    - Use ';' only when you need to run commands sequentially but don't care if earlier commands fail\n    - DO NOT use newlines to separate commands (newlines are ok in quoted strings)\n  - AVOID using `cd <directory> && <command>`. Use the `workdir` parameter to change directories instead.\n    <good-example>\n    Use workdir=\"/foo/bar\" with command: pytest tests\n    </good-example>\n    <bad-example>\n    cd /foo/bar && pytest tests\n    </bad-example>\n\n# Committing changes with git\n\nOnly create commits when requested by the user. If unclear, ask first. When the user asks you to create a new git commit, follow these steps carefully:\n\nGit Safety Protocol:\n- NEVER update the git config\n- NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them\n- NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it\n- NEVER run force push to main/master, warn the user if they request it\n- Avoid git commit --amend. ONLY use --amend when ALL conditions are met:\n  (1) User explicitly requested amend, OR commit SUCCEEDED but pre-commit hook auto-modified files that need including\n  (2) HEAD commit was created by you in this conversation (verify: git log -1 --format='%an %ae')\n  (3) Commit has NOT been pushed to remote (verify: git status shows \"Your branch is ahead\")\n- CRITICAL: If commit FAILED or was REJECTED by hook, NEVER amend - fix the issue and create a NEW commit\n- CRITICAL: If you already pushed to remote, NEVER amend unless user explicitly requests it (requires force push)\n- NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.\n\n1. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following bash commands in parallel, each using the Bash tool:\n  - Run a git status command to see all untracked files.\n  - Run a git diff command to see both staged and unstaged changes that will be committed.\n  - Run a git log command to see recent commit messages, so that you can follow this repository's commit message style.\n2. Analyze all staged changes (both previously staged and newly added) and draft a commit message:\n  - Summarize the nature of the changes (eg. new feature, enhancement to an existing feature, bug fix, refactoring, test, docs, etc.). Ensure the message accurately reflects the changes and their purpose (i.e. \"add\" means a wholly new feature, \"update\" means an enhancement to an existing feature, \"fix\" means a bug fix, etc.).\n  - Do not commit files that likely contain secrets (.env, credentials.json, etc.). Warn the user if they specifically request to commit those files\n  - Draft a concise (1-2 sentences) commit message that focuses on the \"why\" rather than the \"what\"\n  - Ensure it accurately reflects the changes and their purpose\n3. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following commands:\n   - Add relevant untracked files to the staging area.\n   - Create the commit with a message\n   - Run git status after the commit completes to verify success.\n   Note: git status depends on the commit completing, so run it sequentially after the commit.\n4. If the commit fails due to pre-commit hook, fix the issue and create a NEW commit (see amend rules above)\n\nImportant notes:\n- NEVER run additional commands to read or explore code, besides git bash commands\n- NEVER use the TodoWrite or Task tools\n- DO NOT push to the remote repository unless the user explicitly asks you to do so\n- IMPORTANT: Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported.\n- If there are no changes to commit (i.e., no untracked files and no modifications), do not create an empty commit\n\n# Creating pull requests\nUse the gh command via the Bash tool for ALL GitHub-related tasks including working with issues, pull requests, checks, and releases. If given a GitHub URL use the gh command to get the information needed.\n\nIMPORTANT: When the user asks you to create a pull request, follow these steps carefully:\n\n1. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following bash commands in parallel using the Bash tool, in order to understand the current state of the branch since it diverged from the main branch:\n   - Run a git status command to see all untracked files\n   - Run a git diff command to see both staged and unstaged changes that will be committed\n   - Check if the current branch tracks a remote branch and is up to date with the remote, so you know if you need to push to the remote\n   - Run a git log command and `git diff [base-branch]...HEAD` to understand the full commit history for the current branch (from the time it diverged from the base branch)\n2. Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request!!!), and draft a pull request summary\n3. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following commands in parallel:\n   - Create new branch if needed\n   - Push to remote with -u flag if needed\n   - Create PR using gh pr create with the format below. Use a HEREDOC to pass the body to ensure correct formatting.\n<example>\ngh pr create --title \"the pr title\" --body \"$(cat <<'EOF'\n## Summary\n<1-3 bullet points>\n</example>\n\nImportant:\n- DO NOT use the TodoWrite or Task tools\n- Return the PR URL when you're done, so the user can see it\n\n# Other common operations\n- View comments on a GitHub PR: gh api repos/foo/bar/pulls/123/comments\n","parameters":{"required":["command","description"],"type":"object","properties":{"command":{"description":"The command to execute","type":"string"},"timeout":{"description":"Optional timeout in milliseconds","type":"number"},"workdir":{"description":"The working directory to run the command in. Defaults to /root/Projects/SuperMap/PrototypeMaker. Use this instead of 'cd' commands.","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"}}}},{"name":"read","description":"Reads a file from the local filesystem. You can access any file directly by using this tool.\nAssume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.\n\nUsage:\n- The filePath parameter must be an absolute path, not a relative path\n- By default, it reads up to 2000 lines starting from the beginning of the file\n- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters\n- Any lines longer than 2000 characters will be truncated\n- Results are returned using cat -n format, with line numbers starting at 1\n- You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.\n- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.\n- You can read image files using this tool.\n","parameters":{"required":["filePath"],"type":"object","properties":{"filePath":{"description":"The path to the file to read","type":"string"},"offset":{"description":"The line number to start reading from (0-based)","type":"number"},"limit":{"description":"The number of lines to read (defaults to 2000)","type":"number"}}}},{"name":"glob","description":"Fast file pattern matching tool with safety limits (60s timeout, 100 file limit). Supports glob patterns like \"**/*.js\" or \"src/**/*.ts\". Returns matching file paths sorted by modification time. Use this tool when you need to find files by name patterns.","parameters":{"required":["pattern"],"type":"object","properties":{"pattern":{"type":"string"},"path":{"type":"string"}}}},{"name":"grep","description":"Fast content search tool with safety limits (60s timeout, 10MB output). Searches file contents using regular expressions. Supports full regex syntax (eg. \"log.*Error\", \"function\\s+\\w+\", etc.). Filter files by pattern with the include parameter (eg. \"*.js\", \"*.{ts,tsx}\"). Returns file paths with matches sorted by modification time.","parameters":{"required":["pattern"],"type":"object","properties":{"pattern":{"type":"string"},"include":{"type":"string"},"path":{"type":"string"}}}},{"name":"edit","description":"Performs exact string replacements in files. \n\nUsage:\n- You must use your `Read` tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file. \n- When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the oldString or newString.\n- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.\n- Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.\n- The edit will FAIL if `oldString` is not found in the file with an error \"oldString not found in content\".\n- The edit will FAIL if `oldString` is found multiple times in the file with an error \"oldString found multiple times and requires more code context to uniquely identify the intended match\". Either provide a larger string with more surrounding context to make it unique or use `replaceAll` to change every instance of `oldString`. \n- Use `replaceAll` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.\n","parameters":{"required":["filePath","oldString","newString"],"type":"object","properties":{"filePath":{"description":"The absolute path to the file to modify","type":"string"},"oldString":{"description":"The text to replace","type":"string"},"newString":{"description":"The text to replace it with (must be different from oldString)","type":"string"},"replaceAll":{"description":"Replace all occurrences of oldString (default false)","type":"boolean"}}}},{"name":"write","description":"Writes a file to the local filesystem.\n\nUsage:\n- This tool will overwrite the existing file if there is one at the provided path.\n- If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.\n- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.\n- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.\n- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.\n","parameters":{"required":["content","filePath"],"type":"object","properties":{"content":{"description":"The content to write to the file","type":"string"},"filePath":{"description":"The absolute path to the file to write (must be absolute, not relative)","type":"string"}}}},{"name":"task","description":"Spawn agent task with category-based or direct agent selection.\n\nMUTUALLY EXCLUSIVE: Provide EITHER category OR subagent_type, not both (unless continuing a session).\n\n- load_skills: ALWAYS REQUIRED. Pass at least one skill name (e.g., [\"playwright\"], [\"git-master\", \"frontend-ui-ux\"]).\n- category: Use predefined category → Spawns Sisyphus-Junior with category config\n  Available categories:\n  - visual-engineering: Frontend, UI/UX, design, styling, animation\n  - ultrabrain: Use ONLY for genuinely hard, logic-heavy tasks. Give clear goals only, not step-by-step instructions.\n  - deep: Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding.\n  - artistry: Complex problem-solving with unconventional, creative approaches - beyond standard patterns\n  - quick: Trivial tasks - single file changes, typo fixes, simple modifications\n  - unspecified-low: Tasks that don't fit other categories, low effort required\n  - unspecified-high: Tasks that don't fit other categories, high effort required\n  - writing: Documentation, prose, technical writing\n- subagent_type: Use specific agent directly (e.g., \"oracle\", \"explore\")\n- run_in_background: true=async (returns task_id), false=sync (waits for result). Default: false. Use background=true ONLY for parallel exploration with 5+ independent queries.\n- session_id: Existing Task session to continue (from previous task output). Continues agent with FULL CONTEXT PRESERVED - saves tokens, maintains continuity.\n- command: The command that triggered this task (optional, for slash command tracking).\n\n**WHEN TO USE session_id:**\n- Task failed/incomplete → session_id with \"fix: [specific issue]\"\n- Need follow-up on previous result → session_id with additional question\n- Multi-turn conversation with same agent → always session_id instead of new task\n\nPrompts MUST be in English.","parameters":{"required":["load_skills","description","prompt","run_in_background"],"type":"object","properties":{"load_skills":{"type":"array","items":{"type":"string"}},"description":{"type":"string"},"prompt":{"type":"string"},"run_in_background":{"type":"boolean"},"category":{"type":"string"},"subagent_type":{"type":"string"},"session_id":{"type":"string"},"command":{"type":"string"}}}},{"name":"webfetch","description":"- Fetches content from a specified URL\n- Takes a URL and optional format as input\n- Fetches the URL content, converts to requested format (markdown by default)\n- Returns the content in the specified format\n- Use this tool when you need to retrieve and analyze web content\n\nUsage notes:\n  - IMPORTANT: if another tool is present that offers better web fetching capabilities, is more targeted to the task, or has fewer restrictions, prefer using that tool instead of this one.\n  - The URL must be a fully-formed valid URL\n  - HTTP URLs will be automatically upgraded to HTTPS\n  - Format options: \"markdown\" (default), \"text\", or \"html\"\n  - This tool is read-only and does not modify any files\n  - Results may be summarized if the content is very large\n","parameters":{"required":["url","format"],"type":"object","properties":{"url":{"description":"The URL to fetch content from","type":"string"},"format":{"description":"The format to return the content in (text, markdown, or html). Defaults to markdown. (Allowed: text, markdown, html)","type":"string","enum":["text","markdown","html"]},"timeout":{"description":"Optional timeout in seconds (max 120)","type":"number"}}}},{"name":"todowrite","description":"Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.\nIt also helps the user understand the progress of the task and overall progress of their requests.\n\n## When to Use This Tool\nUse this tool proactively in these scenarios:\n\n1. Complex multistep tasks - When a task requires 3 or more distinct steps or actions\n2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations\n3. User explicitly requests todo list - When the user directly asks you to use the todo list\n4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)\n5. After receiving new instructions - Immediately capture user requirements as todos. Feel free to edit the todo list based on new information.\n6. After completing a task - Mark it complete and add any new follow-up tasks\n7. When you start working on a new task, mark the todo as in_progress. Ideally you should only have one todo as in_progress at a time. Complete existing tasks before starting new ones.\n\n## When NOT to Use This Tool\n\nSkip using this tool when:\n1. There is only a single, straightforward task\n2. The task is trivial and tracking it provides no organizational benefit\n3. The task can be completed in less than 3 trivial steps\n4. The task is purely conversational or informational\n\nNOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.\n\n## Examples of When to Use the Todo List\n\n<example>\nUser: I want to add a dark mode toggle to the application settings. Make sure you run the tests and build when you're done!\nAssistant: I'll help add a dark mode toggle to your application settings. Let me create a todo list to track this implementation.\n*Creates todo list with the following items:*\n1. Create dark mode toggle component in Settings page\n2. Add dark mode state management (context/store)\n3. Implement CSS-in-JS styles for dark theme\n4. Update existing components to support theme switching\n5. Run tests and build process, addressing any failures or errors that occur\n*Begins working on the first task*\n\n<reasoning>\nThe assistant used the todo list because:\n1. Adding dark mode is a multi-step feature requiring UI, state management, and styling changes\n2. The user explicitly requested tests and build be run afterward\n3. The assistant inferred that tests and build need to pass by adding \"Ensure tests and build succeed\" as the final task\n</reasoning>\n</example>\n\n<example>\nUser: Help me rename the function getCwd to getCurrentWorkingDirectory across my project\nAssistant: Let me first search through your codebase to find all occurrences of 'getCwd'.\n*Uses grep or search tools to locate all instances of getCwd in the codebase*\nAssistant: I've found 15 instances of 'getCwd' across 8 different files. Let me create a todo list to track these changes.\n*Creates todo list with specific items for each file that needs updating*\n\n<reasoning>\nThe assistant used the todo list because:\n1. First, the assistant searched to understand the scope of the task\n2. Upon finding multiple occurrences across different files, it determined this was a complex task with multiple steps\n3. The todo list helps ensure every instance is tracked and updated systematically\n4. This approach prevents missing any occurrences and maintains code consistency\n</reasoning>\n</example>\n\n\n<example>\nUser: I need to implement these features for my e-commerce site: user registration, product catalog, shopping cart, and checkout flow.\nAssistant: I'll help implement these features. First, let's add all the features to the todo list.\n*Creates a todo list breaking down each feature into specific tasks based on the project architecture*\nAssistant: Let's start with user registration. This will involve creating database models, API endpoints, and frontend forms that integrate with your existing authentication system.\n\n<reasoning>\nThe assistant used the todo list because:\n1. The user provided multiple complex features to implement in a comma separated list\n2. The todo list helps organize these large features into manageable tasks\n3. This approach allows for tracking progress across the entire implementation\n</reasoning>\n</example>\n\n<example>\nUser: Can you help optimize my React application? It's rendering slowly and has performance issues.</user>\nAssistant: I'll help optimize your React application. First, let me examine your codebase to identify potential performance bottlenecks.\n*Reviews component structure, render patterns, state management, and data fetching*\nAssistant: After analyzing your codebase, I've identified several performance issues. Let me create a todo list to track our optimization efforts.\n*Creates todo list with items like: 1) Implement memoization for expensive calculations in ProductList, 2) Add virtualization for long lists in Dashboard, 3) Optimize image loading in Gallery component, 4) Fix state update loops in ShoppingCart, 5) Review bundle size and implement code splitting*\nLet's start by implementing memoization for the expensive calculations in your ProductList component.</assistant>\n\n<reasoning>\nThe assistant used the todo list because:\n1. First, the assistant examined the codebase to identify specific performance issues\n2. Based on this analysis, it identified multiple optimization opportunities\n3. Performance optimization is a non-trivial task requiring multiple steps\n4. The todo list helps methodically track improvements across different components\n5. This systematic approach ensures all performance bottlenecks are addressed\n</reasoning>\n</example>\n\n## Examples of When NOT to Use the Todo List\n\n<example>\nUser: How do I print 'Hello World' in Python?\nAssistant: In Python, you can print \"Hello World\" with this simple code:\n\npython\nprint(\"Hello World\")\n\nThis will output the text \"Hello World\" to the console when executed.</assistant>\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, trivial task that can be completed in one step. There's no need to track multiple tasks or steps for such a straightforward request.\n</reasoning>\n</example>\n\n<example>\nUser: What does the git status command do?\nAssistant: The git status command shows the current state of your working directory and staging area. It displays which changes have been staged, which haven't, and which files aren't being tracked by Git. This is a fundamental command for understanding the current state of your repository before making commits.\n\n<reasoning>\nThe assistant did not use the todo list because this is an informational request with no actual coding task to complete. The user is simply asking for an explanation, not for the assistant to perform multiple steps or tasks.\n</reasoning>\n</example>\n\n<example>\nUser: Can you add a comment to the calculateTotal function to explain what it does?\nAssistant: Sure, let me add a comment to the calculateTotal function to explain what it does.\n* Uses the Edit tool to add a comment to the calculateTotal function *\n\n<reasoning>\nThe assistant did not use the todo list because this is a single, straightforward task confined to one location in the code. Adding a comment doesn't require tracking multiple steps or systematic organization.\n</reasoning>\n</example>\n\n<example>\nUser: Run npm install for me and tell me what happens.\nAssistant: I'll run the npm install command for you.\n\n*Executes: npm install*\n\nThe command completed successfully. Here's the output:\n[Output of npm install command]\n\nAll dependencies have been installed according to your package.json file.\n\n<reasoning>\nThe assistant did not use the todo list because this is a single command execution with immediate results. There are no multiple steps to track or organize, making the todo list unnecessary for this straightforward task.\n</reasoning>\n</example>\n\n## Task States and Management\n\n1. **Task States**: Use these states to track progress:\n   - pending: Task not yet started\n   - in_progress: Currently working on (limit to ONE task at a time)\n   - completed: Task finished successfully\n   - cancelled: Task no longer needed\n\n2. **Task Management**:\n   - Update task status in real-time as you work\n   - Mark tasks complete IMMEDIATELY after finishing (don't batch completions)\n   - Only have ONE task in_progress at any time\n   - Complete current tasks before starting new ones\n   - Cancel tasks that become irrelevant\n\n3. **Task Breakdown**:\n   - Create specific, actionable items\n   - Break complex tasks into smaller, manageable steps\n   - Use clear, descriptive task names\n\nWhen in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.\n\n","parameters":{"required":["todos"],"type":"object","properties":{"todos":{"description":"The updated todo list","type":"array","items":{"required":["content","status","priority","id"],"type":"object","properties":{"content":{"description":"Brief description of the task","type":"string"},"status":{"description":"Current status of the task: pending, in_progress, completed, cancelled","type":"string"},"priority":{"description":"Priority level of the task: high, medium, low","type":"string"},"id":{"description":"Unique identifier for the todo item","type":"string"}}}}}}},{"name":"skill","description":"Load a skill to get detailed instructions for a specific task.\n\nSkills provide specialized knowledge and step-by-step guidance.\nUse this when a task matches an available skill's description.\n\n<available_skills>\n  <skill>\n    <name>playwright</name>\n    <description>(opencode - Skill) MUST USE for any browser-related tasks. Browser automation via Playwright MCP - verification, browsing, information gathering, web scraping, testing, screenshots, and all browser interactions.</description>\n  </skill>\n  <skill>\n    <name>frontend-ui-ux</name>\n    <description>(opencode - Skill) Designer-turned-developer who crafts stunning UI/UX even without design mockups</description>\n  </skill>\n  <skill>\n    <name>git-master</name>\n    <description>(opencode - Skill) MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with task(category='quick', load_skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.</description>\n  </skill>\n  <skill>\n    <name>dev-browser</name>\n    <description>(opencode - Skill) Browser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include 'go to [url]', 'click on', 'fill out the form', 'take a screenshot', 'scrape', 'automate', 'test the website', 'log into', or any browser interaction request.</description>\n  </skill>\n  <skill>\n    <name>vercel-react-best-practices</name>\n    <description>(opencode - Skill) React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.</description>\n  </skill>\n  <skill>\n    <name>ui-ux-pro-max</name>\n    <description>(opencode - Skill) UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples.</description>\n    <compatibility>OpenCode with Python 3.x</compatibility>\n  </skill>\n  <skill>\n    <name>web-interface-guidelines</name>\n    <description>(opencode - Skill) Review UI code for Vercel Web Interface Guidelines compliance</description>\n  </skill>\n  <skill>\n    <name>docx</name>\n    <description>(opencode - Skill) Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks</description>\n  </skill>\n</available_skills>","parameters":{"required":["name"],"type":"object","properties":{"name":{"type":"string"}}}},{"name":"google_search","description":"Search the web using Google Search and analyze URLs. Returns real-time information from the internet with source citations. Use this when you need up-to-date information about current events, recent developments, or any topic that may have changed. You can also provide specific URLs to analyze. IMPORTANT: If the user mentions or provides any URLs in their query, you MUST extract those URLs and pass them in the 'urls' parameter for direct analysis.","parameters":{"required":["query","thinking"],"type":"object","properties":{"query":{"type":"string"},"urls":{"type":"array","items":{"type":"string"}},"thinking":{"type":"boolean"}}}},{"name":"pty_spawn","description":"Spawns a new interactive PTY (pseudo-terminal) session that runs in the background.\n\nUnlike the built-in bash tool which runs commands synchronously and waits for completion, PTY sessions persist and allow you to:\n- Run long-running processes (dev servers, watch modes, etc.)\n- Send interactive input (including Ctrl+C, arrow keys, etc.)\n- Read output at any time\n- Manage multiple concurrent terminal sessions\n\nUsage:\n- The `command` parameter is required (e.g., \"npm\", \"python\", \"bash\")\n- Use `args` to pass arguments to the command (e.g., [\"run\", \"dev\"])\n- Use `workdir` to set the working directory (defaults to project root)\n- Use `env` to set additional environment variables\n- Use `title` to give the session a human-readable name\n- The `description` parameter is required: a clear, concise 5-10 word description\n- Use `notifyOnExit` to receive a notification when the process exits (default: false)\n\nReturns the session info including:\n- `id`: Unique identifier (pty_XXXXXXXX) for use with other pty_* tools\n- `pid`: Process ID\n- `status`: Current status (\"running\")\n\nAfter spawning, use:\n- `pty_write` to send input to the PTY\n- `pty_read` to read output from the PTY\n- `pty_list` to see all active PTY sessions\n- `pty_kill` to terminate the PTY\n\nExit Notifications:\nWhen `notifyOnExit` is true, you will receive a message when the process exits containing:\n- Session ID and title\n- Exit code\n- Total output lines\n- Last line of output (truncated to 250 chars)\n\nThis is useful for long-running processes where you want to be notified when they complete\ninstead of polling with `pty_read`. If the process fails (non-zero exit code), the notification\nwill suggest using `pty_read` with the `pattern` parameter to search for errors.\n\nExamples:\n- Start a dev server: command=\"npm\", args=[\"run\", \"dev\"], title=\"Dev Server\"\n- Start a Python REPL: command=\"python3\", title=\"Python REPL\"\n- Run tests in watch mode: command=\"npm\", args=[\"test\", \"--\", \"--watch\"]\n- Run build with notification: command=\"npm\", args=[\"run\", \"build\"], notifyOnExit=true\n","parameters":{"required":["command","args","description"],"type":"object","properties":{"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"workdir":{"type":"string"},"env":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]},"title":{"type":"string"},"description":{"type":"string"},"notifyOnExit":{"type":"boolean"}}}},{"name":"pty_write","description":"Sends input data to an active PTY session.\n\nUse this tool to:\n- Type commands or text into an interactive terminal\n- Send special key sequences (Ctrl+C, Enter, arrow keys, etc.)\n- Respond to prompts in interactive programs\n\nUsage:\n- `id`: The PTY session ID (from pty_spawn or pty_list)\n- `data`: The input to send (text, commands, or escape sequences)\n\nCommon escape sequences:\n- Enter/newline: \"\\n\" or \"\\r\"\n- Ctrl+C (interrupt): \"\\x03\"\n- Ctrl+D (EOF): \"\\x04\"\n- Ctrl+Z (suspend): \"\\x1a\"\n- Tab: \"\\t\"\n- Arrow Up: \"\\x1b[A\"\n- Arrow Down: \"\\x1b[B\"\n- Arrow Right: \"\\x1b[C\"\n- Arrow Left: \"\\x1b[D\"\n\nReturns success or error message.\n\nExamples:\n- Send a command: data=\"ls -la\\n\"\n- Interrupt a process: data=\"\\x03\"\n- Answer a prompt: data=\"yes\\n\"\n","parameters":{"required":["id","data"],"type":"object","properties":{"id":{"type":"string"},"data":{"type":"string"}}}},{"name":"pty_read","description":"Reads output from a PTY session's buffer.\n\nThe PTY maintains a rolling buffer of output lines. Use offset and limit to paginate through the output, similar to reading a file.\n\nUsage:\n- `id`: The PTY session ID (from pty_spawn or pty_list)\n- `offset`: Line number to start reading from (0-based, defaults to 0)\n- `limit`: Number of lines to read (defaults to 500)\n- `pattern`: Regex pattern to filter lines (optional)\n- `ignoreCase`: Case-insensitive pattern matching (default: false)\n\nReturns:\n- Numbered lines of output (similar to cat -n format)\n- Total line count in the buffer\n- Indicator if more lines are available\n\nThe buffer stores up to PTY_MAX_BUFFER_LINES (default: 50000) lines. Older lines are discarded when the limit is reached.\n\nPattern Filtering:\n- When `pattern` is set, lines are FILTERED FIRST using the regex, then offset/limit apply to the MATCHES\n- Original line numbers are preserved so you can see where matches occurred in the buffer\n- Supports full regex syntax (e.g., \"error\", \"ERROR|WARN\", \"failed.*connection\", etc.)\n- If the pattern is invalid, an error message is returned explaining the issue\n- If no lines match the pattern, a clear message indicates zero matches\n\nTips:\n- To see the latest output, use a high offset or omit offset to read from the start\n- To tail recent output, calculate offset as (totalLines - N) where N is how many recent lines you want\n- Lines longer than 2000 characters are truncated\n- Empty output may mean the process hasn't produced output yet\n\nExamples:\n- Read first 100 lines: offset=0, limit=100\n- Read lines 500-600: offset=500, limit=100\n- Read all available: omit both parameters\n- Find errors: pattern=\"error\", ignoreCase=true\n- Find specific log levels: pattern=\"ERROR|WARN|FATAL\"\n- First 10 matches only: pattern=\"error\", limit=10\n","parameters":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"offset":{"type":"number"},"limit":{"type":"number"},"pattern":{"type":"string"},"ignoreCase":{"type":"boolean"}}}},{"name":"pty_list","description":"Lists all PTY sessions (active and exited).\n\nUse this tool to:\n- See all running and exited PTY sessions\n- Get session IDs for use with other pty_* tools\n- Check the status and output line count of each session\n- Monitor which processes are still running\n\nReturns for each session:\n- `id`: Unique identifier for use with other tools\n- `title`: Human-readable name\n- `command`: The command that was executed\n- `status`: Current status (running, exited, killed)\n- `exitCode`: Exit code (if exited/killed)\n- `pid`: Process ID\n- `lineCount`: Number of lines in the output buffer\n- `createdAt`: When the session was created\n\nTips:\n- Use the session ID with pty_read, pty_write, or pty_kill\n- Sessions remain in the list after exit until explicitly cleaned up with pty_kill\n- This allows you to compare output from multiple sessions\n","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"pty_kill","description":"Terminates a PTY session and optionally cleans up its buffer.\n\nUse this tool to:\n- Stop a running process (sends SIGTERM)\n- Clean up an exited session to free memory\n- Remove a session from the list\n\nUsage:\n- `id`: The PTY session ID (from pty_spawn or pty_list)\n- `cleanup`: If true, removes the session and frees the buffer (default: false)\n\nBehavior:\n- If the session is running, it will be killed (status becomes \"killed\")\n- If cleanup=false (default), the session remains in the list with its output buffer intact\n- If cleanup=true, the session is removed entirely and the buffer is freed\n- Keeping sessions without cleanup allows you to compare logs between runs\n\nTips:\n- Use cleanup=false if you might want to read the output later\n- Use cleanup=true when you're done with the session entirely\n- To send Ctrl+C instead of killing, use pty_write with data=\"\\x03\"\n\nExamples:\n- Kill but keep logs: cleanup=false (or omit)\n- Kill and remove: cleanup=true\n","parameters":{"required":["id"],"type":"object","properties":{"id":{"type":"string"},"cleanup":{"type":"boolean"}}}},{"name":"lsp_goto_definition","description":"Jump to symbol definition. Find WHERE something is defined.","parameters":{"required":["filePath","line","character"],"type":"object","properties":{"filePath":{"type":"string"},"line":{"type":"number"},"character":{"type":"number"}}}},{"name":"lsp_find_references","description":"Find ALL usages/references of a symbol across the entire workspace.","parameters":{"required":["filePath","line","character"],"type":"object","properties":{"filePath":{"type":"string"},"line":{"type":"number"},"character":{"type":"number"},"includeDeclaration":{"type":"boolean"}}}},{"name":"lsp_symbols","description":"Get symbols from file (document) or search across workspace. Use scope='document' for file outline, scope='workspace' for project-wide symbol search.","parameters":{"required":["filePath","scope"],"type":"object","properties":{"filePath":{"type":"string"},"scope":{"type":"string","enum":["document","workspace"],"description":"Allowed: document, workspace"},"query":{"type":"string"},"limit":{"type":"number"}}}},{"name":"lsp_diagnostics","description":"Get errors, warnings, hints from language server BEFORE running build.","parameters":{"required":["filePath"],"type":"object","properties":{"filePath":{"type":"string"},"severity":{"type":"string","enum":["error","warning","information","hint","all"],"description":"Allowed: error, warning, information, hint, all"}}}},{"name":"lsp_prepare_rename","description":"Check if rename is valid. Use BEFORE lsp_rename.","parameters":{"required":["filePath","line","character"],"type":"object","properties":{"filePath":{"type":"string"},"line":{"type":"number"},"character":{"type":"number"}}}},{"name":"lsp_rename","description":"Rename symbol across entire workspace. APPLIES changes to all files.","parameters":{"required":["filePath","line","character","newName"],"type":"object","properties":{"filePath":{"type":"string"},"line":{"type":"number"},"character":{"type":"number"},"newName":{"type":"string"}}}},{"name":"ast_grep_search","description":"Search code patterns across filesystem using AST-aware matching. Supports 25 languages. Use meta-variables: $VAR (single node), $$$ (multiple nodes). IMPORTANT: Patterns must be complete AST nodes (valid code). For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'. Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'","parameters":{"required":["pattern","lang"],"type":"object","properties":{"pattern":{"type":"string"},"lang":{"type":"string","enum":["bash","c","cpp","csharp","css","elixir","go","haskell","html","java","javascript","json","kotlin","lua","nix","php","python","ruby","rust","scala","solidity","swift","typescript","tsx","yaml"]},"paths":{"type":"array","items":{"type":"string"}},"globs":{"type":"array","items":{"type":"string"}},"context":{"type":"number"}}}},{"name":"ast_grep_replace","description":"Replace code patterns across filesystem with AST-aware rewriting. Dry-run by default. Use meta-variables in rewrite to preserve matched content. Example: pattern='console.log($MSG)' rewrite='logger.info($MSG)'","parameters":{"required":["pattern","rewrite","lang"],"type":"object","properties":{"pattern":{"type":"string"},"rewrite":{"type":"string"},"lang":{"type":"string","enum":["bash","c","cpp","csharp","css","elixir","go","haskell","html","java","javascript","json","kotlin","lua","nix","php","python","ruby","rust","scala","solidity","swift","typescript","tsx","yaml"]},"paths":{"type":"array","items":{"type":"string"}},"globs":{"type":"array","items":{"type":"string"}},"dryRun":{"type":"boolean"}}}},{"name":"session_list","description":"List all OpenCode sessions with optional filtering.\n\nReturns a list of available session IDs with metadata including message count, date range, and agents used.\n\nArguments:\n- limit (optional): Maximum number of sessions to return\n- from_date (optional): Filter sessions from this date (ISO 8601 format)\n- to_date (optional): Filter sessions until this date (ISO 8601 format)\n\nExample output:\n| Session ID | Messages | First | Last | Agents |\n|------------|----------|-------|------|--------|\n| ses_abc123 | 45 | 2025-12-20 | 2025-12-24 | build, oracle |\n| ses_def456 | 12 | 2025-12-19 | 2025-12-19 | build |","parameters":{"type":"object","properties":{"limit":{"type":"number"},"from_date":{"type":"string"},"to_date":{"type":"string"},"project_path":{"type":"string"}}}},{"name":"session_read","description":"Read messages and history from an OpenCode session.\n\nReturns a formatted view of session messages with role, timestamp, and content. Optionally includes todos and transcript data.\n\nArguments:\n- session_id (required): Session ID to read\n- include_todos (optional): Include todo list if available (default: false)\n- include_transcript (optional): Include transcript log if available (default: false)\n- limit (optional): Maximum number of messages to return (default: all)\n\nExample output:\nSession: ses_abc123\nMessages: 45\nDate Range: 2025-12-20 to 2025-12-24\n\n[Message 1] user (2025-12-20 10:30:00)\nHello, can you help me with...\n\n[Message 2] assistant (2025-12-20 10:30:15)\nOf course! Let me help you with...","parameters":{"required":["session_id"],"type":"object","properties":{"session_id":{"type":"string"},"include_todos":{"type":"boolean"},"include_transcript":{"type":"boolean"},"limit":{"type":"number"}}}},{"name":"session_search","description":"Search for content within OpenCode session messages.\n\nPerforms full-text search across session messages and returns matching excerpts with context.\n\nArguments:\n- query (required): Search query string\n- session_id (optional): Search within specific session only (default: all sessions)\n- case_sensitive (optional): Case-sensitive search (default: false)\n- limit (optional): Maximum number of results to return (default: 20)\n\nExample output:\nFound 3 matches across 2 sessions:\n\n[ses_abc123] Message msg_001 (user)\n...implement the **session manager** tool...\n\n[ses_abc123] Message msg_005 (assistant)\n...I'll create a **session manager** with full search...\n\n[ses_def456] Message msg_012 (user)\n...use the **session manager** to find...","parameters":{"required":["query"],"type":"object","properties":{"query":{"type":"string"},"session_id":{"type":"string"},"case_sensitive":{"type":"boolean"},"limit":{"type":"number"}}}},{"name":"session_info","description":"Get metadata and statistics about an OpenCode session.\n\nReturns detailed information about a session including message count, date range, agents used, and available data sources.\n\nArguments:\n- session_id (required): Session ID to inspect\n\nExample output:\nSession ID: ses_abc123\nMessages: 45\nDate Range: 2025-12-20 10:30:00 to 2025-12-24 15:45:30\nDuration: 4 days, 5 hours\nAgents Used: build, oracle, librarian\nHas Todos: Yes (12 items, 8 completed)\nHas Transcript: Yes (234 entries)","parameters":{"required":["session_id"],"type":"object","properties":{"session_id":{"type":"string"}}}},{"name":"background_output","description":"Get output from background task. Use full_session=true to fetch session messages with filters. System notifies on completion, so block=true rarely needed.","parameters":{"required":["task_id"],"type":"object","properties":{"task_id":{"type":"string"},"block":{"type":"boolean"},"timeout":{"type":"number"},"full_session":{"type":"boolean"},"include_thinking":{"type":"boolean"},"message_limit":{"type":"number"},"since_message_id":{"type":"string"},"include_tool_results":{"type":"boolean"},"thinking_max_chars":{"type":"number"}}}},{"name":"background_cancel","description":"Cancel running background task(s). Use all=true to cancel ALL before final answer.","parameters":{"type":"object","properties":{"taskId":{"type":"string"},"all":{"type":"boolean"}}}},{"name":"look_at","description":"Analyze media files (PDFs, images, diagrams) that require interpretation beyond raw text. Extracts specific information or summaries from documents, describes visual content. Use when you need analyzed/extracted data rather than literal file contents.","parameters":{"required":["goal"],"type":"object","properties":{"file_path":{"type":"string"},"image_data":{"type":"string"},"goal":{"type":"string"}}}},{"name":"skill_mcp","description":"Invoke MCP server operations from skill-embedded MCPs. Requires mcp_name plus exactly one of: tool_name, resource_name, or prompt_name.","parameters":{"required":["mcp_name"],"type":"object","properties":{"mcp_name":{"type":"string"},"tool_name":{"type":"string"},"resource_name":{"type":"string"},"prompt_name":{"type":"string"},"arguments":{"type":"object","description":"Accepts: string | object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]},"grep":{"type":"string"}}}},{"name":"slashcommand","description":"Load a skill or execute a command to get detailed instructions for a specific task.\n\nSkills and commands provide specialized knowledge and step-by-step guidance.\nUse this when a task matches an available skill's or command's description.\n\n**How to use:**\n- Call with command name only: command='publish'\n- Call with command and arguments: command='publish' user_message='patch'\n- The tool will return detailed instructions for the command with your arguments substituted.\n\n<available_skills>\n- /init-deep: (builtin) Initialize hierarchical AGENTS.md knowledge base (builtin)\n- /ralph-loop: (builtin) Start self-referential development loop until completion (builtin)\n- /ulw-loop: (builtin) Start ultrawork loop - continues until completion with ultrawork mode (builtin)\n- /cancel-ralph: (builtin) Cancel active Ralph Loop (builtin)\n- /refactor: (builtin) Intelligent refactoring command with LSP, AST-grep, architecture analysis, codemap, and TDD verification. (builtin)\n- /start-work: (builtin) Start Sisyphus work session from Prometheus plan (builtin)\n- /stop-continuation: (builtin) Stop all continuation mechanisms (ralph loop, todo continuation, boulder) for this session (builtin)\n- /handoff: (builtin) Create a detailed context summary for continuing work in a new session (builtin)\n- /playwright: (opencode - Skill) MUST USE for any browser-related tasks. Browser automation via Playwright MCP - verification, browsing, information gathering, web scraping, testing, screenshots, and all browser interactions. (builtin)\n- /frontend-ui-ux: (opencode - Skill) Designer-turned-developer who crafts stunning UI/UX even without design mockups (builtin)\n- /git-master: (opencode - Skill) MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with task(category='quick', load_skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'. (builtin)\n- /dev-browser: (opencode - Skill) Browser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include 'go to [url]', 'click on', 'fill out the form', 'take a screenshot', 'scrape', 'automate', 'test the website', 'log into', or any browser interaction request. (builtin)\n- /vercel-react-best-practices: (opencode - Skill) React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements. (opencode)\n- /ui-ux-pro-max: (opencode - Skill) UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 9 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn/ui MCP for component search and examples. (opencode)\n- /web-interface-guidelines <file-or-pattern>: (opencode - Skill) Review UI code for Vercel Web Interface Guidelines compliance (opencode)\n- /docx: (opencode - Skill) Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks (opencode)\n</available_skills>","parameters":{"required":["command"],"type":"object","properties":{"command":{"type":"string"},"user_message":{"type":"string"}}}},{"name":"interactive_bash","description":"WARNING: This is TMUX ONLY. Pass tmux subcommands directly (without 'tmux' prefix).\n\nExamples: new-session -d -s omo-dev, send-keys -t omo-dev \"vim\" Enter\n\nFor TUI apps needing ongoing interaction (vim, htop, pudb). One-shot commands → use Bash with &.","parameters":{"required":["tmux_command"],"type":"object","properties":{"tmux_command":{"type":"string"}}}},{"name":"distill","description":"Use this tool to distill relevant findings from a selection of raw tool outputs into preserved knowledge, in order to denoise key bits and parts of context.\n\nTHE PRUNABLE TOOLS LIST\nA <prunable-tools> will show in context when outputs are available for distillation (you don't need to look for it). Each entry follows the format `ID: tool, parameter (~token usage)` (e.g., `20: read, /path/to/file.ts (~1500 tokens)`). You MUST select outputs by their numeric ID. THESE ARE YOUR ONLY VALID TARGETS.\n\nTHE PHILOSOPHY OF DISTILLATION\n`distill` is your favored instrument for transforming raw tool outputs into preserved knowledge. This is not mere summarization; it is high-fidelity extraction that makes the original output obsolete.\n\nYour distillation must be COMPLETE. Capture function signatures, type definitions, business logic, constraints, configuration values... EVERYTHING essential. Think of it as creating a high signal technical substitute so faithful that re-fetching the original would yield no additional value. Be thorough; be comprehensive; leave no ambiguity, ensure that your distillation stands alone, and is designed for easy retrieval and comprehension.\n\nAIM FOR IMPACT. Distillation is most powerful when applied to outputs that contain signal buried in noise. A single line requires no distillation; a hundred lines of API documentation do. Make sure the distillation is meaningful.\n\nTHE WAYS OF DISTILL\n`distill` when you have extracted the essence from tool outputs and the raw form has served its purpose.\nHere are some examples:\nEXPLORATION: You've read extensively and grasp the architecture. The original file contents are no longer needed; your understanding, synthesized, is sufficient.\nPRESERVATION: Valuable technical details (signatures, logic, constraints) coexist with noise. Preserve the former; discard the latter.\n\nNot everything should be distilled. Prefer keeping raw outputs when:\nPRECISION MATTERS: You will edit the file, grep for exact strings, or need line-accurate references. Distillation sacrifices precision for essence.\nUNCERTAINTY REMAINS: If you might need to re-examine the original, defer. Distillation is irreversible; be certain before you commit.\n\nBefore distilling, ask yourself: _\"Will I need the raw output for upcoming work?\"_ If you plan to edit a file you just read, keep it intact. Distillation is for completed exploration, not active work.\n\nTHE FORMAT OF DISTILL\n`targets`: Array of objects, each containing:\n`id`: Numeric ID (as string) from the `<prunable-tools>` list\n`distillation`: Complete technical substitute for that tool output\n","parameters":{"required":["targets"],"type":"object","properties":{"targets":{"type":"array","items":{"required":["id","distillation"],"type":"object","properties":{"id":{"type":"string"},"distillation":{"type":"string"}}}}}}},{"name":"compress","description":"Use this tool to collapse a contiguous range of conversation into a preserved summary.\n\nTHE PHILOSOPHY OF COMPRESS\n`compress` transforms verbose conversation sequences into dense, high-fidelity summaries. This is not cleanup - it is crystallization. Your summary becomes the authoritative record of what transpired.\n\nThink of compression as phase transitions: raw exploration becomes refined understanding. The original context served its purpose; your summary now carries that understanding forward.\n\nTHE SUMMARY\nYour summary must be EXHAUSTIVE. Capture file paths, function signatures, decisions made, constraints discovered, key findings... EVERYTHING that maintains context integrity. This is not a brief note - it is an authoritative record so faithful that the original conversation adds no value.\n\nYet be LEAN. Strip away the noise: failed attempts that led nowhere, verbose tool outputs, back-and-forth exploration. What remains should be pure signal - golden nuggets of detail that preserve full understanding with zero ambiguity.\n\nTHE WAYS OF COMPRESS\n`compress` when a chapter closes - when a phase of work is truly complete and the raw conversation has served its purpose:\n\nResearch concluded and findings are clear\nImplementation finished and verified\nExploration exhausted and patterns understood\n\nDo NOT compress when:\nYou may need exact code, error messages, or file contents from the range\nWork in that area is still active or may resume\nYou're mid-sprint on related functionality\n\nBefore compressing, ask: _\"Is this chapter closed?\"_ Compression is irreversible. The summary replaces everything in the range.\n\nBOUNDARY MATCHING\nYou specify boundaries by matching unique text strings in the conversation. CRITICAL: In code-centric conversations, strings repeat often. Provide sufficiently unique text to match exactly once. If a match fails (not found or found multiple times), the tool will error - extend your boundary string with more surrounding context in order to make SURE the tool does NOT error.\n\nWHERE TO PICK STRINGS FROM (important for reliable matching):\n\n- Your own assistant text responses (MOST RELIABLE - always stored verbatim)\n- The user's own words in their messages\n- Tool result output text (distinctive substrings within the output)\n- Previous compress summaries\n- Tool input string values (individual values, not whole serialized objects)\n\nWHERE TO NEVER PICK STRINGS FROM:\n\n- `<system-reminder>` tags or any XML wrapper/meta-commentary around messages\n- Injected system instructions (plan mode text, max-steps warnings, mode-switch text, environment info)\n- File/directory listing framing text (e.g. \"Called the Read tool with the following input...\")\n- Strings that span across message or part boundaries\n- Entire serialized JSON objects (key ordering may differ - pick a distinctive substring within instead)\n\nTHE FORMAT OF COMPRESS\n`topic`: Short label (3-5 words) for display - e.g., \"Auth System Exploration\"\n`content`: Object containing:\n`startString`: Unique text string marking the beginning of the range\n`endString`: Unique text string marking the end of the range\n`summary`: Complete technical summary replacing all content in the range\n","parameters":{"required":["topic","content"],"type":"object","properties":{"topic":{"type":"string"},"content":{"required":["startString","endString","summary"],"type":"object","properties":{"startString":{"type":"string"},"endString":{"type":"string"},"summary":{"type":"string"}}}}}},{"name":"prune","description":"Use this tool to remove tool outputs from context entirely. No preservation - pure deletion.\n\nTHE PRUNABLE TOOLS LIST\nA `<prunable-tools>` section surfaces in context showing outputs eligible for removal. Each line reads `ID: tool, parameter (~token usage)` (e.g., `20: read, /path/to/file.ts (~1500 tokens)`). Reference outputs by their numeric ID - these are your ONLY valid targets for pruning.\n\nTHE WAYS OF PRUNE\n`prune` is surgical deletion - eliminating noise (irrelevant or unhelpful outputs), superseded information (older outputs replaced by newer data), or wrong targets (you accessed something that turned out to be irrelevant). Use it to keep your context lean and focused.\n\nBATCH WISELY! Pruning is most effective when consolidated. Don't prune a single tiny output - accumulate several candidates before acting.\n\nDo NOT prune when:\nNEEDED LATER: You plan to edit the file or reference this context for implementation.\nUNCERTAINTY: If you might need to re-examine the original, keep it.\n\nBefore pruning, ask: _\"Is this noise, or will it serve me?\"_ If the latter, keep it. Pruning that forces re-fetching is a net loss.\n\nTHE FORMAT OF PRUNE\n`ids`: Array of numeric IDs (as strings) from the `<prunable-tools>` list\n","parameters":{"required":["ids"],"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}}}}},{"name":"fast-context_fast_context_search","description":"AI-driven semantic code search using Windsurf's Devstral model. Searches a codebase with natural language and returns relevant file paths with line ranges, plus suggested grep keywords for follow-up searches.\nParameter tuning guide:\n- tree_depth: Controls how much directory structure the remote AI sees before searching. If you get a payload/size error, REDUCE this value. If search results are too shallow (missing files in deep subdirectories), INCREASE this value.\n- max_turns: Controls how many search-execute-feedback rounds the remote AI gets. If results are incomplete or the AI didn't find enough files, INCREASE this value. If you want a quick rough answer, use 1.\nResponse includes a [config] line showing actual parameters used — use this to decide adjustments on retry.","parameters":{"required":["query"],"type":"object","properties":{"query":{"description":"Natural language search query (e.g. \"where is auth handled\", \"database connection pool\")","type":"string"},"project_path":{"description":"Absolute path to project root. Empty = current working directory.","type":"string"},"tree_depth":{"description":"Directory tree depth for the initial repo map sent to the remote AI. Default 3. Use 1-2 for huge monorepos (>5000 files) or if you get payload size errors. Use 4-6 for small projects (<200 files) where you want the AI to see deeper structure. Auto falls back to a lower depth if tree output exceeds 250KB.","type":"integer"},"max_turns":{"description":"Number of search rounds. Each round: remote AI generates search commands → local execution → results sent back. Default 3. Use 1 for quick simple lookups. Use 4-5 for complex queries requiring deep tracing across many files. More rounds = better results but slower and uses more API quota.","type":"integer"}}}},{"name":"fast-context_extract_windsurf_key","description":"Extract Windsurf API Key from local installation. Auto-detects OS (macOS/Windows/Linux) and reads the API key from Windsurf's local database. Set the result as WINDSURF_API_KEY env var.","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"context7_resolve-library-id","description":"Resolves a package/product name to a Context7-compatible library ID and returns matching libraries.\n\nYou MUST call this function before 'query-docs' to obtain a valid Context7-compatible library ID UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.\n\nSelection Process:\n1. Analyze the query to understand what library/package the user is looking for\n2. Return the most relevant match based on:\n- Name similarity to the query (exact matches prioritized)\n- Description relevance to the query's intent\n- Documentation coverage (prioritize libraries with higher Code Snippet counts)\n- Source reputation (consider libraries with High or Medium reputation more authoritative)\n- Benchmark Score: Quality indicator (100 is the highest score)\n\nResponse Format:\n- Return the selected library ID in a clearly marked section\n- Provide a brief explanation for why this library was chosen\n- If multiple good matches exist, acknowledge this but proceed with the most relevant one\n- If no good matches exist, clearly state this and suggest query refinements\n\nFor ambiguous queries, request clarification before proceeding with a best-guess match.\n\nIMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best result you have.","parameters":{"required":["query","libraryName"],"type":"object","properties":{"query":{"description":"The user's original question or task. This is used to rank library results by relevance to what the user is trying to accomplish. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query.","type":"string"},"libraryName":{"description":"Library name to search for and retrieve a Context7-compatible library ID.","type":"string"}}}},{"name":"context7_query-docs","description":"Retrieves and queries up-to-date documentation and code examples from Context7 for any programming library or framework.\n\nYou must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool, UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.\n\nIMPORTANT: Do not call this tool more than 3 times per question. If you cannot find what you need after 3 calls, use the best information you have.","parameters":{"required":["libraryId","query"],"type":"object","properties":{"libraryId":{"description":"Exact Context7-compatible library ID (e.g., '/mongodb/docs', '/vercel/next.js', '/supabase/supabase', '/vercel/next.js/v14.3.0-canary.87') retrieved from 'resolve-library-id' or directly from user query in the format '/org/project' or '/org/project/version'.","type":"string"},"query":{"description":"The question or task you need help with. Be specific and include relevant details. Good: 'How to set up authentication with JWT in Express.js' or 'React useEffect cleanup function examples'. Bad: 'auth' or 'hooks'. IMPORTANT: Do not include any sensitive or confidential information such as API keys, passwords, credentials, or personal data in your query.","type":"string"}}}},{"name":"websearch_web_search_exa","description":"Search the web for any topic and get clean, ready-to-use content.\n\nBest for: Finding current information, news, facts, or answering questions about any topic.\nReturns: Clean text content from top search results, ready for LLM use.","parameters":{"required":["query"],"type":"object","properties":{"query":{"description":"Websearch query","type":"string"},"numResults":{"description":"Number of search results to return (must be a number, default: 8)","type":"number"},"livecrawl":{"description":"Live crawl mode - 'fallback': use live crawling as backup if cached content unavailable, 'preferred': prioritize live crawling (default: 'fallback') (Allowed: fallback, preferred)","type":"string","enum":["fallback","preferred"]},"type":{"description":"Search type - 'auto': balanced search (default), 'fast': quick results (Allowed: auto, fast)","type":"string","enum":["auto","fast"]},"contextMaxCharacters":{"description":"Maximum characters for context string optimized for LLMs (must be a number, default: 10000)","type":"number"}}}},{"name":"grep_app_searchGitHub","description":"Find real-world code examples from over a million public GitHub repositories to help answer programming questions.\n\n**IMPORTANT: This tool searches for literal code patterns (like grep), not keywords. Search for actual code that would appear in files:**\n- ✅ Good: 'useState(', 'import React from', 'async function', '(?s)try {.*await'\n- ❌ Bad: 'react tutorial', 'best practices', 'how to use'\n\n**When to use this tool:**\n- When implementing unfamiliar APIs or libraries and need to see real usage patterns\n- When unsure about correct syntax, parameters, or configuration for a specific library\n- When looking for production-ready examples and best practices for implementation\n- When needing to understand how different libraries or frameworks work together\n\n**Perfect for questions like:**\n- \"How do developers handle authentication in Next.js apps?\" → Search: 'getServerSession' with language=['TypeScript', 'TSX']\n- \"What are common React error boundary patterns?\" → Search: 'ErrorBoundary' with language=['TSX']\n- \"Show me real useEffect cleanup examples\" → Search: '(?s)useEffect\\(\\(\\) => {.*removeEventListener' with useRegexp=true\n- \"How do developers handle CORS in Flask applications?\" → Search: 'CORS(' with matchCase=true and language=['Python']\n\nUse regular expressions with useRegexp=true for flexible patterns like '(?s)useState\\(.*loading' to find useState hooks with loading-related variables. Prefix the pattern with '(?s)' to match across multiple lines.\n\nFilter by language, repository, or file path to narrow results.","parameters":{"required":["query"],"type":"object","properties":{"query":{"description":"The literal code pattern to search for (e.g., 'useState(', 'export function'). Use actual code that would appear in files, not keywords or questions.","type":"string"},"matchCase":{"description":"Whether the search should be case sensitive","type":"boolean"},"matchWholeWords":{"description":"Whether to match whole words only","type":"boolean"},"useRegexp":{"description":"Whether to interpret the query as a regular expression","type":"boolean"},"repo":{"description":"Filter by repository.\n            Examples: 'facebook/react', 'microsoft/vscode', 'vercel/ai'.\n            Can match partial names, for example 'vercel/' will find repositories in the vercel org.","type":"string"},"path":{"description":"Filter by file path.\n            Examples: 'src/components/Button.tsx', 'README.md'.\n            Can match partial paths, for example '/route.ts' will find route.ts files at any level.","type":"string"},"language":{"description":"Filter by programming language.\n            Examples: ['TypeScript', 'TSX'], ['JavaScript'], ['Python'], ['Java'], ['C#'], ['Markdown'], ['YAML']","type":"array","items":{"type":"string"}}}}},{"name":"playwright_browser_close","description":"Close the page","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"playwright_browser_resize","description":"Resize the browser window","parameters":{"required":["width","height"],"type":"object","properties":{"width":{"description":"Width of the browser window","type":"number"},"height":{"description":"Height of the browser window","type":"number"}}}},{"name":"playwright_browser_console_messages","description":"Returns all console messages","parameters":{"required":["level"],"type":"object","properties":{"level":{"description":"Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to \"info\". (Allowed: error, warning, info, debug)","type":"string","enum":["error","warning","info","debug"]},"filename":{"description":"Filename to save the console messages to. If not provided, messages are returned as text.","type":"string"}}}},{"name":"playwright_browser_handle_dialog","description":"Handle a dialog","parameters":{"required":["accept"],"type":"object","properties":{"accept":{"description":"Whether to accept the dialog.","type":"boolean"},"promptText":{"description":"The text of the prompt in case of a prompt dialog.","type":"string"}}}},{"name":"playwright_browser_evaluate","description":"Evaluate JavaScript expression on page or element","parameters":{"required":["function"],"type":"object","properties":{"function":{"description":"() => { /* code */ } or (element) => { /* code */ } when element is provided","type":"string"},"element":{"description":"Human-readable element description used to obtain permission to interact with the element","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot","type":"string"}}}},{"name":"playwright_browser_file_upload","description":"Upload one or multiple files","parameters":{"type":"object","properties":{"paths":{"description":"The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.","type":"array","items":{"type":"string"}}}}},{"name":"playwright_browser_fill_form","description":"Fill multiple form fields","parameters":{"required":["fields"],"type":"object","properties":{"fields":{"description":"Fields to fill in","type":"array","items":{"required":["name","type","ref","value"],"type":"object","properties":{"name":{"description":"Human-readable field name","type":"string"},"type":{"description":"Type of the field (Allowed: textbox, checkbox, radio, combobox, slider)","type":"string","enum":["textbox","checkbox","radio","combobox","slider"]},"ref":{"description":"Exact target field reference from the page snapshot","type":"string"},"value":{"description":"Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.","type":"string"}}}}}}},{"name":"playwright_browser_install","description":"Install the browser specified in the config. Call this if you get an error about the browser not being installed.","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"playwright_browser_press_key","description":"Press a key on the keyboard","parameters":{"required":["key"],"type":"object","properties":{"key":{"description":"Name of the key to press or a character to generate, such as `ArrowLeft` or `a`","type":"string"}}}},{"name":"playwright_browser_type","description":"Type text into editable element","parameters":{"required":["ref","text"],"type":"object","properties":{"element":{"description":"Human-readable element description used to obtain permission to interact with the element","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot","type":"string"},"text":{"description":"Text to type into the element","type":"string"},"submit":{"description":"Whether to submit entered text (press Enter after)","type":"boolean"},"slowly":{"description":"Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.","type":"boolean"}}}},{"name":"playwright_browser_navigate","description":"Navigate to a URL","parameters":{"required":["url"],"type":"object","properties":{"url":{"description":"The URL to navigate to","type":"string"}}}},{"name":"playwright_browser_navigate_back","description":"Go back to the previous page in the history","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"playwright_browser_network_requests","description":"Returns all network requests since loading the page","parameters":{"required":["includeStatic"],"type":"object","properties":{"includeStatic":{"description":"Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false.","type":"boolean"},"filename":{"description":"Filename to save the network requests to. If not provided, requests are returned as text.","type":"string"}}}},{"name":"playwright_browser_run_code","description":"Run Playwright code snippet","parameters":{"required":["code"],"type":"object","properties":{"code":{"description":"A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction. For example: `async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }`","type":"string"}}}},{"name":"playwright_browser_take_screenshot","description":"Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.","parameters":{"required":["type"],"type":"object","properties":{"type":{"description":"Image format for the screenshot. Default is png. (Allowed: png, jpeg)","type":"string","enum":["png","jpeg"]},"filename":{"description":"File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified. Prefer relative file names to stay within the output directory.","type":"string"},"element":{"description":"Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.","type":"string"},"fullPage":{"description":"When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.","type":"boolean"}}}},{"name":"playwright_browser_snapshot","description":"Capture accessibility snapshot of the current page, this is better than screenshot","parameters":{"type":"object","properties":{"filename":{"description":"Save snapshot to markdown file instead of returning it in the response.","type":"string"}}}},{"name":"playwright_browser_click","description":"Perform click on a web page","parameters":{"required":["ref"],"type":"object","properties":{"element":{"description":"Human-readable element description used to obtain permission to interact with the element","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot","type":"string"},"doubleClick":{"description":"Whether to perform a double click instead of a single click","type":"boolean"},"button":{"description":"Button to click, defaults to left (Allowed: left, right, middle)","type":"string","enum":["left","right","middle"]},"modifiers":{"description":"Modifier keys to press","type":"array","items":{"type":"string","enum":["Alt","Control","ControlOrMeta","Meta","Shift"],"description":"Allowed: Alt, Control, ControlOrMeta, Meta, Shift"}}}}},{"name":"playwright_browser_drag","description":"Perform drag and drop between two elements","parameters":{"required":["startElement","startRef","endElement","endRef"],"type":"object","properties":{"startElement":{"description":"Human-readable source element description used to obtain the permission to interact with the element","type":"string"},"startRef":{"description":"Exact source element reference from the page snapshot","type":"string"},"endElement":{"description":"Human-readable target element description used to obtain the permission to interact with the element","type":"string"},"endRef":{"description":"Exact target element reference from the page snapshot","type":"string"}}}},{"name":"playwright_browser_hover","description":"Hover over element on page","parameters":{"required":["ref"],"type":"object","properties":{"element":{"description":"Human-readable element description used to obtain permission to interact with the element","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot","type":"string"}}}},{"name":"playwright_browser_select_option","description":"Select an option in a dropdown","parameters":{"required":["ref","values"],"type":"object","properties":{"element":{"description":"Human-readable element description used to obtain permission to interact with the element","type":"string"},"ref":{"description":"Exact target element reference from the page snapshot","type":"string"},"values":{"description":"Array of values to select in the dropdown. This can be a single value or multiple values.","type":"array","items":{"type":"string"}}}}},{"name":"playwright_browser_tabs","description":"List, create, close, or select a browser tab.","parameters":{"required":["action"],"type":"object","properties":{"action":{"description":"Operation to perform (Allowed: list, new, close, select)","type":"string","enum":["list","new","close","select"]},"index":{"description":"Tab index, used for close/select. If omitted for close, current tab is closed.","type":"number"}}}},{"name":"playwright_browser_wait_for","description":"Wait for text to appear or disappear or a specified time to pass","parameters":{"type":"object","properties":{"time":{"description":"The time to wait in seconds","type":"number"},"text":{"description":"The text to wait for","type":"string"},"textGone":{"description":"The text to wait for to disappear","type":"string"}}}},{"name":"mcp-deepwiki_deepwiki_fetch","description":"Fetch a deepwiki.com repo and return Markdown","parameters":{"required":["url"],"type":"object","properties":{"url":{"description":"should be a URL, owner/repo name (e.g. \"vercel/ai\"), a two-word \"owner repo\" form (e.g. \"vercel ai\"), or a single library keyword","type":"string"},"maxDepth":{"description":"Can fetch a single site => maxDepth 0 or multiple/all sites => maxDepth 1","type":"integer"},"mode":{"type":"string","enum":["aggregate","pages"],"description":"Allowed: aggregate, pages"},"verbose":{"type":"boolean"}}}},{"name":"agent-logs_record-agent-log","description":"根据标题和内容生成递增编号的 Markdown 日志文件,并自动维护 .gitignore。","parameters":{"required":["title","content"],"type":"object","properties":{"title":{"description":"工作内容标题 (minLength: 1)","type":"string"},"content":{"description":"工作记录内容(Markdown 格式)","type":"string"}}}},{"name":"agent-logs_list-logs","description":"列出日志目录(AgentLogs)中的所有历史日志记录,返回编号、文件名、标题和创建时间。","parameters":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},{"name":"agent-logs_read-log","description":"根据日志编号或文件名读取指定日志的完整内容。","parameters":{"required":["identifier"],"type":"object","properties":{"identifier":{"type":"string","description":"日志编号(如 1 或 \"1\")或文件名(如 \"0001-任务标题.md\") (Accepts: string | number)"}}}},{"name":"agent-logs_search-logs","description":"**重要提示:当需要查找历史记录时,优先使用此工具进行搜索!**\n\n使用自然语言搜索历史日志记录。此工具支持语义搜索。\n\n## 使用场景\n- 当你需要查找之前做过的相关任务\n- 当你想了解某个功能的实现历史\n- 当你需要回顾之前的解决方案\n- **强烈建议在开始新任务前先搜索历史记录,避免重复工作**\n\n## 查询示例\n- \"查找关于数据库连接的日志\"\n- \"之前做过哪些 API 相关的任务?\"\n- \"修复登录 bug 的记录\"\n- \"用户认证功能的实现过程\"\n\n## 返回格式\n返回格式化搜索结果,包含文件路径和相关代码片段。","parameters":{"required":["query"],"type":"object","properties":{"query":{"description":"自然语言搜索查询 (minLength: 1)","type":"string"}}}},{"name":"firecrawl-mcp_firecrawl_scrape","description":"\nScrape content from a single URL with advanced options. \nThis is the most powerful, fastest and most reliable scraper tool, if available you should always default to using this tool for any web scraping needs.\n\n**Best for:** Single page content extraction, when you know exactly which page contains the information.\n**Not recommended for:** Multiple pages (use batch_scrape), unknown page (use search), structured data (use extract).\n**Common mistakes:** Using scrape for a list of URLs (use batch_scrape instead). If batch scrape doesnt work, just use scrape and call it multiple times.\n**Other Features:** Use 'branding' format to extract brand identity (colors, fonts, typography, spacing, UI components) for design analysis or style replication.\n**Prompt Example:** \"Get the content of the page at https://example.com.\"\n**Usage Example:**\n```json\n{\n  \"name\": \"firecrawl_scrape\",\n  \"arguments\": {\n    \"url\": \"https://example.com\",\n    \"formats\": [\"markdown\"],\n    \"maxAge\": 172800000\n  }\n}\n```\n**Performance:** Add maxAge parameter for 500% faster scrapes using cached data.\n**Returns:** Markdown, HTML, or other formats as specified.\n\n","parameters":{"required":["url"],"type":"object","properties":{"url":{"type":"string","description":"format: uri"},"formats":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"enum":["json"],"type":"string"},"prompt":{"type":"string"},"schema":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},"description":"Accepts: string | object"}},"parsers":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["pdf"]},"maxPages":{"type":"integer"}},"description":"Accepts: string | object"}},"onlyMainContent":{"type":"boolean"},"includeTags":{"type":"array","items":{"type":"string"}},"excludeTags":{"type":"array","items":{"type":"string"}},"waitFor":{"type":"number"},"actions":{"type":"array","items":{"required":["type"],"type":"object","properties":{"type":{"type":"string","enum":["wait","screenshot","scroll","scrape","click","write","press","executeJavascript","generatePDF"],"description":"Allowed: wait, screenshot, scroll, scrape, click, write, press, executeJavascript, generatePDF"},"selector":{"type":"string"},"milliseconds":{"type":"number"},"text":{"type":"string"},"key":{"type":"string"},"direction":{"type":"string","enum":["up","down"],"description":"Allowed: up, down"},"script":{"type":"string"},"fullPage":{"type":"boolean"}}}},"mobile":{"type":"boolean"},"skipTlsVerification":{"type":"boolean"},"removeBase64Images":{"type":"boolean"},"location":{"type":"object","properties":{"country":{"type":"string"},"languages":{"type":"array","items":{"type":"string"}}}},"storeInCache":{"type":"boolean"},"zeroDataRetention":{"type":"boolean"},"maxAge":{"type":"number"},"proxy":{"type":"string","enum":["basic","stealth","auto"],"description":"Allowed: basic, stealth, auto"}}}},{"name":"firecrawl-mcp_firecrawl_map","description":"\nMap a website to discover all indexed URLs on the site.\n\n**Best for:** Discovering URLs on a website before deciding what to scrape; finding specific sections of a website.\n**Not recommended for:** When you already know which specific URL you need (use scrape or batch_scrape); when you need the content of the pages (use scrape after mapping).\n**Common mistakes:** Using crawl to discover URLs instead of map.\n**Prompt Example:** \"List all URLs on example.com.\"\n**Usage Example:**\n```json\n{\n  \"name\": \"firecrawl_map\",\n  \"arguments\": {\n    \"url\": \"https://example.com\"\n  }\n}\n```\n**Returns:** Array of URLs found on the site.\n","parameters":{"required":["url"],"type":"object","properties":{"url":{"type":"string","description":"format: uri"},"search":{"type":"string"},"sitemap":{"type":"string","enum":["include","skip","only"],"description":"Allowed: include, skip, only"},"includeSubdomains":{"type":"boolean"},"limit":{"type":"number"},"ignoreQueryParameters":{"type":"boolean"}}}},{"name":"firecrawl-mcp_firecrawl_search","description":"\nSearch the web and optionally extract content from search results. This is the most powerful web search tool available, and if available you should always default to using this tool for any web search needs.\n\nThe query also supports search operators, that you can use if needed to refine the search:\n| Operator | Functionality | Examples |\n---|-|-|\n| `\"\"` | Non-fuzzy matches a string of text | `\"Firecrawl\"`\n| `-` | Excludes certain keywords or negates other operators | `-bad`, `-site:firecrawl.dev`\n| `site:` | Only returns results from a specified website | `site:firecrawl.dev`\n| `inurl:` | Only returns results that include a word in the URL | `inurl:firecrawl`\n| `allinurl:` | Only returns results that include multiple words in the URL | `allinurl:git firecrawl`\n| `intitle:` | Only returns results that include a word in the title of the page | `intitle:Firecrawl`\n| `allintitle:` | Only returns results that include multiple words in the title of the page | `allintitle:firecrawl playground`\n| `related:` | Only returns results that are related to a specific domain | `related:firecrawl.dev`\n| `imagesize:` | Only returns images with exact dimensions | `imagesize:1920x1080`\n| `larger:` | Only returns images larger than specified dimensions | `larger:1920x1080`\n\n**Best for:** Finding specific information across multiple websites, when you don't know which website has the information; when you need the most relevant content for a query.\n**Not recommended for:** When you need to search the filesystem. When you already know which website to scrape (use scrape); when you need comprehensive coverage of a single website (use map or crawl.\n**Common mistakes:** Using crawl or map for open-ended questions (use search instead).\n**Prompt Example:** \"Find the latest research papers on AI published in 2023.\"\n**Sources:** web, images, news, default to web unless needed images or news.\n**Scrape Options:** Only use scrapeOptions when you think it is absolutely necessary. When you do so default to a lower limit to avoid timeouts, 5 or lower.\n**Optimal Workflow:** Search first using firecrawl_search without formats, then after fetching the results, use the scrape tool to get the content of the relevantpage(s) that you want to scrape\n\n**Usage Example without formats (Preferred):**\n```json\n{\n  \"name\": \"firecrawl_search\",\n  \"arguments\": {\n    \"query\": \"top AI companies\",\n    \"limit\": 5,\n    \"sources\": [\n      \"web\"\n    ]\n  }\n}\n```\n**Usage Example with formats:**\n```json\n{\n  \"name\": \"firecrawl_search\",\n  \"arguments\": {\n    \"query\": \"latest AI research papers 2023\",\n    \"limit\": 5,\n    \"lang\": \"en\",\n    \"country\": \"us\",\n    \"sources\": [\n      \"web\",\n      \"images\",\n      \"news\"\n    ],\n    \"scrapeOptions\": {\n      \"formats\": [\"markdown\"],\n      \"onlyMainContent\": true\n    }\n  }\n}\n```\n**Returns:** Array of search results (with optional scraped content).\n","parameters":{"required":["query"],"type":"object","properties":{"query":{"type":"string","description":"minLength: 1"},"limit":{"type":"number"},"tbs":{"type":"string"},"filter":{"type":"string"},"location":{"type":"string"},"sources":{"type":"array","items":{"required":["type"],"type":"object","properties":{"type":{"type":"string","enum":["web","images","news"],"description":"Allowed: web, images, news"}}}},"scrapeOptions":{"type":"object","properties":{"formats":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"enum":["json"],"type":"string"},"prompt":{"type":"string"},"schema":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},"description":"Accepts: string | object"}},"parsers":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["pdf"]},"maxPages":{"type":"integer"}},"description":"Accepts: string | object"}},"onlyMainContent":{"type":"boolean"},"includeTags":{"type":"array","items":{"type":"string"}},"excludeTags":{"type":"array","items":{"type":"string"}},"waitFor":{"type":"number"},"actions":{"type":"array","items":{"required":["type"],"type":"object","properties":{"type":{"type":"string","enum":["wait","screenshot","scroll","scrape","click","write","press","executeJavascript","generatePDF"],"description":"Allowed: wait, screenshot, scroll, scrape, click, write, press, executeJavascript, generatePDF"},"selector":{"type":"string"},"milliseconds":{"type":"number"},"text":{"type":"string"},"key":{"type":"string"},"direction":{"type":"string","enum":["up","down"],"description":"Allowed: up, down"},"script":{"type":"string"},"fullPage":{"type":"boolean"}}}},"mobile":{"type":"boolean"},"skipTlsVerification":{"type":"boolean"},"removeBase64Images":{"type":"boolean"},"location":{"type":"object","properties":{"country":{"type":"string"},"languages":{"type":"array","items":{"type":"string"}}}},"storeInCache":{"type":"boolean"},"zeroDataRetention":{"type":"boolean"},"maxAge":{"type":"number"},"proxy":{"type":"string","enum":["basic","stealth","auto"],"description":"Allowed: basic, stealth, auto"}}},"enterprise":{"type":"array","items":{"type":"string","enum":["default","anon","zdr"],"description":"Allowed: default, anon, zdr"}}}}},{"name":"firecrawl-mcp_firecrawl_crawl","description":"\n Starts a crawl job on a website and extracts content from all pages.\n \n **Best for:** Extracting content from multiple related pages, when you need comprehensive coverage.\n **Not recommended for:** Extracting content from a single page (use scrape); when token limits are a concern (use map + batch_scrape); when you need fast results (crawling can be slow).\n **Warning:** Crawl responses can be very large and may exceed token limits. Limit the crawl depth and number of pages, or use map + batch_scrape for better control.\n **Common mistakes:** Setting limit or maxDiscoveryDepth too high (causes token overflow) or too low (causes missing pages); using crawl for a single page (use scrape instead). Using a /* wildcard is not recommended.\n **Prompt Example:** \"Get all blog posts from the first two levels of example.com/blog.\"\n **Usage Example:**\n ```json\n {\n   \"name\": \"firecrawl_crawl\",\n   \"arguments\": {\n     \"url\": \"https://example.com/blog/*\",\n     \"maxDiscoveryDepth\": 5,\n     \"limit\": 20,\n     \"allowExternalLinks\": false,\n     \"deduplicateSimilarURLs\": true,\n     \"sitemap\": \"include\"\n   }\n }\n ```\n **Returns:** Operation ID for status checking; use firecrawl_check_crawl_status to check progress.\n \n ","parameters":{"required":["url"],"type":"object","properties":{"url":{"type":"string"},"prompt":{"type":"string"},"excludePaths":{"type":"array","items":{"type":"string"}},"includePaths":{"type":"array","items":{"type":"string"}},"maxDiscoveryDepth":{"type":"number"},"sitemap":{"type":"string","enum":["skip","include","only"],"description":"Allowed: skip, include, only"},"limit":{"type":"number"},"allowExternalLinks":{"type":"boolean"},"allowSubdomains":{"type":"boolean"},"crawlEntireDomain":{"type":"boolean"},"delay":{"type":"number"},"maxConcurrency":{"type":"number"},"webhook":{"required":["url"],"type":"object","properties":{"url":{"type":"string"},"headers":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},"description":"Accepts: string | object"},"deduplicateSimilarURLs":{"type":"boolean"},"ignoreQueryParameters":{"type":"boolean"},"scrapeOptions":{"type":"object","properties":{"formats":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"enum":["json"],"type":"string"},"prompt":{"type":"string"},"schema":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}},"description":"Accepts: string | object"}},"parsers":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["pdf"]},"maxPages":{"type":"integer"}},"description":"Accepts: string | object"}},"onlyMainContent":{"type":"boolean"},"includeTags":{"type":"array","items":{"type":"string"}},"excludeTags":{"type":"array","items":{"type":"string"}},"waitFor":{"type":"number"},"actions":{"type":"array","items":{"required":["type"],"type":"object","properties":{"type":{"type":"string","enum":["wait","screenshot","scroll","scrape","click","write","press","executeJavascript","generatePDF"],"description":"Allowed: wait, screenshot, scroll, scrape, click, write, press, executeJavascript, generatePDF"},"selector":{"type":"string"},"milliseconds":{"type":"number"},"text":{"type":"string"},"key":{"type":"string"},"direction":{"type":"string","enum":["up","down"],"description":"Allowed: up, down"},"script":{"type":"string"},"fullPage":{"type":"boolean"}}}},"mobile":{"type":"boolean"},"skipTlsVerification":{"type":"boolean"},"removeBase64Images":{"type":"boolean"},"location":{"type":"object","properties":{"country":{"type":"string"},"languages":{"type":"array","items":{"type":"string"}}}},"storeInCache":{"type":"boolean"},"zeroDataRetention":{"type":"boolean"},"maxAge":{"type":"number"},"proxy":{"type":"string","enum":["basic","stealth","auto"],"description":"Allowed: basic, stealth, auto"}}}}}},{"name":"firecrawl-mcp_firecrawl_check_crawl_status","description":"\nCheck the status of a crawl job.\n\n**Usage Example:**\n```json\n{\n  \"name\": \"firecrawl_check_crawl_status\",\n  \"arguments\": {\n    \"id\": \"550e8400-e29b-41d4-a716-446655440000\"\n  }\n}\n```\n**Returns:** Status and progress of the crawl job, including results if available.\n","parameters":{"required":["id"],"type":"object","properties":{"id":{"type":"string"}}}},{"name":"firecrawl-mcp_firecrawl_extract","description":"\nExtract structured information from web pages using LLM capabilities. Supports both cloud AI and self-hosted LLM extraction.\n\n**Best for:** Extracting specific structured data like prices, names, details from web pages.\n**Not recommended for:** When you need the full content of a page (use scrape); when you're not looking for specific structured data.\n**Arguments:**\n- urls: Array of URLs to extract information from\n- prompt: Custom prompt for the LLM extraction\n- schema: JSON schema for structured data extraction\n- allowExternalLinks: Allow extraction from external links\n- enableWebSearch: Enable web search for additional context\n- includeSubdomains: Include subdomains in extraction\n**Prompt Example:** \"Extract the product name, price, and description from these product pages.\"\n**Usage Example:**\n```json\n{\n  \"name\": \"firecrawl_extract\",\n  \"arguments\": {\n    \"urls\": [\"https://example.com/page1\", \"https://example.com/page2\"],\n    \"prompt\": \"Extract product information including name, price, and description\",\n    \"schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": { \"type\": \"string\" },\n        \"price\": { \"type\": \"number\" },\n        \"description\": { \"type\": \"string\" }\n      },\n      \"required\": [\"name\", \"price\"]\n    },\n    \"allowExternalLinks\": false,\n    \"enableWebSearch\": false,\n    \"includeSubdomains\": false\n  }\n}\n```\n**Returns:** Extracted structured data as defined by your schema.\n","parameters":{"required":["urls"],"type":"object","properties":{"urls":{"type":"array","items":{"type":"string"}},"prompt":{"type":"string"},"schema":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]},"allowExternalLinks":{"type":"boolean"},"enableWebSearch":{"type":"boolean"},"includeSubdomains":{"type":"boolean"}}}},{"name":"firecrawl-mcp_firecrawl_agent","description":"\nAutonomous web data gathering agent. Describe what data you want, and the agent searches, navigates, and extracts it from anywhere on the web.\n\n**Best for:** Complex data gathering tasks where you don't know the exact URLs; research tasks requiring multiple sources; finding data in hard-to-reach places.\n**Not recommended for:** Simple single-page scraping (use scrape); when you already know the exact URL (use scrape or extract).\n**Key advantages over extract:**\n- No URLs required - just describe what you need\n- Autonomously searches and navigates the web\n- Faster and more cost-effective for complex tasks\n- Higher reliability for varied queries\n\n**Arguments:**\n- prompt: Natural language description of the data you want (required, max 10,000 characters)\n- urls: Optional array of URLs to focus the agent on specific pages\n- schema: Optional JSON schema for structured output\n\n**Prompt Example:** \"Find the founders of Firecrawl and their backgrounds\"\n**Usage Example (no URLs):**\n```json\n{\n  \"name\": \"firecrawl_agent\",\n  \"arguments\": {\n    \"prompt\": \"Find the top 5 AI startups founded in 2024 and their funding amounts\",\n    \"schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"startups\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"name\": { \"type\": \"string\" },\n              \"funding\": { \"type\": \"string\" },\n              \"founded\": { \"type\": \"string\" }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n**Usage Example (with URLs):**\n```json\n{\n  \"name\": \"firecrawl_agent\",\n  \"arguments\": {\n    \"urls\": [\"https://docs.firecrawl.dev\", \"https://firecrawl.dev/pricing\"],\n    \"prompt\": \"Compare the features and pricing information from these pages\"\n  }\n}\n```\n**Returns:** Extracted data matching your prompt/schema, plus credits used.\n","parameters":{"required":["prompt"],"type":"object","properties":{"prompt":{"type":"string","description":"minLength: 1"},"urls":{"type":"array","items":{"type":"string","description":"format: uri"}},"schema":{"type":"object","properties":{"_placeholder":{"type":"boolean","description":"Placeholder. Always pass true."}},"required":["_placeholder"]}}}},{"name":"firecrawl-mcp_firecrawl_agent_status","description":"\nCheck the status of an agent job.\n\n**Usage Example:**\n```json\n{\n  \"name\": \"firecrawl_agent_status\",\n  \"arguments\": {\n    \"id\": \"550e8400-e29b-41d4-a716-446655440000\"\n  }\n}\n```\n**Possible statuses:**\n- processing: Agent is still working\n- completed: Extraction finished successfully\n- failed: An error occurred\n\n**Returns:** Status, progress, and results (if completed) of the agent job.\n","parameters":{"required":["id"],"type":"object","properties":{"id":{"type":"string"}}}}]}]

@Tarquinen
Copy link
Collaborator

Not sure what those errors are... Did you confirm everything works without DCP? Do you have any other plugins other than the auth plugin? Any idea on how I can replicate? Mine works fine

image

@Lynricsy
Copy link

I think so, because this error only occurs after using the prune tool, and after turning off DCP and retrying, the request works normally

Not sure what those errors are... Did you confirm everything works without DCP? Do you have any other plugins other than the auth plugin? Any idea on how I can replicate? Mine works fine

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants