Add tool-schemas/ — JSON input_schema for 35 builtin tools (refs #22)#24
Add tool-schemas/ — JSON input_schema for 35 builtin tools (refs #22)#24YiRaaaan wants to merge 9 commits into
Conversation
📝 WalkthroughWalkthroughAdds 35 draft-2020-12 JSON Schema documents under tool-schemas/ plus a README documenting provenance, capture method, serialization/naming, grouping, gating, and the explicit exclusion of StructuredOutput schemas. ChangesTool Schema Definitions
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tool-schemas/README.md`:
- Line 3: Update the README text that reads "JSON `input_schema` for Claude
Code's builtin tools, captured verbatim from" to use the standard spelling
"built-in" (i.e., "JSON `input_schema` for Claude Code's built-in tools,
captured verbatim from"); search for other occurrences of "builtin" in the
README and replace them with "built-in" to keep user-facing docs consistent and
clear.
- Around line 31-33: Update the README entry that references
`tool-description-<tool>.md` so the hyperlink points directly to the actual file
pattern location instead of the parent directory; replace the link target
`../system-prompts/` with the precise path or pattern that resolves to
`system-prompts/tool-description-<tool>.md` (or a glob that navigates directly
to those files) and ensure the link label still mentions
`tool-description-<tool>.md` to avoid misleading readers.
In `@tool-schemas/task-stop.json`:
- Around line 9-11: The schemas are inconsistent: task-stop.json and
task-output.json use "task_id" while task-get.json and task-update.json use
"taskId"; pick one canonical field name (preferably "taskId" to match existing
camelCase usage) and update the schemas so all operations use the same property;
specifically change the "task_id" property in task-stop.json and
task-output.json to "taskId" (update description/type entries if necessary) and
run schema validation to ensure no other references expect the old name.
- Around line 1-15: Add a required constraint to the JSON schema so payloads
must include task_id; specifically, update the root schema (containing
properties "shell_id" and "task_id") to include a "required" array with
"task_id" (e.g., "required": ["task_id"]), leaving "shell_id"
optional/deprecated as-is so backward-compatibility is preserved but invalid
payloads without task_id are rejected.
In `@tool-schemas/workflow.json`:
- Around line 1-36: The schema currently allows calls with none of the workflow
specifiers set (no script, scriptPath or name); update the JSON Schema to
require exactly one of those properties by adding a top-level oneOf (or anyOf
with an additional dependent requirement) that lists objects with "required":
["script"], "required": ["scriptPath"], and "required": ["name"] (or use oneOf
to enforce exclusivity), referencing the existing property names "script",
"scriptPath", and "name" so validation fails unless one of those is provided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e63ba804-aad9-4485-ae6c-59e94b9b3553
📒 Files selected for processing (36)
tool-schemas/README.mdtool-schemas/agent.jsontool-schemas/ask-user-question.jsontool-schemas/bash.jsontool-schemas/cron-create.jsontool-schemas/cron-delete.jsontool-schemas/cron-list.jsontool-schemas/edit.jsontool-schemas/enter-plan-mode.jsontool-schemas/enter-worktree.jsontool-schemas/exit-plan-mode.jsontool-schemas/exit-worktree.jsontool-schemas/glob.jsontool-schemas/grep.jsontool-schemas/lsp.jsontool-schemas/monitor.jsontool-schemas/notebook-edit.jsontool-schemas/push-notification.jsontool-schemas/read.jsontool-schemas/remote-trigger.jsontool-schemas/schedule-wakeup.jsontool-schemas/send-message.jsontool-schemas/send-user-message.jsontool-schemas/skill.jsontool-schemas/task-create.jsontool-schemas/task-get.jsontool-schemas/task-list.jsontool-schemas/task-output.jsontool-schemas/task-stop.jsontool-schemas/task-update.jsontool-schemas/team-create.jsontool-schemas/team-delete.jsontool-schemas/web-fetch.jsontool-schemas/web-search.jsontool-schemas/workflow.jsontool-schemas/write.json
|
Quick note on intent for future readers in response to the @coderabbitai review: The files under So 4 of the 5 suggestions land on the wrong side of that line:
Replied inline on each with the specific reason. Marking the review-requested-changes as intentional design rather than oversight. |
|
Tip For best results, initiate chat on the files or code changes.
The verbatim-capture constraint is a strong one and my suggestions violated it on all four counts. To summarise the corrections back:
I'll add learnings so this doesn't recur on future reviews of this repo. 🐇 ✦ ✏️ Learnings added
|
Per CodeRabbit suggestion on Piebald-AI#24: previous form labeled the link as a specific file pattern (tool-description-<tool>.md) but pointed at the parent directory, which could mislead readers expecting to land on one file. Make both the label and the target the directory, and keep the glob as inline code.
|
@YiRaaaan Thank you, this looks great!
Yes please, that would be great, thank you.
We appreciate the offer! However, it would be inconvenient to have to rely on external contributions for something that's dependent on a product released as frequently as Claude Code, so we'd need to do that ourselves. |
|
Thanks for the clear answers!
Let me know if you'd like anything else changed here before merging. |
|
Thank you for #25. I don't see any scripts or anything that would generate these JSON files—did you possibly forget to commit them? |
…o per-tool schemas Mirrors the existing prompt pipeline (`prompts-X.X.X.json` → `updatePrompts.js` → `system-prompts/*.md`): the script takes one or more captured POST /v1/messages request bodies, merges by tool name (first-seen wins), and writes each `tools[i].input_schema` to `tool-schemas/<kebab>.json`. The capture step itself is delegated to whatever proxy the maintainer prefers (mitmproxy, a small reverse proxy, etc.). The header doc on the script explains the four `claude -p` runs that produce the current 35-tool set (default, --agent-teams, local-agent entrypoint, brief). Why not bundle a Node proxy: Anthropic's OAuth bearer tokens appear bound to the TLS/connection profile of the proxy that established them — a freshly-started Node proxy gets `403 Request not allowed` from upstream even with byte-identical headers to a working one. So the script does the part that's stable (splitting JSON) and leaves the capture to a proven proxy. mitmproxy in reverse mode (one line) or any equivalent works. Verified end-to-end: feeding the four captured request bodies through the script produces 34/35 byte-identical files to what Piebald-AI#24 ships; the one diff (`agent.json` gained a `mode` enum) reflects a real upstream change in Claude Code since Piebald-AI#24 was captured. Skipped tools: - StructuredOutput — caller-supplied schema per workflow, no stable value (see tool-schemas/README.md).
Bundles a tiny HTTP intercept server with the four-run capture loop so
that, on any machine with `claude -p` installed, running
node tools/captureToolSchemas.mjs
regenerates the full `tool-schemas/` directory in ~15s, with no external
proxy, no API key, no Anthropic account, no upstream call at all.
How it works:
1. Server listens on 127.0.0.1:4099 (configurable via CAPTURE_PORT).
2. Spawns `claude -p "ok"` four times, each with the env that surfaces
a different tool set (default, --agent-teams, local-agent
entrypoint, brief / KAIROS).
3. On each spawn, claude POSTs to /v1/messages through ANTHROPIC_BASE_URL
pointed at us. The server pulls `tools[]` out of the request body
and replies with a stub 403 — claude exits immediately without
retrying, and we move on to the next env.
4. After all four runs, the unioned `tools[]` (first-seen wins per
name) is sorted by tool name, each `input_schema` is recursively
lexically key-sorted for byte-stable diffs, StructuredOutput is
dropped (its schema is caller-supplied), and one file per tool is
written under tool-schemas/.
Why a stub 403 instead of forwarding to api.anthropic.com:
Anthropic's OAuth bearer tokens are bound to the TLS / connection
profile of the proxy that established them. A fresh Node proxy
forwarding identical headers gets `403 Request not allowed`
consistently. So we don't forward — we capture the request body
(which is what we actually want) and stub a fast-exit error
response. Claude still emits the full tools[] before we reply.
Verified end-to-end on Claude Code v2.1.168: 33/35 output files are
byte-identical to PR Piebald-AI#24's committed schemas; the 2 deltas (agent.json,
…) reflect real-world wire changes since Piebald-AI#24 was captured. Two
back-to-back runs produce byte-identical output.
Complements Piebald-AI#24, which adds the `tool-schemas/` directory. Per the PR discussion on Piebald-AI#24, the README listing should surface these alongside the existing prompt categories. Behavior: - `getToolSchemas()` scans `tool-schemas/*.json` alphabetically; returns empty when the directory is absent, so the patch is a no-op on repos that haven't merged the schemas yet (safe to land in either order). - `schemaFileToDisplayName()` does kebab→PascalCase with one explicit override (`lsp` → `LSP`). Add more overrides as needed. - A new `### Tool Schemas` section is appended after the existing Builtin Tool Descriptions section, with a one-line intro and one bullet per file linking to `./tool-schemas/<file>.json`. No changes to existing categories, prompt extraction, token counting, or any other behavior. Only one new code path, guarded by directory existence.
Bundles a tiny HTTP intercept server with the four-run capture loop so
that, on any machine with `claude -p` installed, running
node tools/captureToolSchemas.mjs
regenerates the full `tool-schemas/` directory in ~15s, with no external
proxy, no API key, no Anthropic account, no upstream call at all.
How it works:
1. Server listens on 127.0.0.1:4099 (configurable via CAPTURE_PORT).
2. Spawns `claude -p "ok"` four times, each with the env that surfaces
a different tool set (default, --agent-teams, local-agent
entrypoint, brief / KAIROS).
3. On each spawn, claude POSTs to /v1/messages through ANTHROPIC_BASE_URL
pointed at us. The server pulls `tools[]` out of the request body
and replies with a stub 403 — claude exits immediately without
retrying, and we move on to the next env.
4. After all four runs, the unioned `tools[]` (first-seen wins per
name) is sorted by tool name, each `input_schema` is recursively
lexically key-sorted for byte-stable diffs, StructuredOutput is
dropped (its schema is caller-supplied), and one file per tool is
written under tool-schemas/.
Why a stub 403 instead of forwarding to api.anthropic.com:
Anthropic's OAuth bearer tokens are bound to the TLS / connection
profile of the proxy that established them. A fresh Node proxy
forwarding identical headers gets `403 Request not allowed`
consistently. So we don't forward — we capture the request body
(which is what we actually want) and stub a fast-exit error
response. Claude still emits the full tools[] before we reply.
Verified end-to-end on Claude Code v2.1.168: 33/35 output files are
byte-identical to PR Piebald-AI#24's committed schemas; the 2 deltas (agent.json,
…) reflect real-world wire changes since Piebald-AI#24 was captured. Two
back-to-back runs produce byte-identical output.
Seeded from issue Piebald-AI#22. Each file is a standalone JSON Schema document captured verbatim from a real POST /v1/messages request, via a local reverse proxy (flare). Notes for reviewers: - Schemas come from the API payload, not from parsing cli.js, so they are independent of bundler/minifier changes and require no addition to tools/updatePrompts.js. - 28 of 29 schemas are byte-identical across v2.1.161 -> v2.1.168 (seven patch releases); only LSP changed (new "query" property for the workspaceSymbol operation). README documents the data point. - Files contain only input_schema; tool-level prose descriptions stay in system-prompts/tool-description-<tool>.md as the single source of truth.
Two follow-up findings from comparing 188+ captures across the main loop and sub-agents (Explore, Workflow): 1. Schema is agent-invariant. Every shared tool name produces the same byte-for-byte input_schema across all callers. Sub-agents differ from the main loop only by subsetting the tool list (e.g. Explore drops write tools for its read-only mode), not by altering schemas. One tool-schemas/<tool>.json per tool is sufficient. 2. StructuredOutput is deliberately omitted. Its input_schema is supplied at call time by the workflow orchestration script that spawned the subagent, not defined by Claude Code. Two unrelated schemas appeared across captures. Including a fixed file would misrepresent the tool.
Move PR-rationale content (LSP diff, 28/29 stability, 188-capture forensics, prose-description churn) out of the directory README — those belong in the PR body, not in long-lived in-tree docs that will go stale. Fix broken issue link (was Piebald-AI/system-prompts, should be Piebald-AI/claude-code-system-prompts). Drop the hardcoded cc_version=2.1.168.fc4 pin to avoid a per-release update treadmill. Compress the StructuredOutput exclusion and the relationship-to-extractor section to one sentence each. Add an offer to rename files to tool-schema-<tool>.json if a closer mirror of system-prompts/ is preferred.
These appear in the API tools[] payload only when Agent Teams is enabled via CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 or --agent-teams (see utils/agentSwarmsEnabled.ts). Captured from a v2.1.168 session with the gate on. README updated to split coverage into 29 default tools + 3 gated ones, and to clearly call out which other gated tools are out of scope (e.g. KAIROS/HISTORY_SNIP features that aren't shipped in the public npm bundle, PowerShell which is Windows-only).
- glob.json, grep.json: surfaced under CLAUDE_CODE_ENTRYPOINT=local-agent. In sub-agent context Claude Code exposes the dedicated search tools instead of having the model shell out via Bash. grep.json fills the gap left by the existing tool-description-grep.md. - send-user-message.json: surfaced under CLAUDE_CODE_BRIEF=1 (the KAIROS-style brief assistant entrypoint). README rewritten as a 4-row 'how to surface' table covering all 35 schemas now in the directory. Build-time-gated tools that DO live in the public native binary (SendUserFile, WebBrowser, Snip) require a server-side GrowthBook entitlement (tengu_kairos) that cannot be flipped from local env vars — left for a follow-up PR.
The 'Source' section linked to https://github.com/YiRaaaan/flare which is private; reviewer click would 404. Just describe the proxy approach without naming or linking the specific implementation.
Per CodeRabbit suggestion on Piebald-AI#24: previous form labeled the link as a specific file pattern (tool-description-<tool>.md) but pointed at the parent directory, which could mislead readers expecting to land on one file. Make both the label and the target the directory, and keep the glob as inline code.
Two schemas changed since the initial capture against v2.1.168:
- agent.json: model enum gained "fable" (Fable 5 family).
- send-message.json: added length constraints — a 200-char maxLength
on the top-level `summary` field and a matching ^[^\n\r]{1,200}$
regex on the same field inside the nested shutdown_request /
status_update message variants.
Regenerated with tools/captureToolSchemas.mjs (PR Piebald-AI#25). No other
schema bytes changed across the four runs.
5f31a02 to
180bbfd
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tool-schemas/README.md (1)
26-26: 💤 Low valueConsider mentioning the JSON Schema draft version.
If the
.jsonfiles include a$schemafield (e.g.,"$schema": "https://json-schema.org/draft/2020-12/schema"), briefly noting the draft version in this line would help readers understand which JSON Schema spec applies—especially if they plan to validate or extend these schemas.📝 Example phrasing
-Each `<tool>.json` is a standalone JSON Schema document — the exact value of +Each `<tool>.json` is a standalone JSON Schema (draft 2020-12) document — the exact value of(Adjust the draft version to match what's actually declared in the files, or skip this suggestion entirely if the files omit
$schema.)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tool-schemas/README.md` at line 26, Update the README sentence to mention the JSON Schema draft/version used by the tool JSON files: check the `.json` files for a `$schema` field (e.g., `"$schema": "https://json-schema.org/draft/2020-12/schema"`) and add a short clause stating that each `<tool>.json` is a standalone JSON Schema document conforming to that draft (or omit if no `$schema` is present); ensure the README line referencing "Each `<tool>.json` is a standalone JSON Schema document" includes this draft/version note so consumers know which JSON Schema spec applies.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tool-schemas/README.md`:
- Line 26: Update the README sentence to mention the JSON Schema draft/version
used by the tool JSON files: check the `.json` files for a `$schema` field
(e.g., `"$schema": "https://json-schema.org/draft/2020-12/schema"`) and add a
short clause stating that each `<tool>.json` is a standalone JSON Schema
document conforming to that draft (or omit if no `$schema` is present); ensure
the README line referencing "Each `<tool>.json` is a standalone JSON Schema
document" includes this draft/version note so consumers know which JSON Schema
spec applies.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 920933ea-440c-4fbd-bdc7-be65bb398f51
📒 Files selected for processing (36)
tool-schemas/README.mdtool-schemas/agent.jsontool-schemas/ask-user-question.jsontool-schemas/bash.jsontool-schemas/cron-create.jsontool-schemas/cron-delete.jsontool-schemas/cron-list.jsontool-schemas/edit.jsontool-schemas/enter-plan-mode.jsontool-schemas/enter-worktree.jsontool-schemas/exit-plan-mode.jsontool-schemas/exit-worktree.jsontool-schemas/glob.jsontool-schemas/grep.jsontool-schemas/lsp.jsontool-schemas/monitor.jsontool-schemas/notebook-edit.jsontool-schemas/push-notification.jsontool-schemas/read.jsontool-schemas/remote-trigger.jsontool-schemas/schedule-wakeup.jsontool-schemas/send-message.jsontool-schemas/send-user-message.jsontool-schemas/skill.jsontool-schemas/task-create.jsontool-schemas/task-get.jsontool-schemas/task-list.jsontool-schemas/task-output.jsontool-schemas/task-stop.jsontool-schemas/task-update.jsontool-schemas/team-create.jsontool-schemas/team-delete.jsontool-schemas/web-fetch.jsontool-schemas/web-search.jsontool-schemas/workflow.jsontool-schemas/write.json
✅ Files skipped from review due to trivial changes (6)
- tool-schemas/task-stop.json
- tool-schemas/task-get.json
- tool-schemas/edit.json
- tool-schemas/lsp.json
- tool-schemas/monitor.json
- tool-schemas/enter-plan-mode.json
🚧 Files skipped from review as they are similar to previous changes (26)
- tool-schemas/write.json
- tool-schemas/glob.json
- tool-schemas/schedule-wakeup.json
- tool-schemas/exit-worktree.json
- tool-schemas/cron-list.json
- tool-schemas/task-output.json
- tool-schemas/skill.json
- tool-schemas/web-fetch.json
- tool-schemas/team-create.json
- tool-schemas/send-user-message.json
- tool-schemas/notebook-edit.json
- tool-schemas/cron-delete.json
- tool-schemas/web-search.json
- tool-schemas/task-create.json
- tool-schemas/cron-create.json
- tool-schemas/push-notification.json
- tool-schemas/exit-plan-mode.json
- tool-schemas/agent.json
- tool-schemas/ask-user-question.json
- tool-schemas/team-delete.json
- tool-schemas/enter-worktree.json
- tool-schemas/send-message.json
- tool-schemas/task-list.json
- tool-schemas/grep.json
- tool-schemas/read.json
- tool-schemas/task-update.json
|
Not forgotten — the generator lives in the follow-up #25, which I had split off before you asked since each PR does one thing (#24 commits the schemas; #25 adds the tooling). It's Independent fresh-clone smoke-test of #25 just passed end to end (35/35 valid JSON, override path works, path-traversal guard works, ~8.3s wall clock) — should be safe to land #24 and #25 together (either order). |
Seeded from #22. Thanks for the welcoming reply there — I went ahead and
captured the full default tool set rather than just Bash, since the data
turned out to make a small but interesting case for the approach.
What's added
A new top-level
tool-schemas/directory with 35 standalone JSON Schemafiles, each the verbatim value of
tools[i].input_schemafrom a realPOST /v1/messagesrequest, plus a short README. No transformation, nokey reordering, no wrapping — just
JSON.stringify(value, null, 2)sodiffs stay readable.
Files are grouped by what surfaces them in
tools[]:CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1/--agent-teamslocal-agentsub-agentCLAUDE_CODE_ENTRYPOINT=local-agent(addsGlob/Grep)CLAUDE_CODE_BRIEF=1(addsSendUserMessage)Stability evidence (relevant to your maintenance-burden concern)
I compared captures from v2.1.161 through v2.1.168 (seven patch
releases). 28 of 29 default schemas are byte-identical across that
range. The only change was
LSP, which gained a newquerypropertyfor the
workspaceSymboloperation:That kind of contract change is exactly what schema tracking surfaces
and prose-description tracking cannot. Over the same seven versions,
prose descriptions for
AskUserQuestion,LSP,NotebookEdit, andWorkflowchanged — so schemas and descriptions vary on independentaxes.
Agent invariance
A given tool's
input_schemais identical whether the request comesfrom the main loop, the
Exploresubagent, aWorkflow-spawnedsubagent, or any other context. Comparing 188+ captures across those,
every shared tool name produces the same byte-for-byte schema.
Subagents differ from the main loop only in which tools they get,
not in schema content — so one file per tool is sufficient (no
need to partition by caller).
Deliberately excluded
StructuredOutput— a sub-agent tool whoseinput_schemais suppliedat spawn time by the caller (the workflow orchestration script), not
defined by Claude Code. Captures show two unrelated schemas for it
depending on the workflow; recording a fixed file would misrepresent
the tool.
Out of scope (left for follow-ups)
SendUserFile,Snip,WebBrowser— code is present in the publicnative binary but requires a server-side GrowthBook entitlement
(
tengu_kairos) not flippable from local env.request_teach_access— comes from themcp__computer-use__*MCPserver, requires that server installed and connected.
PowerShell— Windows-only.Open questions for you
Naming: I used
tool-schemas/<kebab>.jsonto keep schemas in aself-contained directory. If you'd rather mirror
system-prompts/with
tool-schema-<kebab>.jsonfiles inside that same directory,the rename is mechanical — happy to do it if you prefer.
Main README integration: I haven't touched
tools/updatePrompts.jsor the main
README.mdlisting — those are wired to yourprompts-X.X.X.jsonextractor, which uses a different input paththan these schemas. If you'd like the schemas to also appear in
the main README's tool list (with versions / sizes / etc.), happy
to follow up with a small
updatePrompts.jspatch that scanstool-schemas/and adds a Tool Schemas section. Kept out of thisPR to keep one change at a time.
Maintenance: I'm happy to refresh these on the same cadence
as your existing extractor — capturing through the proxy is a
claude -paway and the diff per release looks small (oftenempty). Let me know if you'd rather do it yourselves or have me
send PRs.
Branch / commit notes
Seven commits, atomic and reviewable in order. The early ones add
the default 29, the middle ones add the gated groups, and the last
slimming-down commits respond to a self-review pass.
Summary by CodeRabbit