feat: tool annotations (title + readOnly/destructive hints) - #44
Conversation
Wire the codegen's annotation support: derive readOnlyHint/destructiveHint from each operation's HTTP method (GET/HEAD read-only, DELETE destructive) and pass a human title from HUMANIZED_TASKADE_ACTIONS. Covers all 57 tools via one generator change; tools.generated.ts regenerated. Runtime-verified: 57 tools register, 57 titled, 25 read-only, 9 destructive; the generated diff is purely additive (no schema/handler changes).
🦋 Changeset detectedLatest commit: 05bbc4c The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
This PR enhances the OpenAPI → MCP tool generation pipeline to attach MCP tool annotations to each generated tool registration, enabling clients to display a human-friendly title and safety hints (readOnlyHint / destructiveHint) derived from HTTP methods.
Changes:
- Update the OpenAPI codegen to always emit an annotations object and to derive
readOnlyHint(GET/HEAD) anddestructiveHint(DELETE), with optionaltitlesourced fromopts.actions. - Update the Taskade tools generation script to pass per-tool titles from
HUMANIZED_TASKADE_ACTIONS. - Regenerate
tools.generated.tsto include annotations for eachserver.tool(...)call and add a changeset entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/openapi-codegen/src/codegen.ts | Always emits MCP tool annotations; derives read-only/destructive hints from HTTP method; wires opts.actions.title into tool annotations. |
| packages/server/scripts/gen-taskade-mcp-tools.ts | Passes a title map into codegen based on HUMANIZED_TASKADE_ACTIONS. |
| packages/server/src/tools.generated.ts | Regenerated output adding annotations objects to each tool registration. |
| .changeset/tool-annotations.md | Declares patch releases describing the new annotation behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const description = opts.actions?.[tool.name]?.description ?? tool.description; | ||
|
|
||
| if (Object.keys(annotations).length > 0) { | ||
| toolArgs.push(JSON.stringify(annotations)); | ||
| } | ||
| const toolArgs = [`"${tool.name}"`, `"${description}"`, generateToolInputFromParsedTool(tool)]; | ||
|
|
| // Supply a human-friendly title per tool from the humanized action map; the | ||
| // codegen derives readOnly/destructive hints from each operation's HTTP method. | ||
| const actions = Object.fromEntries( | ||
| Object.entries(HUMANIZED_TASKADE_ACTIONS).map(([name, title]) => [name, { title }]), | ||
| ); |
✅ Validation & QA — ready to mergeTwo Copilot comments — both validated as valid-but-non-impactful (no change; rationale below):
QA: regenerated diff is purely additive ( Confidence: high · zero regression. Merging. (Hardening of the two notes tracked as optional follow-up.) |
What & why
Generated tools carried no MCP annotations. The codegen already had latent
opts.actionsplumbing — this wires it and adds method-derived hints, so every tool gets atitle+readOnlyHint/destructiveHint. Improves client UX/safety display and is a hard prerequisite for the Claude Connectors Directory.Changes
packages/openapi-codegen/src/codegen.ts: derivereadOnlyHint(GET/HEAD) +destructiveHint(DELETE) fromtool.method; taketitlefromopts.actions. (Also drops the prior invaliddescriptionannotation field —descriptionstays the 2nd positional arg.)packages/server/scripts/gen-taskade-mcp-tools.ts: pass titles built fromHUMANIZED_TASKADE_ACTIONS.packages/server/src/tools.generated.ts: regenerated.Zero-regression (verified)
173 insertions, 0 deletions— only an annotation object added perserver.tool(...); names, descriptions, Zod schemas, and handlers unchanged. Still 57server.tool(calls.McpServer+setupTools): 57 registered, 57 titled, 25 read-only, 9 destructive;taskDelete→ destructive,workspacesGet→ read-only. SDK accepts the(name, description, schema, annotations, cb)overload.yarn build+yarn lintclean. Changeset added (patch).