Skills — minimal (SEP-2640)

The scoped-down core skills shape: a skills file served as skill:// resources. Experimental.

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 — 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

  1. resources/list — every file under a skill directory is a skill:// resource.
  2. skill://index.json — the discovery catalog, generated from the live provider (never on disk), each entry carrying a SHA-256 digest.
  3. Read a SKILL.md — a skill is data: YAML frontmatter (name, description) plus a markdown body of instructions. mcpkit delivers it over resources/read; it is never staged to disk and never executed.
  4. Tool handling — the bundled commit-helper skill instructs the host to call the format_commit tool. 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 — 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

MCP Skills — 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 — 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, never executed.
  • Tool handling — call 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 — 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 — call 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 — 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 — 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)
for _, e := range idx.Skills {
    fmt.Printf("%s digest=%s\n", e.Name, e.Digest)
}

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, never executed.

Step 6: Tool handling — call 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