Skip to content

fix(mcp): add directory-compliant tool annotations#1031

Merged
phernandez merged 2 commits into
mainfrom
fix/mcp-directory-annotations
Jul 2, 2026
Merged

fix(mcp): add directory-compliant tool annotations#1031
phernandez merged 2 commits into
mainfrom
fix/mcp-directory-annotations

Conversation

@phernandez

Copy link
Copy Markdown
Member

Summary

Prep for the Anthropic directory submission. The directory validator reads ToolAnnotations.title (inside the annotations object), not FastMCP's top-level title= kwarg, so the review flagged every tool as missing a title annotation and every write tool as missing readOnlyHint.

  • Add "title" inside every tool's annotations dict (23 tools, plus the two disabled MCP-UI tools for consistency)
  • Add explicit readOnlyHint: False to the seven write tools
  • Flip edit_note to destructiveHint: Truefind_replace/replace_section overwrite existing content, so the tool is not purely additive; matches the directory criteria requiring destructiveHint: true for tools modifying data
  • Cite target API docs in build_context and read_content descriptions (the criteria require tools accepting freeform paths to reference their API; both URLs verified live on docs.basicmemory.com)
  • Add test_mcp_tool_annotations_meet_directory_requirements to tests/mcp/test_tool_contracts.py: a table-driven contract test asserting the wire-level annotations (to_mcp_tool()) for every registered tool — unannotated new tools fail CI with instructions

Test plan

  • pytest tests/mcp/test_tool_contracts.py tests/mcp/test_tool_edit_note.py — 62 passed
  • pytest tests/mcp/test_ui_sdk.py tests/mcp/test_tool_contracts.py — 11 passed (proves the contract test is independent of whether the optional UI tools registered)
  • ruff check / ruff format --check / ty check src tests clean

Follow-up

basic-memory-cloud pins this repo by git rev; after this lands, the pin bump + deploy must happen before re-running the directory review (companion PR updates the cloud-side activity_feed annotations and removes canvas from the hosted server).

🤖 Generated with Claude Code

Anthropic directory review reads ToolAnnotations.title rather than
FastMCP's top-level title kwarg, so every tool was flagged as missing
a title annotation and write tools as missing readOnlyHint.

- add "title" inside every tool's annotations dict
- add explicit readOnlyHint: False to the seven write tools
- flip edit_note to destructiveHint: True (find_replace and
  replace_section overwrite existing content, so the tool is not
  purely additive)
- cite target API docs in build_context and read_content descriptions
  per the directory criteria for tools accepting freeform paths
- add a table-driven contract test asserting the wire-level
  annotations for every registered tool, so new tools fail CI until
  they declare directory-compliant annotations

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 90c843eed6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/mcp/test_tool_contracts.py Outdated
Comment on lines +143 to +144
"canvas": {"readOnlyHint": False, "destructiveHint": False},
"create_memory_project": {"readOnlyHint": False, "destructiveHint": False},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Set write tool destructive hints to true

For the directory-submission contract, these expectations now lock canvas and create_memory_project to destructiveHint: False even though both mutate user data (canvas creates/updates a .canvas file, and project creation changes project/config or cloud state); move_note below has the same false expectation. Anthropic's review criteria require destructiveHint: true for tools that modify or delete data, so this test can pass while the submission still fails; update the write-tool annotations and expectations to true.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially adopted in 8f658cc. canvas is now destructiveHint: True — it falls back to PUT when the file exists, replacing its content, same standard as write_note/edit_note. move_note and create_memory_project deliberately stay False: move refuses to overwrite an existing destination (entity_service raises "file already exists at destination path") and preserves all content, and project creation is purely additive and errors if the target exists. Per the MCP spec, destructiveHint: false asserts additive/non-destructive updates, which both satisfy — and keeping them non-destructive lets clients allowlist bulk lifecycle moves without per-call confirmation. Rationale is recorded in the contract test table.

Codex review follow-up: canvas falls back to PUT when the file already
exists, replacing its content, so it warrants destructiveHint: True by
the same standard as write_note and edit_note.

move_note and create_memory_project stay non-destructive deliberately:
move refuses to overwrite an existing destination and preserves all
content, and project creation is purely additive and errors if the
target exists. Rationale recorded in the contract test table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
@phernandez phernandez merged commit a1e0987 into main Jul 2, 2026
25 checks passed
@phernandez phernandez deleted the fix/mcp-directory-annotations branch July 2, 2026 20:17
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.

1 participant