Expose idfkit agent references over MCP (idfkit#160)#73
Open
samuelduchesne wants to merge 2 commits into
Open
Conversation
…kit#160)
Add two new resources backed by the agent reference docs shipped inside
the idfkit wheel under .agents/skills/developing-with-idfkit/:
idfkit://references/ — index (slug, title, description per topic
+ SKILL.md dispatch document)
idfkit://references/{topic} — raw markdown for a single topic
The new tools/references.py module reads from the installed idfkit via
importlib.resources, so there's no vendored copy and no path hardcoding —
when idfkit bumps to a version that ships the references, the resources
surface them automatically. Older idfkit versions are handled gracefully:
the index returns count=0 and the topic resource raises a clear ValueError.
Tests cover metadata parsing, the loader, both resources (when references
are available), and the no-references fallback path. The integration tests
skip cleanly when the installed idfkit predates the references, so the
suite passes against the current idfkit==0.12.2 pin and will exercise the
full path once the pin is bumped.
…esource
The idfkit://references/{topic} resource was joining the raw topic
string onto the references directory. A URI like
idfkit://references/..%2F..%2F..%2Fetc%2Fpasswd would resolve outside
the bundled references tree (any .md-suffixed file readable by the
server process). The MCP transport may or may not normalize ..; this
is defense in depth.
Validate topic against ^[a-z0-9][a-z0-9-]*$ before path-joining;
return ValueError("Invalid reference topic '{topic}'.") otherwise.
Parametrized test covers .., parent-relative paths, slashes, leading
dash, uppercase, and the empty string.
Refs idfkit#160.
Contributor
|
Docs preview for this PR is available at: Changed pages: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to idfkit/idfkit#160 (PR idfkit/idfkit#TBD).
Summary
idfkit://references/returns a JSON index of available topics (slug, title, description, URI) plus the bundledSKILL.mddispatch document.idfkit://references/{topic}returns the raw markdown for a single topic.src/idfkit_mcp/tools/references.pyreads the docs viaimportlib.resourcesfrom the installed idfkit. Cached withfunctools.cache(the wheel layout doesn't change at runtime). Returns an empty index when the installed idfkit predates the references, so this PR is self-sufficient and the next idfkit pin bump surfaces the docs automatically.src/idfkit_mcp/server.pyregisters the two resources alongside the existing tool surface.Security
The
{topic}segment comes off the MCP URI;idfkit://references/..%2F..%2F..%2Fetc%2Fpasswdwould have resolved outside the bundled tree under naive path joining. The resource now validatestopicagainst^[a-z0-9][a-z0-9-]*$before any filesystem access; the parametrized test covers..,foo/bar, leading dash, uppercase, and the empty string. Defense in depth — the MCP transport may or may not normalize...Test plan
make check— ruff, pyright, deptry: cleanmake test— 240 passed, 9 skipped (skips are integration paths that need the new references in the installed idfkit; they'll exercise on the next pin bump)idfkit://references/returns the empty index against the currently pinned idfkit==0.12.2; the topic resource raisesInvalid reference topicfor..,foo/bar, etc.idfkithere and watch the 9 skipped tests turn greenGenerated by Claude Code