Okapi

MCP & agents

Okapi mounts an MCP server over HTTP at /mcp, inside the same running instance as everything else — there's no separate process to start and no stdio transport. One transport, identical on self-host and cloud: point an agent at your instance's /mcp endpoint and it can do everything the dashboard's Issues/Logs/Releases pages can, scoped to whatever its credential is allowed to see. Agents are never metered and never gated to a paid tier — the whole MCP surface ships in every edition, every plan.

Two ways to authenticate

/mcp accepts two credentials, and they are equivalent once resolved: the same tools, the same scoping, the same roles, the same errors. They differ only in how you obtain one, who can revoke it, and what the audit log records next to the actions it takes.

OAuth (okapi_oauth_…) Agent token (okapi_agent_…)
How you get it Sign in and approve in your browser An owner mints it in the dashboard or on the CLI
Best for A person working interactively at a laptop CI, headless agents, shared automation
Lifetime 30 days, then re-approve Until revoked
Revoked by You (Connected apps), an organization owner, or a password reset/change An organization owner
Audit rows Name the human who approved it Name the token, no human
Configuration None — no header, no secret in a file The token lives in the client's config

whoami reports which door a call arrived on (door), and — for OAuth only — whose approval it is acting under (user).

OAuth: the interactive path

Add the server with no header at all. Claude Desktop, Claude Code, Codex, Cursor, and OpenCode all complete this flow:

# Cloud
claude mcp add okapi --transport http https://cloud.useokapi.app/mcp

# Self-host
claude mcp add okapi --transport http https://your-okapi-host/mcp

The first call gets a 401 pointing at your instance's own authorization server — Okapi is both the authorization server and the protected resource, so authorization never leaves your instance — and the client opens a consent screen in your browser. Sign in if you aren't already; the screen names the client asking, and you choose the organization, the projects, and the role it will get. Approve and the client completes the exchange itself; there is nothing to paste. Deny and no grant exists.

Clients identify themselves by a Client ID Metadata Document — an https:// URL Okapi fetches to learn the client's name and redirect URIs (Claude and Codex work this way, and the consent screen shows their marks). A client that can't do that may register itself dynamically (RFC 7591) instead; Okapi verifies nothing about such a client, so the consent screen presents it as an unverified application named only by what it calls itself (Cursor and OpenCode connect this way). Registration confers no access on its own and is rate limited.

A grant lives 30 days, and its power is whatever you chose on the consent screen — not something the client asked for. When it expires, the next call walks the same flow again.

Agent tokens: the CI and headless path

An agent token is a Bearer credential you paste into a client's configuration — the right shape when there is no human and no browser:

# Cloud
claude mcp add okapi --transport http https://cloud.useokapi.app/mcp \
  --header "Authorization: Bearer okapi_agent_…"

# Self-host
claude mcp add okapi --transport http https://your-okapi-host/mcp \
  --header "Authorization: Bearer okapi_agent_…"

Self-host and cloud differ only in hostname — same transport, same tools, same token format. The documented default is a project-scoped token in a per-repo .mcp.json, so each codebase talks to exactly its own Okapi project; mint a broader organization-wide token only when an agent genuinely needs to work across projects (e.g. provisioning a new one).

Managing OAuth connections

  • Yours: Account settings → Connected apps lists every grant you have approved, across every organization, with what it can reach and when it was last used. Disconnecting takes effect on the next call — the token is checked against the grant every time, never cached.
  • Your organization's: organization Settings → Connected apps (owner-only) lists every member's grants into that organization and lets an owner revoke any of them.
  • A password reset or password change revokes every one of that user's grants, in the same transaction as the credential rotation.

For self-host operators

OAuth on /mcp is on by default and needs no configuration beyond OKAPI_BASE_URL being a public https:// origin (it's the OAuth issuer). When it isn't, OAuth stays off, /mcp keeps working on agent tokens alone, and okapi serve logs one WARN naming the problem — it never refuses to boot over it. To turn OAuth off deliberately, set OKAPI_MCP_OAUTH=0; that closes the door completely and immediately invalidates any tokens it issued. Agent tokens are untouched by the switch.

Minting an agent token

Dashboard: Settings → Agent tokens (organization settings, owner-only) → New token. Give it a name, a role, and — optionally — narrow it to one project. The plaintext is shown once, alongside a ready-to-paste claude mcp add command with the token already filled in.

CLI, for headless self-host operators or CI:

okapi createtoken --role triage
okapi createtoken --role read --project web-app --name ci

--project <slug> scopes the token to one project; omitted, the token is organization-wide. On a self-host instance (exactly one organization) the organization resolves automatically; on an instance with more than one organization, pass --organization <slug> or the command errors with that instruction. The plaintext and the inline claude mcp add command print once — there's no second chance to retrieve either.

Roles

Three capability tiers, checked on every tool call — the same three whether the credential is an agent token or an OAuth grant (an OAuth grant's role is chosen on the consent screen and can never exceed the approving user's own role in that organization):

