Connect your agent
Configure Shepherd in Claude Code, Codex, Pi, Cursor, or another MCP client.
Every client launches the same stdio MCP server:
npx -y @korso/shepherdUse your own hub URL and token in the examples below.
Korso-hosted users get a SHEPHERD_TOKEN from the dashboard's Connect Agent panel (sign in with Google or GitHub, then generate a per-account token) — it works across every workspace on the account. Self-hosted teams use TEAM_TOKEN from whoever runs their hub. Both sit in the same spot in every example below — swap the name and value for your setup.
Claude Code
Recommended user-scope install:
claude mcp add shepherd -s user -e HUB_URL=https://your-shepherd-hub.example.com -e SHEPHERD_TOKEN=<your-token> -- npx -y @korso/shepherdAlternative project-root .mcp.json:
{
"mcpServers": {
"shepherd": {
"command": "npx",
"args": ["-y", "@korso/shepherd"],
"env": {
"HUB_URL": "https://your-shepherd-hub.example.com",
"SHEPHERD_TOKEN": "<your-token>"
}
}
}
}Claude Code does not read ~/.claude/mcp.json. Use claude mcp add or a project-root
.mcp.json.
Verify with:
claude mcp listCodex
Recommended install:
codex mcp add shepherd --env HUB_URL=https://your-shepherd-hub.example.com --env SHEPHERD_TOKEN=<your-token> --env PROGRAM=codex -- npx -y @korso/shepherdAlternative ~/.codex/config.toml entry:
[mcp_servers.shepherd]
command = "npx"
args = ["-y", "@korso/shepherd"]
env = { HUB_URL = "https://your-shepherd-hub.example.com", SHEPHERD_TOKEN = "<your-token>", PROGRAM = "codex" }Verify from the Codex /mcp panel.
Pi
Add Shepherd to ~/.pi/agent/mcp.json or project-local .pi/mcp.json:
{
"mcpServers": {
"shepherd": {
"command": "npx",
"args": ["-y", "@korso/shepherd"],
"env": {
"HUB_URL": "https://your-shepherd-hub.example.com",
"SHEPHERD_TOKEN": "<your-token>",
"PROGRAM": "pi"
}
}
}
}Verify from Pi's /mcp panel.
Cursor
Cursor reads the same JSON mcpServers shape as Pi — global at ~/.cursor/mcp.json, or per-project at .cursor/mcp.json:
{
"mcpServers": {
"shepherd": {
"command": "npx",
"args": ["-y", "@korso/shepherd"],
"env": {
"HUB_URL": "https://your-shepherd-hub.example.com",
"SHEPHERD_TOKEN": "<your-token>",
"PROGRAM": "cursor"
}
}
}
}Verify under Settings → MCP — shepherd should be listed with its tools.
Passive announcement delivery (hooks)
Announcements always reach an agent eventually: every work/sync/done/announce call returns anything waiting for it, so nothing is ever lost even with no hook installed. But that only delivers on the agent's next Shepherd tool call. To surface announcements (and the link/decline nudge for an unlinked repo) on the agent's next action of any kind — without waiting for it to call a Shepherd tool — the client needs a small delivery hook wired up.
You don't normally set this up yourself. The first time the server runs under Claude Code, Codex, Cursor, or Pi, it installs the hook automatically:
| Client | File it edits/creates | What it adds |
|---|---|---|
| Claude Code | ~/.claude/settings.json | SessionStart + PreToolUse hook entries |
| Codex | ~/.codex/config.toml | a [[hooks.UserPromptSubmit]] block (+ features.hooks = true) |
| Cursor | ~/.cursor/hooks.json | a beforeSubmitPrompt entry |
| Pi | ~/.pi/agent/extensions/shepherd-inbox.js | copies the bundled extension |
This is disclosed here because it's a real, one-time edit to a file in your home directory — not a separate confirmation prompt. It's deliberately conservative:
- Additive only — existing keys/entries in your config are never modified, removed, or reordered.
- At most one attempt per machine per client, recorded under
~/.shepherd/hooks/. If you remove the hook afterward, Shepherd never re-adds it. - Version-pinned — the installed command runs the exact shipped build, not a floating
npx @korso/shepherd@latest. - Fail-open — a config file Shepherd can't confidently parse is left untouched, with a stderr notice instead of a crash.
Set SHEPHERD_NO_AUTO_HOOKS=1 in the server's env to opt out entirely; the server then never touches any client config. Every hook runs the same npx -y --package=@korso/shepherd shepherd-inbox-hook command (a Pi extension for Pi, since it has no stdin/stdout hook mechanism) — wire it into your client's hook config by hand if you'd rather do it yourself, or if SHEPHERD_NO_AUTO_HOOKS skipped a client it doesn't recognize.
Any MCP client
If your client accepts a stdio MCP server, configure this command and environment:
{
"command": "npx",
"args": ["-y", "@korso/shepherd"],
"env": {
"HUB_URL": "https://your-shepherd-hub.example.com",
"SHEPHERD_TOKEN": "<your-token>",
"PROGRAM": "your-client-name"
}
}Other environment variables
HUB_URL plus one token is all that's required. A few more variables tune optional behavior — set them in the same env block as everything above:
| Variable | Default | What it changes |
|---|---|---|
HEARTBEAT_INTERVAL_SECONDS | 60 | How often the client polls the hub for presence and pending announcements. |
SHEPHERD_INBOX_DIR | ~/.shepherd/inbox | Where the background heartbeat stages announcements for hook delivery. Only change it if you also point a manually-wired hook at the same directory. |
SHEPHERD_NO_AUTO_HOOKS | unset (auto-install on) | Set to 1 to stop the server from auto-installing the client delivery hook described above. |
SHEPHERD_ALLOW_INSECURE_HTTP | unset | Set to 1 to permit a plain-http HUB_URL to a non-loopback host. Loopback http never needs this; a non-loopback http:// hub is otherwise refused so a token can't travel unencrypted. |
Smoke test without a client
PowerShell:
$env:HUB_URL = "https://your-shepherd-hub.example.com"
$env:SHEPHERD_TOKEN = "<your-token>"
npx -y @korso/shepherdbash or zsh:
HUB_URL=https://your-shepherd-hub.example.com SHEPHERD_TOKEN=<your-token> npx -y @korso/shepherdA healthy server prints no error and waits on stdin. Press Ctrl+C to stop it.