Skip to content

Tool annotations (readOnlyHint/destructiveHint) + registerTool migration — works on SDK 1.x today #260

Description

@StuMason

Why (do this BEFORE V3 — works on the current SDK)

None of our 42 tools declare tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) — spec-stable since 2025-03-26 and supported by SDK 1.x registerTool(). Client behavior is real now:

  • Claude Code parallel-dispatches tools marked readOnlyHint: true — our ~15 read-only tools (list_*, get_*, diagnose_*, search_docs, …) currently serialize when they could fan out
  • VS Code Copilot shows confirmation dialogs for anything NOT read-only — unannotated read tools get scary prompts they don't deserve
  • ChatGPT dev mode badges READ/WRITE from annotations; Claude Desktop groups tool UI by them

For a server whose tool list includes deploy, stop_all_apps, bulk_env_update, and four flavors of delete, the safety signal of destructiveHint is exactly what the spec authors had in mind.

What

  1. Migrate mcp-server.ts from legacy this.tool(name, desc, schema, handler) to this.registerTool(name, { description, inputSchema, annotations }, handler) — mechanical sweep, and it future-proofs for SDK v2 (V3 Epic: migrate to MCP TypeScript SDK v2 + spec 2026-07-28 #259) which keeps the registerTool shape.
  2. Annotate all 42 tools. Suggested mapping:
    • readOnlyHint: trueget_version, get_mcp_version, get_infrastructure_overview, list_* (5), get_* (4), server_resources, server_domains, diagnose_app, diagnose_server, find_issues, search_docs, deployment (get/list actions)
    • destructiveHint: trueapplication/database/service/projects/environments/private_keys/github_apps/storages/scheduled_tasks/database_backups (delete actions), stop_all_apps, bulk_env_update, control (stop/restart), deploy, redeploy_project, restart_project_apps, system (disable_api)
    • idempotentHint: true where PATCH semantics apply (updates)
    • openWorldHint: true on everything (remote Coolify API)
    • Mixed-action tools take worst-case annotations (a tool with any destructive action is destructiveHint: true, readOnlyHint: false)
  3. Tests: assert annotations on registered tools (snapshot of name → annotations map).

Notes

  • Zero token cost — annotations ride the existing tools/list response.
  • Also consider Claude Code's proprietary anthropic/maxResultSizeChars meta-annotation for application_logs / deployment get.

Refs: #259 (V3 epic). Annotation support survey: https://mcpblog.dev/blog/2026-03-13-mcp-tool-annotations

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmcp-specNew MCP spec feature adoption

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions