Skip to content
 
 

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-experience

Serve your Agent Skills through MCP instead of loading them all into every prompt.

A skill library is progressive by design — ~100 tokens of metadata to find a skill, the full body only once you've chosen it. A flat listing throws that away and pays for the whole catalogue on every request. This plugin restores it.

The problem, measured

On a real inventory of 277 installed skills:

Flat listing of every name + description ~22,000 tokens, on every single request
Skills ever invoked, across 143 sessions 7
Invocation rate 0.14% of all tool calls
Listing cost per skill that ever gets used ~3,100 tokens

Twenty-two thousand tokens of permanent context overhead to advertise a library that fires roughly once per seven hundred tool calls — all spent before the model knows whether the task needs a skill at all.

Worse, that cost is linear in inventory size, so the catalogue itself has a ceiling. At ~80 tokens per skill a thousand skills would be ~80k tokens of system prompt, and a few thousand simply will not fit.

What this changes

Measured against the same inventory, through the MCP server:

Call Result Cost
skills_list (no arguments) all 263 skills, complete ~1,900 tokens
skills_list({query: "supabase"}) 9 matches with descriptions ~900 tokens
activate_skill({name: "supabase"}) the one skill you chose ~2,300 tokens
Nothing needed this turn 0 tokens

~7 tokens per skill instead of ~80, because browsing needs names and only the narrowed set needs prose. A thousand skills is ~7k tokens; ten thousand is ~70k. The inventory stops being bounded by the context window, and nothing is paid at all on turns where no skill is used.

(Your numbers will differ — the audit below prints them for your machine.)

Progressive disclosure over MCP

The Agent Skills format defines three disclosure stages. This maps each onto an MCP primitive, so the cost is paid when a stage is reached, not upfront:

Stage Cost MCP primitive
Discovery — what exists ~7 tokens/skill, on request skills_list tool
Activation — full SKILL.md body ~2,300 tokens, one skill activate_skill tool
Resources — bundled scripts, references, assets on demand, per file skill://{name}/{path}

The catalogue leaves the system prompt entirely. The model calls skills_list when it wants to know what's available, activate_skill once it has chosen, and reads bundled files through skill:// URIs only if the skill's instructions point at them.

Discovery has three levels, so breadth is cheap and prose is bought only where it's needed:

  • detail: "names" (default with no query) — every skill name, grouped by root, uncapped. The complete catalogue for less than one activated skill.
  • detail: "summary" (default with a query) — matching skills with descriptions truncated to 200 characters. Enough to choose between hits.
  • detail: "full" — untruncated descriptions and bundle metadata.

Two stable tools plus one resource template — not one tool per skill, which would reintroduce the same bloat through the tool list instead of the prompt.

Install

/plugin marketplace add JesseVent/agent-experience
/plugin install agent-experience@agent-experience

The MCP server starts automatically. It auto-discovers skills from ~/.agents/skills, ~/.claude/skills, <cwd>/.agents/skills, and plugin skill directories — resolving symlinks and de-duplicating by canonical path.

Tools

Tool Transport What it does
skills_list stdio + HTTP Discovery — filter by query/root, paginated, cacheable (5-min TTL)
activate_skill stdio + HTTP Activation — loads the full SKILL.md into context
skill_provenance stdio + HTTP Where a skill came from: source repo, hash, install/update times
skill_experience stdio + HTTP What's been recorded about past use of a skill
skill_updates_available stdio Detect locally-modified skills via folder-hash comparison
skill_update stdio Apply upstream updates (destructive — replaces skill files)
experience_record stdio Record an outcome after using a skill

Read-only tools work on both transports. Anything with a local side effect is stdio-only, and skill_update is explicitly destructive.

Resources: skill://{name}/{path} for any bundled file, skill://{name}/provenance for lockfile data. Path traversal is rejected at three layers.

The audit

The measurement above is reproducible, and it's a tool in its own right — because knowing why 270 of 277 skills never fire is a prerequisite for fixing it.

node "${CLAUDE_PLUGIN_ROOT}/scripts/audit.cjs" --out ~/.agents/experience

Or just ask Claude to "audit my skills" — the bundled skill-audit skill handles it. The report covers:

  • Context cost — the numbers above, for your inventory
  • Invoked — with mandated invocations flagged separately, so forced calls don't flatter the figures
  • Near-misses — unused skills whose vocabulary overlaps your real prompts, ranked by prevalence × distinctiveness, always showing the matched terms
  • Duplicates across roots — resolution is first-match-wins, so the second copy is unreachable; diverged: true means the copy you edit may never load
  • Description problemstoo_short, no_prompt_overlap, no_trigger_vocabulary
  • Dormant — the deletion shortlist, and only a shortlist

It reads session transcripts, which Claude Code already writes. No telemetry is collected — the transcript is the record.

Scoring is deliberately mechanical and always shows its matched terms: a match means the words line up, not that the skill would have helped. The script never decides a skill is dead; judgement belongs to the skill reading the report, and deletion belongs to you.

The suggest hook

A UserPromptSubmit hook that surfaces a never-used skill when your prompt strongly matches one — discovery fails at prompt time, so that's where it acts.

Conservative by design; a prompt-path hook that cries wolf is worse than none:

  • reads the precomputed audit.json, never scans the filesystem (~48ms)
  • fires only on 3+ distinct term matches, on prompts of 25+ characters
  • suggests at most 2 skills, phrased as availability rather than instruction
  • 6-hour per-skill cooldown, so it cannot nag
  • prints nothing and exits 0 on any error — never blocks a prompt

Disable with AGENT_EXPERIENCE_SUGGEST=0. Silent until you generate an audit.json with --out.

Privacy

Everything runs locally; nothing is transmitted. The audit reads prompt text to extract term frequencies and never retains or writes it — only counts and normalised terms leave the scanner, and a term survives only if it already appears in one of your skill descriptions.

audit.json contains your skill names and matched terms. It lives under ~/.agents/experience and should not be committed anywhere public.

Development

scripts/*.cjs are esbuild bundles of a TypeScript source tree — bundled rather than published as packages so the plugin has no install step and no dependency resolution at hook or server startup.

esbuild bin/mcp-stdio.ts --bundle --platform=node --format=cjs --target=node20 \
  --outfile=plugins/agent-experience/scripts/mcp-server.cjs
esbuild bin/audit.ts --bundle --platform=node --format=cjs --target=node20 \
  --outfile=plugins/agent-experience/scripts/audit.cjs

License

MIT

About

Serve your Claude Code Agent Skills through MCP with progressive disclosure — discovery, activation, and bundled resources on demand — instead of loading the whole catalogue into every prompt.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages