MCP overview
Kestrel ships an MCP (Model Context Protocol) server in the same binary that serves the API and web UI. The agent sees a small, focused set of tools designed for one workflow:
list errors → get one → diagnose → mark resolved with a commit SHA
There is no create_issue, assign, add_comment, or set_priority — those concepts don't exist in Kestrel.
Two transports, same tools
# Best for local agents (Claude Code / Cursor / your CLI). The stdio
# transport reads the SQLite file directly, so it must run on the same
# machine that has data/kestrel.db (use --db to point elsewhere).
kestrel mcp
# Or in a JSON config:
{
"command": "kestrel",
"args": ["mcp"],
"env": { "KESTREL_TOKEN": "<project-token>" }
}# Best for any setup where the agent and the server are not on the same
# host — including the common Docker-deployed case.
POST /mcp HTTP/1.1
Authorization: Bearer <project-token>The HTTP endpoint requires Authorization: Bearer <token> on every call — anonymous clients get a 401 before tools/list or initialize are exposed, so agents can't enumerate the schema without the token.
Auth → project scoping
Each project's ingest token doubles as the MCP credential. The token a request presents determines the project the tool calls scope to — there's no way to read another project's issues with someone else's token.
This is intentionally simpler than RBAC: one token, one project, one mental model.
Wiring it into Claude Code
If your agent is on the same machine as the server (binary install with the SQLite at ./data/kestrel.db):
// ~/.claude/mcp.json
{
"mcpServers": {
"kestrel": {
"command": "kestrel",
"args": ["mcp"],
"env": { "KESTREL_TOKEN": "your-project-token" }
}
}
}If Kestrel is in Docker or on another host, point Claude Code at the HTTP transport instead:
{
"mcpServers": {
"kestrel": {
"url": "http://localhost:8080/mcp",
"headers": { "Authorization": "Bearer your-project-token" }
}
}
}After Claude Code restarts, the tools below are available without any prompt scaffolding. Try: "List the open errors and pick the one I should look at first."
What's the point?
The whole reason Kestrel exists is to make this loop short:
- Bug ships.
- SDK posts an envelope.
- Agent sees the new error, reads the resolved stack with source context, recent logs, and the responsible commit.
- Agent proposes a fix, the human approves and commits.
- Agent calls
mark_resolved(issue_id, commit_sha).
Step 4 is the only step a human is required for. Everything else is the agent doing what on-call would do — faster, and without paging anyone.