Skills — minimal (SEP-2640)
The scoped-down core skills shape: a skills file served as skill:// resources. Experimental.
Source: examples/skills-core/README.md
examples/skills-core ¶
⚠ Experimental - the minimal SEP-2640 (Skills) shape, a draft SEP. Wire format may change.
The minimal SEP-2640 shape: a skills file served over MCP’s Resources
primitive, plus tool handling, consumed load-on-demand. This is the
scoped-down core the Skills Over MCP Working Group blessed at its
2026-06-30 meeting (discussion 2994).
If you want the full surface, meaning archives (.tar.gz / .zip), remote source
adapters (GitHub, archive directories, multi-source mounts), and
fsnotify-driven index invalidation, see examples/skills. Those
are the deferred / extended features and are deliberately left out here.
What this shows ¶
resources/list- every file under a skill directory is askill://resource.skill://index.json- the discovery catalog, generated from the live provider (never on disk), each entry carrying a SHA-256 digest.- Read a
SKILL.md. A skill is data: YAML frontmatter (name,description) plus a markdown body of instructions. mcpkit delivers it overresources/read; it is never staged to disk and never executed. - Tool handling - the bundled
commit-helperskill instructs the host to call theformat_committool. The walkthrough reads the skill, then calls the tool. Skills make ordinary tools easier to use well.
Run it ¶
Terminal 1: just serve # skills-core server, file mode, :8080
Terminal 2: just demo # this walkthrough (interactive TUI)
Or drive it non-interactively:
just serve # in one terminal
go run . --non-interactive
Wire mode: mcpkit’s server defaults to dual-wire (SEP-2575). The first step
lets you pick adaptive (probe server/discover, fall back to initialize),
stateless, or legacy; the rest of the walkthrough is identical either way.
The skill ¶
skills/commit-helper/SKILL.md describes a task and points the host at a
tool:
---
name: commit-helper
description: Turn a change description into a Conventional Commits subject line using the format_commit tool
---
...call the `format_commit` tool with type / scope / summary...
The server registers format_commit alongside the skill provider
(main.go). That pairing of a skills file plus the tool it references is the
minimal shape in one example.
Safety posture ¶
ext/skills treats a skill as data delivered over resource primitives, never
as code to run: it does not import os/exec and never writes skill content to
disk. That invariant is enforced by TestNoCodeExecutionSurface in the
ext/skills package.
See WALKTHROUGH.md for the generated step-by-step (run
just readme to regenerate).
Next steps ¶
Walkthrough
Generated from the scripted demo — run it with make serve + make demo. Source: examples/skills-core/WALKTHROUGH.md
MCP Skills, the minimal shape (SEP-2640, scoped down) ¶
The minimal SEP-2640 shape the WG blessed on 2026-06-30: a skills file served over MCP’s Resources primitive plus tool handling, consumed load-on-demand. No archives, no remote sources, no fsnotify. Those are the deferred / extended surface (see examples/skills for the full walkthrough).
What you’ll learn ¶
- Choose the client wire mode - mcpkit’s server defaults to dual-wire (SEP-2575): one URL answers both the legacy initialize handshake and the server/discover probe. The rest of the walkthrough is identical either way.
- Read skill://index.json, the discovery catalog - mcpkit generates index.json from the live provider catalog on each cache miss, so it is not a file on disk. Each entry carries a SHA-256 digest over the skill’s SKILL.md.
- Read the commit-helper SKILL.md, the skill file - A skill is data: markdown with YAML frontmatter. Its body tells the host which tool to call and how. mcpkit delivers it over resources/read, never staged to disk and never executed.
- Tool handling, calling the tool the skill points at - This is the ’tool handling’ half of the minimal shape. The skill guided the host to format_commit; the host calls it and returns the result. Skills make ordinary tools easier to use well, the pattern Paul Withers raised in-channel on 2026-07-01.
Flow ¶
sequenceDiagram
participant Host as MCP Host (this client)
participant Server as MCP Server (just serve)
Note over Host,Server: Step 1: Choose the client wire mode
Note over Host,Server: Step 2: Connect to the skills server
Host->>Server: server/discover (stateless) OR initialize (legacy)
Server-->>Host: serverInfo + capabilities.extensions.skills
Note over Host,Server: Step 3: resources/list, where each skill file is a skill:// resource
Host->>Server: resources/list
Server-->>Host: [ skill://index.json, skill://commit-helper/SKILL.md ]
Note over Host,Server: Step 4: Read skill://index.json, the discovery catalog
Host->>Server: resources/read uri=skill://index.json
Server-->>Host: { $schema, skills:[{name,url,digest}] }
Note over Host,Server: Step 5: Read the commit-helper SKILL.md, the skill file
Host->>Server: resources/read uri=skill://commit-helper/SKILL.md
Server-->>Host: frontmatter (name, description) + body
Note over Host,Server: Step 6: Tool handling, calling the tool the skill points at
Host->>Server: tools/call name=format_commit {type:"feat", scope:"skills", summary:"..."}
Server-->>Host: feat(skills): ...
Steps ¶
Setup ¶
Terminal 1: just serve # skills-core server, file mode, :8080
Terminal 2: just demo # this walkthrough (--tui interactive)
What ‘minimal’ means ¶
Serve each file under a skill directory as a skill:// URI, enumerate them at skill://index.json with a SHA-256 digest, and let a skill’s instructions point the host at a real tool. That is the whole blessed core: skills file + tool handling, consumed load-on-demand. Archives, remote sources, and fsnotify invalidation are deferred/extended and live in examples/skills.
Step 1: Choose the client wire mode ¶
mcpkit’s server defaults to dual-wire (SEP-2575): one URL answers both the legacy initialize handshake and the server/discover probe. The rest of the walkthrough is identical either way.
Step 2: Connect to the skills server ¶
Reproduce ¶
c := client.NewClient(serverURL+"/mcp",
core.ClientInfo{Name: "skills-core-host", Version: "1.0"},
client.WithClientMode(wireMode),
)
if err := c.Connect(); err != nil { /* run: just serve */ }
Step 3: resources/list, where each skill file is a skill:// resource ¶
Step 4: Read skill://index.json, the discovery catalog ¶
mcpkit generates index.json from the live provider catalog on each cache miss, so it is not a file on disk. Each entry carries a SHA-256 digest over the skill’s SKILL.md.
Reproduce ¶
body, _ := c.ReadResource(skills.IndexURI)
var idx skills.Index
json.Unmarshal([]byte(body), &idx)
entries, _ := sc.ListSkillEntries(ctx)
for _, e := range entries {
fmt.Printf("%s files=%d\n", e.Name(), len(e.Resources.Files))
}
Step 5: Read the commit-helper SKILL.md, the skill file ¶
A skill is data: markdown with YAML frontmatter. Its body tells the host which tool to call and how. mcpkit delivers it over resources/read, never staged to disk and never executed.
Step 6: Tool handling, calling the tool the skill points at ¶
This is the ’tool handling’ half of the minimal shape. The skill guided the host to format_commit; the host calls it and returns the result. Skills make ordinary tools easier to use well, the pattern Paul Withers raised in-channel on 2026-07-01.
Reproduce ¶
out, _ := c.ToolCall("format_commit", map[string]any{
"type": "feat", "scope": "skills", "summary": "add commit-helper skill",
})
Run it ¶
go run ./examples/skills/
Pass --non-interactive to skip pauses:
go run ./examples/skills/ --non-interactive