Problem
Toolcraft commands cannot declare standard MCP tool metadata. CommandConfig has no title or annotations, and the MCP adapter registers commands through the legacy server.tool(...) overload. As a result, every generated MCP tool omits readOnlyHint, destructiveHint, idempotentHint, and openWorldHint.
MCP applies pessimistic defaults when these fields are absent: non-read-only, potentially destructive, non-idempotent, and open-world. A consumer with many read tools therefore presents all of them as destructive. OpenAI Apps review also expects complete annotations.
The bundled tiny MCP server already supports these fields through registerTool(definition, handler).
Proposed API
Keep this optional and local to the existing command API:
defineCommand({
name: "get",
title: "Get calendar event",
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false
},
params,
handler
})
Non-MCP and existing commands should require no changes. Re-export a Toolcraft-owned structural ToolAnnotations type so callers do not need to import a transport package.
Implementation
- Add optional
title and annotations to CommandConfig and materialized Command metadata.
- Clone and preserve them across group materialization/composition.
- Include them in enumerated MCP tool definitions.
- Register non-stream tools through
server.registerTool({ name, title, description, inputSchema, outputSchema, annotations }, handler).
- Preserve existing input/output validation and structured-content behavior.
- Add tools/list tests for all four boolean hints and title, plus a compatibility test proving commands without metadata remain unchanged.
Acceptance criteria
tools/list contains declared title and annotations unchanged.
- All four standard hints are supported.
- Output schemas continue to be advertised and validated.
- CLI/SDK behavior and commands that omit this optional metadata are unchanged.
- Public API stays on
defineCommand; no separate package or server-specific configuration is required.
Found while auditing the hosted Skylight Calendar MCP server, where all 116 tools currently inherit the unsafe defaults.
Problem
Toolcraft commands cannot declare standard MCP tool metadata.
CommandConfighas notitleorannotations, and the MCP adapter registers commands through the legacyserver.tool(...)overload. As a result, every generated MCP tool omitsreadOnlyHint,destructiveHint,idempotentHint, andopenWorldHint.MCP applies pessimistic defaults when these fields are absent: non-read-only, potentially destructive, non-idempotent, and open-world. A consumer with many read tools therefore presents all of them as destructive. OpenAI Apps review also expects complete annotations.
The bundled tiny MCP server already supports these fields through
registerTool(definition, handler).Proposed API
Keep this optional and local to the existing command API:
Non-MCP and existing commands should require no changes. Re-export a Toolcraft-owned structural
ToolAnnotationstype so callers do not need to import a transport package.Implementation
titleandannotationstoCommandConfigand materializedCommandmetadata.server.registerTool({ name, title, description, inputSchema, outputSchema, annotations }, handler).Acceptance criteria
tools/listcontains declaredtitleandannotationsunchanged.defineCommand; no separate package or server-specific configuration is required.Found while auditing the hosted Skylight Calendar MCP server, where all 116 tools currently inherit the unsafe defaults.