Role Can do
read List and search issues, events, logs, releases; whoami.
triage Everything read can, plus resolve, unresolve, ignore, and snooze issues. The default role for new tokens.
admin Everything triage can, plus delete issues, bulk destructive actions, and provisioning (create projects, read/create DSN keys).

An agent token can be revoked at any time from Settings → Agent tokens; revocation is immediate and irreversible (mint a new one to replace it). OAuth grants are revoked from Connected apps, as above.

Tools

  • whoami — the credential's own name, which door it came through (agent_token or oauth, plus the approving user for OAuth), scope (organization-wide, one project, or a chosen set of projects), role, and rate-limit state, so an agent can discover its own permissions without probing for a 403.
  • list_projects — every project the credential can see (all of them for an organization-wide one; just the granted set for a project-scoped one).
  • list_issues — list issues in a project; filter by status (unresolved default, all, resolved, ignored, snoozed), level, or a title query.
  • whats_new — what changed since a release or a recent time window: new issues, regressions, and spiking issues. The natural first call in a debugging session.
  • get_issue_context — the one-shot fix bundle for an issue by short id: a symbolicated stacktrace, breadcrumbs, trace-id-correlated logs, release info, a daily frequency series, affected-user count and sample contexts, similar issues, and the raw event payload.
  • check_resolution — did a previous single-issue resolve hold? Compares fresh events against the marker stamped when update_issue resolved it.
  • update_issue — triage by short id: resolve, unresolve, ignore, snooze (with snoozeMinutes), or delete (requires the admin role and a confirmDelete: true flag). resolve also accepts an optional commit/release and note.
  • bulk_update_issues — apply one triage action to every issue matching a filter (status/level/query), not just an explicit list — resolve, unresolve, ignore, snooze, or delete (requires admin and confirmBulk: true).
  • search_logs — search a project's logs by level, message query, traceId, attributes, or a sinceMinutes time window.
  • create_project — provision a brand-new project and mint its default DSN key in one call. Requires an organization-wide admin credential.
  • get_dsn — read a project's DSN (the SDK init string). Requires an admin credential, the same sensitivity as the dashboard's owner-only DSN Keys page.
  • verify_installation — is Okapi actually receiving events for this project? Reports whether a DSN key exists, whether any event has arrived, and whether it was a real error or just the synthetic "Send a test event" payload.

Every tool call is scoped to the credential's organization (and projects, if it's project-scoped) — a credential can never reach another organization's data, and a read-role credential can never mutate anything. Event- and log-derived text (messages, stack frames, breadcrumbs, correlated logs, release names, the raw payload) returned by these tools is wrapped in an explicit untrusted-data envelope before it reaches an agent: it's captured application data, never instructions.

Agent bootstrap

An agent arriving at a running instance with no prior context starts at GET /api/v1/agents: a public, ungated JSON manifest describing how to authenticate (OAuth in the browser or a pasted agent token — no session, no credential granted), the three roles and what each grants, recommended first calls (whoamilist_projectswhats_new / verify_installation), and doc links. Its tool catalog is generated from the same registry the instance's live /mcp endpoint runs, so it can't drift from what's actually callable.

Once an agent knows which project it's wiring up, GET /api/v1/organizations/{organizationSlug}/projects/{projectSlug}/install/{node|python|browser}.md serves a DSN-personalized install guide — any organization member may fetch it — so it can install the SDK, initialize it against the real DSN, send a test event, and confirm over verify_installation rather than eyeballing the dashboard.

Agent Kit ships two skills, served as plain markdown from the instance — GET /api/v1/agents/skills/okapi-setup.md and GET /api/v1/agents/skills/okapi-fix-issues.md — encoding the setup loop (detect stack → install → initialize → test event → verify_installation, then mint a per-repo triage token) and the debugging loop (whats_new → bulk-suppress noise → get_issue_context per issue → fix → check_resolution → resolve-in-commit). There's no installer: an agent fetches the markdown and places it itself — .claude/skills/<name>/SKILL.md for Claude Code, the Cursor rules directory, or a fragment appended to AGENTS.md for Codex.

For AI agents

If you're an agent reading this because a human pointed you at an Okapi instance: don't scrape the dashboard UI or ask for a pasted stack trace. Connect over MCP and work from the real data instead —

  1. whoami to confirm your own scope and role, then list_projects.
  2. whats_new or list_issues (default unresolved) to see what's actually open.
  3. get_issue_context for the full fix bundle on anything you're investigating.
  4. search_logs to pull structured logs correlated by trace id or time window around an error.
  5. update_issue or bulk_update_issues to resolve, snooze, or ignore once you've verified a fix — don't leave triage to the human if you've already confirmed the fix landed.

A machine-readable summary of Okapi — what it is, pricing, and where these docs live — is published at /llms.txt.

Next: Telemetry for what an Okapi instance sends home on its own, independent of anything you do with MCP.