Skip to content

Add tool annotation hint fields (readOnlyHint, destructiveHint, etc.) to Annotations #259

Description

@ssathy2

The MCP::Annotations class currently supports audience, priority, and last_modified, but the MCP spec also defines several hint fields for tools that clients like Claude use to make safety decisions (e.g. requiring confirmation before calling a destructive tool):

  • title — human-readable title for the tool
  • readOnlyHint — whether the tool only reads data without modifying state
  • destructiveHint — whether the tool may modify or destroy data
  • idempotentHint — whether the tool is safe to retry
  • openWorldHint — whether the tool interacts with the outside world

We ran into this while adding annotations to our MCP server for the Claude MCP Directory submission. Our workaround is prepending a module onto MCP::Annotations to add the missing fields:

module McpAnnotationsHints
  attr_reader :title, :read_only_hint, :destructive_hint, :idempotent_hint, :open_world_hint

  def initialize(title: nil, read_only_hint: nil, destructive_hint: nil,
    idempotent_hint: nil, open_world_hint: nil, **rest)
    super(**rest)
    @title = title
    @read_only_hint = read_only_hint
    @destructive_hint = destructive_hint
    @idempotent_hint = idempotent_hint
    @open_world_hint = open_world_hint
  end

  def to_h
    super.merge(
      title: title,
      readOnlyHint: read_only_hint,
      destructiveHint: destructive_hint,
      idempotentHint: idempotent_hint,
      openWorldHint: open_world_hint
    ).compact
  end
end

MCP::Annotations.prepend(McpAnnotationsHints)

This works fine but would be nice to have natively in the gem. Happy to put up a PR if that'd be helpful!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions