Skill Router — connect your agent
Skill Router is this organization's library of skills: written instructions for doing a particular kind of work the way the organization does it. It is an MCP server. Once connected, an agent can list, search and pull skills, report how they were used, and propose edits.
https://THIS-HOSTstands for the scheme and host you fetched this page from. Substitute it everywhere below, or fetch/llms.txtfrom the same host: it is this document with the real URLs filled in.
- MCP endpoint:
https://THIS-HOST/mcp - Transport: Streamable HTTP
- Auth: OAuth 2.1 sign-in (preferred, nothing to configure), or an API token
Install
Give the client the endpoint URL and nothing else. It discovers the sign-in by itself. Find the client you are running in below.
VS Code
From a terminal, for your user profile.
code --add-mcp '{"name":"skill-router","type":"http","url":"https://THIS-HOST/mcp"}'
Or .vscode/mcp.json in the repository. Safe to commit.
{
"servers": {
"skill-router": {
"type": "http",
"url": "https://THIS-HOST/mcp"
}
}
}
Copilot CLI
Run once. It is saved to ~/.copilot/mcp-config.json.
copilot mcp add --transport http skill-router https://THIS-HOST/mcp
Claude Code
Run once, in the project you want the skills in.
claude mcp add --transport http skill-router https://THIS-HOST/mcp
Then run /mcp inside Claude Code and choose skill-router to sign in.
OpenCode
opencode.json at the root of the repository. Safe to commit.
{
"mcp": {
"skill-router": {
"type": "remote",
"url": "https://THIS-HOST/mcp",
"enabled": true
}
}
}
Codex CLI
Add it, then sign in.
codex mcp add skill-router --url https://THIS-HOST/mcp
codex mcp login skill-router
Anything else
Register a remote / Streamable HTTP MCP server at https://THIS-HOST/mcp. A client that
implements MCP authorization needs no further configuration.
What happens next — tell the person
The first connection opens a browser on https://THIS-HOST. A person has to finish it: they sign in
with the GitHub account that belongs to the organization, check the name of the client that is
asking, and press Approve. You cannot do this step for them. If you ran the install command,
say that a browser window needs their approval rather than waiting silently.
The connection then appears under Settings → API tokens on https://THIS-HOST, where it can be revoked.
Then make the skills trigger: stubs, synced at session start
Connecting the server is not enough on its own. An MCP tool is only called when you think to call
it, whereas a native skill's description is in front of you on every turn. So a repository that
uses the library keeps one stub SKILL.md per skill in .claude/skills/ — which Claude
Code, GitHub Copilot and OpenCode all read: the skill's name and description as the trigger, over a
body that says to call get_skill. A stub holds none of the skill's content, so it never goes
stale and every real use is still recorded.
You keep them in step yourself, through the MCP server you are already signed in to. No script and no API token.
1. Sync now. Call sync_skill_stubs on the skill-router server. Pass have: the
stubs object from .claude/skills/.skill-router.json — leave it out the first time, when
that file does not exist. The answer is only what changed, with instructions for writing it;
follow them. Pass project or tags to narrow it, and server if this MCP server is
registered under a name other than skill-router.
2. Make it happen at the start of every session. This is where the two main agents differ, so set up the one in use — or both, in a repository people open with either.
Claude Code
.claude/settings.json — if it exists: Merge the SessionStart entry into the existing hooks; keep everything else.
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "echo 'Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.'"
}
]
}
]
}
}
- A
SessionStarthook's plain output is added to the context, so the hook is a bareecho. That is deliberate: on Windows without Git Bash the command runs in PowerShell, and a single-quotedechois the one spelling both shells agree on. - It is context, not a turn: the sync happens when the person sends their first message, not before.
- Skills are reloaded live, so a stub written during a session is usable in that session.
- Hooks in a committed
.claude/settings.jsonrun for everybody who opens the repository, without a trust prompt. Say so when you propose committing it.
GitHub Copilot (VS Code, Copilot CLI, the cloud agent)
.github/hooks/skill-router.json — if it exists: This file is Skill Router's own; overwrite it.
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "command",
"bash": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.\"},\"additionalContext\":\"Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.\"}'",
"powershell": "Write-Output '{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.\"},\"additionalContext\":\"Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.\"}'",
"timeoutSec": 10
}
]
}
}
.github/copilot-instructions.md — if it exists: Append the section; keep everything else. Skip it if it is already there.
## Skill Router
Skill Router: before anything else in this session, call the sync_skill_stubs tool on the skill-router MCP server. Pass as have the stubs object from .claude/skills/.skill-router.json, or leave have out if that file does not exist. Follow the instructions in the answer, then carry on with what the user asked. If the skill-router MCP server is not connected, say so once and carry on.
- Copilot's hook has to print JSON — plain output is not added to the context — and takes a separate command per shell.
- Do not rely on the hook alone. Agent hooks are a Preview feature in VS Code, and Copilot CLI has shipped versions that discard what a
sessionStarthook prints. The instructions file is read by every Copilot surface in every session, so it is the part that always works; the hook is the part that works without the model having to notice. Where both fire the sync runs once — the second answer isupToDate. - VS Code also reads Claude Code's
.claude/settings.jsonhooks, but does nothing with plain output, so the two files do not double up. - The cloud agent has no browser to sign in with. It reaches this MCP server only with an API token in its MCP configuration (see below); the hook and the stubs are the same.
3. Ask whether to commit. .claude/skills/ holds no secret and no skill content, so
committing it — stubs, state file and the hook files above — gives the whole team the triggers from
their first session. The alternative is ignoring the directory and letting each person's first
session fill it. Either works; it is the person's call.
A skill with no description gets a stub that will rarely trigger. The fix is to write the description in Skill Router, not to edit the stub — edits to a stub are overwritten.
Where there is no agent — CI, a setup script — the same stubs come from a standalone script.
It runs outside any MCP client, so it does need an API token, which a person creates at
https://THIS-HOST/settings/tokens:
curl -fsSL https://THIS-HOST/sync-skills.mjs -o sync-skills.mjs
SKILL_ROUTER_URL=https://THIS-HOST SKILL_ROUTER_TOKEN=sr_... node sync-skills.mjs --dry-run
If the client cannot sign in
Scripts, CI, and clients without OAuth present an API token instead. A person creates one at
https://THIS-HOST/settings/tokens — it is shown once — and the client sends it as a header:
claude mcp add --transport http skill-router https://THIS-HOST/mcp \
--header "Authorization: Bearer $SKILL_ROUTER_TOKEN"
Never write the token into a file that gets committed. Read it from the environment
(SKILL_ROUTER_TOKEN) or the client's own secret storage.
Using it
list_skills— the catalogue, with slugs.search_skills— when you know the problem and not the name.get_skill— the whole document. Pass areason: why you reached for it.report_skill_usage— afterwards, whether it helped or fell short.propose_skill_update— opens a review; a person approves it. Nothing you send changes a skill directly.sync_skill_stubs— at the start of a session, as above. Records no usage.
Discovery, for clients
- Protected resource metadata:
https://THIS-HOST/.well-known/oauth-protected-resource - Authorization server metadata:
https://THIS-HOST/.well-known/oauth-authorization-server - These instructions as plain text:
https://THIS-HOST/llms.txt - The stub sync script:
https://THIS-HOST/sync-skills.mjs