Repository navigation
feat(skills): serve the MCP Skills extension - #36
Merged
Merged
Conversation
Route skill:// paths to actions that return a Phantom.Skill, and serve skills/list, skills/get, resources/read, and resources/directory/read.
A file belongs to the deepest skill route that contains it, as the resource router decides. A nested skill that serves nothing serves no files, and a skill's permission covers the skills nested in it. Cache.add_skill/2 takes a list, shares its lock with add_resource_template, logs compiler diagnostics, and waits for reads still running in the old routes. Digests are always computed from the served bytes, and descriptions are limited to 1024 characters.
Add the overridable list_skills/2 router callback. The default lists every skill route without path params.
dbernheisel
force-pushed
the
dbern/skills-mcp
branch
from
October 5, 2026 01:34
a2b3cd1 to
f102882
Compare
dbernheisel
marked this pull request as ready for review
October 5, 2026 01:35
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.
Summary
io.modelcontextprotocol/skills).server/discoverandinitializedeclare it withdirectoryRead: true.Phantom.Router.skill/2,3. The macro routes askill://path to an action that returns aPhantom.Skill. Each route is a resource template in the generatedResourceRouter.Skill(lib/phantom/router.ex).Phantom.Skill(lib/phantom/skill.ex):new/2,dynamic/1,with_cache/2, andembed_skills/1.embed_skills/1compiles skill directories. EEx files render only when a method needs them.skills/list,skills/get,resources/read, andresources/directory/readfrom the action result (lib/phantom/router/skills.ex,lib/phantom/resource_plug.ex). Digests come from the bytes thatresources/readserves.list_skills/2decides which skill URIsskills/listreturns. The default lists each route that has no path params. Phantom makes each entry the same way asskills/get.with_cache/2. Non-canonical skill URIs return-32602.Phantom.Cache.add_skill/2to add skills at runtime. It takes one spec or a list.:yamerlas an optional dependency.embed_skills/1uses it to parseSKILL.mdfrontmatter.niland a deeper skill exists below it, the parent listing shows the directory, but a directory read of it fails. Digests are not cached between calls.Evidence
The script starts Bandit with
Phantom.Plugand sends MCP2026-07-28requests with Req. It uses the skill fixtures intest/support/skills. Run it from the repository root withmix run evidence.exs.iex