docs(mcp): add downloadable MCP tool reference artifact - #1380
Conversation
Closes basicmachines-co#404 Adds scripts/generate_tool_docs.py — an AST-based generator that introspects all registered MCP tools and emits docs/mcp-tools.md, a comprehensive reference covering every tool, its parameters, types, and usage notes. The generator has zero runtime dependencies (pure stdlib) and is idempotent — running it twice produces an identical file. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: FBISiri <masteragentsiri@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 556dfadbee
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| - `search_notes("my-project", "keyword")` - Find any content containing "keyword" | ||
| - `search_notes("work-docs", "'exact phrase'")` - Search for exact phrase match |
There was a problem hiding this comment.
Correct the search_notes argument order in examples
When a reader follows these two-positional-argument examples, the actual search_notes(query, project, ...) signature binds "my-project" to query and "keyword" to project, causing a search for the wrong text in a likely nonexistent project. Rewrite all such examples using explicit query=... and project=... arguments, or reverse their positional order.
AGENTS.md reference: AGENTS.md:L466-L467
Useful? React with 👍 / 👎.
| continue | ||
| out.append(f"- [{category}](#{_anchor(category)})") | ||
| for tool in entries: | ||
| out.append(f" - [`{tool.name}`](#{_anchor(tool.name)})") |
There was a problem hiding this comment.
Disambiguate repeated heading anchors
When a category and tool have the same name, as with the existing Search category and search tool, both TOC entries are emitted as #search. Markdown renderers disambiguate the later heading, so the tool link jumps to the category rather than the tool documentation; track duplicate slugs or emit explicit unique anchors.
Useful? React with 👍 / 👎.
| out.append(f"{tool.summary}\n") | ||
| detail = tool.description.strip() | ||
| if detail: | ||
| out.append(f"{detail}\n") |
There was a problem hiding this comment.
Keep docstring headings inside each tool section
When a tool description contains Markdown headings, as search_notes already does, appending it verbatim allows ## Search Syntax Examples to close the surrounding ### search_notes section. Its example headings consequently appear as peer tool entries and the parameter table falls under the final example heading in rendered outlines; normalize or demote embedded headings relative to the tool heading before rendering.
Useful? React with 👍 / 👎.
|
Thanks @FBISiri — this is the right shape for #404 and I'd like to land it. To get it through CI and the review bot quickly I've cherry-picked your commit as-is (authorship preserved) onto an in-repo branch and added one follow-up commit addressing the three Codex findings above: #1385.
I'll close this PR once #1385 merges so the credit stays attached to your commit. If you'd rather push the fixes here yourself, say so and I'll hold off. |
|
Update, and a change of plan from my earlier comment — sorry for the churn. While finishing #1385 we realized this overlaps with work already in the repo: Basic Memory has a per-tool manual written as Unix-style man pages (#952 — a What carries forward from your work:
Thanks for the contribution — it moved #404 forward even though the file itself won't land in this shape. If you're interested in the manual-side generator, that issue will be linked from #610 once it's filed. |
The examples were wrong in two ways:
- Argument order. The signature is search_notes(query, project, ...) but
all 27 examples read search_notes("my-project", "keyword"), which binds
the project name to `query` and the keyword to `project`. Anyone who
copies them searches for the project name inside a project named after
the query. Examples now pass the query positionally and the project as
a keyword.
- Escapes. The phrase-and-keyword example was written with \"exact
phrase\" escapes, which Python resolves at module load, so the runtime
docstring read search_notes(""exact phrase" AND keyword", ...) — not
valid Python. Single outer quotes keep the rendered call valid.
Scope note: the decorator passes its own short description=, so MCP
clients never received this docstring. It is the developer reference and
what any documentation generator reads (the Codex review of #1380 found
both bugs through exactly that path — thanks @FBISiri).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014pmKq6bqCi6Zp6BTHuZjrp
Signed-off-by: phernandez <paul@basicmachines.co>
|
Thanks for the detailed write-up — no apology needed for the churn,
this is a cleaner outcome than merging a file that'd drift from the
manual.
Good to hear the `search_notes` bugs landed as real fixes in #1386.
That alone makes the extraction work worth doing.
The registry generator feeding man pages is a better home for this
than a standalone reference — same idea, less surface area to
maintain. I'd be interested in picking up a piece of that once the
issue is filed from #610. Happy to start with something small on the
generator side.
|
Closes #404
What
Adds a generated MCP tool reference document (
docs/mcp-tools.md) andthe script that produces it (
scripts/generate_tool_docs.py).Why
Issue #404 requested a downloadable tool usage documentation artifact.
This PR provides a comprehensive reference for all 20+ registered MCP tools,
auto-generated from source to stay current as tools evolve.
How
scripts/generate_tool_docs.pyuses AST parsing (zero runtime deps) toextract tool names, docstrings, parameters, types, and defaults from
src/basic_memory/mcp/tools/__all__(no internal helpers)uv run scripts/generate_tool_docs.pyTesting