Skip to content

Conversation

@triepod-ai
Copy link
Contributor

Summary

Adds MCP tool annotations (readOnlyHint) to all tools to help LLMs better understand tool behavior and make safer decisions about tool execution.

Changes

  • Added readOnlyHint: true to resolve-library-id (read-only library search)
  • Added readOnlyHint: true to get-library-docs (read-only documentation fetch)

Both tools only read/fetch documentation data and do not modify any state, making readOnlyHint the appropriate annotation.

Why This Matters

  • Annotations provide semantic metadata that helps LLMs understand tool behavior
  • LLMs can make better decisions about when to use tools and in what order
  • readOnlyHint: true signals these tools are safe to call without side effects
  • Enables safer tool execution by distinguishing read-only from destructive operations

Testing

  • Server builds successfully (pnpm run build)
  • tools/list returns annotations in response
  • Annotation values match actual tool behavior (both tools are read-only)

Before/After

Before:

{
  name: "resolve-library-id",
  title: "Resolve Context7 Library ID",
  description: "..."
  // No annotations
}

After:

{
  name: "resolve-library-id",
  title: "Resolve Context7 Library ID",
  description: "...",
  annotations: {
    readOnlyHint: true
  }
}

Verification

# tools/list now returns:
Tool: resolve-library-id
  Annotations: {"readOnlyHint": true}

Tool: get-library-docs
  Annotations: {"readOnlyHint": true}

Add readOnlyHint annotations to all tools to help LLMs better understand
tool behavior and make safer decisions about tool execution.

Changes:
- Added readOnlyHint: true to resolve-library-id (read-only search)
- Added readOnlyHint: true to get-library-docs (read-only fetch)

Both tools only read/fetch documentation data and do not modify any state,
making readOnlyHint appropriate for safer LLM tool selection.

Co-Authored-By: Claude <noreply@anthropic.com>
@enesgules
Copy link
Collaborator

Oh thank you so much for this, do you think if we should add idempotentHint too based on the docs?

annotations?: {        // Optional hints about tool behavior
    title?: string;      // Human-readable title for the tool
    readOnlyHint?: boolean;    // If true, the tool does not modify its environment
    destructiveHint?: boolean; // If true, the tool may perform destructive updates
    idempotentHint?: boolean;  // If true, repeated calls with same args have no additional effect
    openWorldHint?: boolean;   // If true, tool interacts with external entities
  }

Also how does these improve the LLM tool calling performance? Is there an actual difference you noticed?

@triepod-ai
Copy link
Contributor Author

Thanks for the review questions!

On idempotentHint: The MCP specification states that idempotentHint is only meaningful when readOnlyHint == false. Since both tools are read-only (they only query/search, never modify state), idempotentHint would be semantically meaningless and ignored by clients. So no, we shouldn't add it here.

On actual benefits: The annotations don't directly improve LLM inference performance - they're advisory hints for MCP clients, not the model itself. The concrete benefits are:

  1. Safety automation - Clients like Claude Code auto-approve tools with readOnlyHint: true while requiring confirmation for destructive operations
  2. UI indicators - Clients can show appropriate warnings/icons
  3. Caching - Read-only tools can have results cached more aggressively
  4. Filtering - Clients can offer "safe mode" showing only read-only tools

The value is in enabling better client behavior and user experience, not model performance. For a library search/docs tool, readOnlyHint: true signals to clients that these operations are safe to auto-approve without user confirmation.

@enesgules enesgules merged commit 93a2d5b into upstash:master Dec 30, 2025
1 of 3 checks passed
@enesgules
Copy link
Collaborator

Thanks for the great contribution!

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.

3 participants