roster-cli
v1.0.1
Published
Zero-runtime-dep static auditor for Claude Code agent rosters — overlap, harness gaps, routing, cost.
Maintainers
Readme
roster
Does your agent earn its context?
roster audit also renders a shareable HTML report with --html — view a live sample report.
Philosophy
Most agent tooling optimizes personas — tone, role-play, instructions. roster starts from a different premise: structure earns value, not persona. An agent's context is a dependency, and dependencies churn — they overlap, route badly, cost tokens, and rot. roster is a static analyzer for your agent roster (skills, subagents, tool configs) that surfaces those problems before they burn context in production.
Install
roster ships as a Claude Code plugin — a resident guard instead of a one-off report.
Install via the bundled marketplace manifest:
/plugin marketplace add sshworld/roster
/plugin install rosterOnce installed:
roster-auditskill — triggers when you ask to audit an agent roster (overlap, missing harness/tools, routing ambiguity, cost); runs the bundled CLI and explains how to read the findings.roster-cleanupskill — triggers when you ask to clean up, prune, or merge agents. Audits, classifies findings into concrete actions (delete / move / merge / rename / uninstall / narrow tools), asks you to approve each destructive step, executes only what you approved, then re-audits and reports the delta.roster-usageskill — triggers when you ask which agents you actually use. Joins your transcript history against the roster to surface unused agents and ghost invocations, and points you at/roster-cleanupwhen dead weight shows up.roster-drift.shhook (SessionStart) — on each session, content- fingerprints (checksum, not just size) the watched agent-md dir(s) recursively against a cached snapshot and emits a short advisory if agents were added/removed/changed (ROSTER_DRIFT_DISABLE=1to opt out). By default it watches.claude/agentsplus, in a plugin-layout repo (one with a top-level.claude-plugin/plugin.json), the rootagents/dir; override withROSTER_DRIFT_DIR(colon-separated dir list). The scan follows symlinks and prunesnode_modules/.git. The advisory is injected into Claude's session context along with a relay directive, so Claude surfaces it to you in its first response of the session. Advisory only — never blocks a session.
Standalone CLI
npm i -g roster-clior run it without installing:
npx roster-cli audit <dir>Usage
roster is one binary with three commands: audit, doccheck, and usage.
The plugin wraps audit and usage as the /roster-audit and
/roster-usage skills, and adds /roster-cleanup — a skill-only
interactive workflow built on top of both. doccheck is CLI-only.
roster audit <dir>
roster audit <dir> --user
roster audit <dir> --repo owner/name[@ref][:subdir]
roster audit <dir> --html report.html
roster audit --plugin --enabled-only
roster doccheck README.md
roster usage --days 14 --userFull flag surface for audit:
roster audit <dir> [--json] [--html <out>] [--user] [--plugin [name]]
[--enabled-only] [--repo <owner/name[@ref][:subdir]>] [--top <n>]
[--fail-above <s>] [--no-fail]--enabled-only (with --plugin) restricts the plugin-cache source to entries
active for the current project.[^enabled-only]
[^enabled-only]: Two filters, AND-combined. Scope: user-scope entries are
always active; local/project-scope entries are active only when the cwd is
inside the pinning project. Settings: a plugin explicitly disabled via
enabledPlugins in settings.json/settings.local.json is excluded —
checked across <home>/.claude/, then the nearest project directory
at-or-above cwd that has a .claude/settings.json, with later files
winning and a key absent from all of them treated as enabled. This is
audit-path only — usage does not take --enabled-only.
What counts as an agent. --repo and <dir> scans ingest a markdown
file only if it has frontmatter with a non-empty name; description is
recommended but not required. Files named SKILL.md, CLAUDE.md, or
AGENTS.md are excluded by basename even if they carry a name key.
Collections that rely on a filename-only naming convention (no name key
in frontmatter) are not ingested by repo/dir sweeps.
MCP server
roster mcp runs a Model Context Protocol
server on stdio, so any MCP client — Claude Code, Cursor, Codex CLI, MCP
Inspector — can call roster_audit, roster_usage, and roster_doccheck
directly as tools, without shelling out.
npm i -g roster-cli
claude mcp add roster -- roster mcpnpx alternative (no global install):
claude mcp add roster -- npx -y roster-cli mcpCursor (.cursor/mcp.json):
{ "mcpServers": { "roster": { "command": "roster", "args": ["mcp"] } } }Codex CLI (~/.codex/config.toml):
[mcp_servers.roster]
command = "roster"
args = ["mcp"]Prefer a global install over npx in MCP client configs — a cold npx
download can exceed the client's startup timeout. Env vars like
ROSTER_CLAUDE_DIR go in the MCP config's env block, not inline in args.
Scope. roster parses markdown+frontmatter agent definitions (the Claude
Code format), and roster_usage reads Claude Code transcript files.
Adapters for other agent formats (Cursor rules, AGENTS.md packs) are on the
roadmap. The MCP server doesn't change what roster understands — it makes
that same analysis callable from any MCP client today.
doccheck
roster doccheck README.md
roster doccheck docs/
roster doccheck # defaults to README.md + docs/**/*.mdScans fenced sh/bash/shell code blocks in markdown docs for commands
that would fail if a reader copy-pasted them: dead relative paths, missing
npm run <script> scripts, and scripts that exist on disk but lack the
executable bit.
To keep false positives at zero, it skips anything it can't verify cheaply:
absolute paths (/plugin ...), npx ... invocations, and bare global
binaries (node, git, ...) with no path separator.
Exits 1 if any finding is reported, 0 otherwise (--json for machine-
readable output).
usage
roster usage
roster usage --days 14
roster usage --user
roster usage --plugin --jsonAggregates how often each subagent_type was invoked (via the Agent/Task
tool) across Claude Code transcript files under ~/.claude (override with
ROSTER_CLAUDE_DIR), within the last --days (default 30).
Joining with --user and/or --plugin also reports:
- unused — agents present in the roster with zero observed invocations
- ghosts — invoked
subagent_typevalues that don't match any roster agent
--plugin --json additionally adds a plugins array (always present and
always an array when --plugin is passed, even if empty) — one entry per
installed plugin:
{ "name": "some-plugin", "scope": "user", "version": "1.2.0",
"agentCount": 3, "usedCount": 0, "unusedAgents": ["a", "b", "c"],
"status": "unused" }status is "unused" when every agent that plugin ships has zero observed
invocations (a plugin-level uninstall candidate — human output lists
these under Fully-unused plugins (uninstall candidates): with a
claude plugin uninstall <name> hint), "used" when at least one agent was
invoked, or "no-agents" when the plugin ships zero agents (excluded from
the uninstall-candidate judgement — listed separately as
No agents (usage unknown): ...).
Always exits 0 — this is a reporting tool, not a gate.
Rules
| Rule | Description | Status |
| --- | --- | --- |
| overlap | Detects agents/skills covering the same responsibility | stable |
| harness | Flags harness-incompatible or malformed configs | stable |
| routing | Checks routing/trigger ambiguity between agents | stable |
| cost | Estimates context/token cost of a roster | stable |
| fluff | Flags low-signal, filler instructions (bodies >20 lines) | experimental |
Benchmarks
roster audit --repo run against well-known public agent rosters (SHA-pinned,
reproducible via scripts/bench.sh). Full reports: docs/benchmarks/.
A weekly cron re-runs the benchmark suite against each roster's latest
upstream HEAD and pushes any changes straight to main.[^leaderboard-cron]
| Repo | Agents | Top overlap pair | No-tools % | Fixed cost | | --- | --- | --- | --- | --- | | affaan-m/ECC:agents | 67 | swift-build-resolver <-> swift-reviewer (0.726) | 0.0% | ~3488 tokens/turn | | contains-studio/agents | 32 | test-writer-fixer <-> test-results-analyzer (0.475) | 3.1% | ~8421 tokens/turn | | msitarzewski/agency-agents | 255 | Backend Architect (github:msitarzewski/agency-agents@9f3e401ccd09aa0ee0ef8e015226d0647908e01e) <-> Backend Architect (github:msitarzewski/agency-agents@9f3e401ccd09aa0ee0ef8e015226d0647908e01e) (0.879) | 93.3% | ~14024 tokens/turn | | wshobson/agents | 199 | api-scaffolding-backend-architect <-> backend-api-security-backend-architect (1.000) | 92.5% | ~14041 tokens/turn |
[^leaderboard-cron]: Runs every Monday via .github/workflows/leaderboard.yml.
GitHub automatically disables scheduled workflows after 60 days of repo
inactivity — re-enable with a manual workflow_dispatch run if that
happens.
Several top pairs score at or near 1.000 similarity (e.g. wshobson/agents has five pairs at a perfect 1.000) — these are near-duplicate agent files (same description/body reused across roles), not incidental topic overlap.
Contributing
See CONTRIBUTING.md.
