Skip to content

Expand FastMCP tool annotations: output_schema, tags, title, timeout #826

@phernandez

Description

@phernandez

Feature Description

Expand the @mcp.tool(...) annotations on every Basic Memory MCP tool to take advantage of the additional fields FastMCP 2.10+ / 3.0+ supports.

We currently ship the four standard ToolAnnotations hints on all 24 tools (readOnlyHint, destructiveHint, idempotentHint, openWorldHint). FastMCP supports more — some are real agent-UX wins we're leaving on the table.

Problem This Feature Solves

  • Agents have to parse free-form text from tool responses. We already return JSON when output_format="json" is set, but we don't declare the shape, so clients can't validate or structure UI around it.
  • Tool lists in client UIs are flat — no categorization to help users (or agents) find the right tool among 24.
  • Tools display by snake_case identifier (write_note) in clients that surface display names; we have no human-readable titles.
  • A few long-running tools (search_notes with vector search, recent_activity over large projects) can hang in cloud transport without a server-side cap.

Proposed Solution

Add the following across src/basic_memory/mcp/tools/*.py:

1. output_schema (highest value)

Declare JSON output schemas for tools that already support output_format="json". Likely candidates:

  • write_note, read_note, edit_note, move_note, delete_note
  • search, search_notes, recent_activity, list_directory
  • build_context, list_memory_projects, get_current_project, sync_status
  • schema_infer, schema_validate, schema_diff

Schemas can be derived from the existing Pydantic response models in src/basic_memory/schemas/.

2. tags (cheap, high signal)

Tag every tool with its category, matching the groupings already used in the README:

  • {"content"}write_note, read_note, edit_note, move_note, delete_note, read_content, view_note
  • {"search"}search, search_notes, recent_activity, list_directory
  • {"graph"}build_context, canvas
  • {"projects"}list_memory_projects, create_memory_project, get_current_project, sync_status, delete_project
  • {"schema"}schema_infer, schema_validate, schema_diff
  • {"cloud"}cloud_info, release_notes, list_workspaces
  • {"chatgpt"}search, fetch (the OpenAI-compatible tools)

3. title (freebie)

Add a human-readable title inside annotations={...} for each tool. Example:

@mcp.tool(
    description="Create or update a Markdown note...",
    annotations={
        "title": "Write note",
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": False,
    },
)

4. timeout (cloud bug prevention)

Set sensible server-side timeouts on tools that can run long:

  • search_notes (vector search) — 30s
  • recent_activity (large projects) — 30s
  • schema_infer — 60s

Skip for now

  • meta — no concrete client-side use case yet.
  • icons — visual only, not worth the maintenance.
  • version — only valuable if we expect to bust client-side schema caches; reconsider later.

Alternative Solutions

We could ship only tags + title as a first pass (one afternoon of work) and split output_schema into a follow-up since that's the biggest design surface.

Additional Context

FastMCP docs: https://gofastmcp.com/servers/tools

Today's annotation usage pattern (every tool):

@mcp.tool(
    description="...",
    annotations={"readOnlyHint": True, "openWorldHint": False},
)

After this change:

@mcp.tool(
    description="...",
    tags={"content"},
    output_schema=WriteNoteResponse.model_json_schema(),
    annotations={
        "title": "Write note",
        "destructiveHint": False,
        "idempotentHint": True,
        "openWorldHint": False,
    },
)

Impact

  • Agents pick the right tool faster. Tags + titles give clients real signal for grouping and surfacing tools.
  • Structured tool output. output_schema lets MCP clients validate responses and build predictable UIs around them — especially valuable for the Cloud web app's tool picker.
  • Fewer hung requests in cloud. Server-side timeouts cap pathological queries instead of stranding the agent.
  • Better README story. Pairs with the "progressive tool discovery" framing in the project README without overstating what ships.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpythonPull requests that update python code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions