Epure

MCP and CLI

Epure error tracking has two agent clients, the MCP server @epure-sh/mcp and the CLI @epure-sh/cli, plus a hosted MCP server at https://app.epure.sh/mcp on Epure Cloud. All three sign in with OAuth and call the same /api/v1 routes, within the scopes you approve. The npm packages need Node.js 18 or later; Apache-2.0 covers these client packages, and the engine is AGPL-3.0. None of them sends errors: events still go from your Sentry SDK to Epure through the DSN (Quickstart).

For a walk-through with checks after each step, see connect Epure to Claude Code, Cursor or Codex. This page is the reference. Last checked against @epure-sh/mcp and @epure-sh/cli 0.3.0 on 6 Nov 2026.

How do I set up an MCP server for my Epure errors?

Setting up the Epure MCP server takes two commands in Claude Code and three for any stdio client. Claude Code connects to the hosted server and signs in with /mcp (Claude Code MCP docs). Cursor, Claude Desktop, Codex and self-hosted instances run npx -y @epure-sh/mcp after one login. The doctor command then confirms the session reaches your instance.

# Claude Code, hosted server (Epure Cloud)
claude mcp add --transport http --scope user epure https://app.epure.sh/mcp
# then, inside Claude Code: /mcp, and approve in the browser

# Any stdio client: Cursor, Claude Desktop, Codex, self-hosted
npx -y @epure-sh/mcp login
npx -y @epure-sh/mcp init      # prints the client configuration
npx -y @epure-sh/mcp doctor    # checks session and instance

# Terminal and scripts
npm install -g @epure-sh/cli
epure auth login
epure issues list --limit 20

init prints a configuration with no credential in it, for mcp.json (Cursor) or claude_desktop_config.json (Claude Desktop):

{ "mcpServers": { "epure": { "command": "npx", "args": ["-y", "@epure-sh/mcp"] } } }

Cursor reads that entry from ~/.cursor/mcp.json or .cursor/mcp.json (Cursor MCP docs). Codex takes the same command: codex mcp add epure -- npx -y @epure-sh/mcp (Codex MCP docs). Add --read-only or --toolsets issues,projects to init to bake those filters into the printed entry, and --transport http to print the hosted entry instead.

How do I add the Epure agent skills?

The Epure agent skills teach a coding agent the setup and triage steps on this page: epure-setup (Cloud or self-host), epure-wire (point the Sentry SDK at the DSN), epure-agent (MCP and CLI) and epure-triage (fix an issue, treat its content as untrusted data). Install them with skills.sh for any agent, or as a Claude Code plugin that also adds the hosted MCP server.

# Any agent that reads skills
npx skills add epure-sh/epure

# Claude Code, inside a session
/plugin marketplace add epure-sh/epure
/plugin install epure@epure

The skills live in plugins/epure/skills in the engine repository. Checked on 12 Nov 2026.

Should I use the hosted MCP server, the stdio package or the CLI?

The three Epure clients share one OAuth model and one tool registry; they differ in transport and where they run. The hosted server needs no install but only exists where the instance enables it. The stdio package runs anywhere Node.js 18 runs, including against self-hosted instances. The CLI suits scripts, CI and agents that prefer a shell.

Hosted /mcpstdio @epure-sh/mcpCLI @epure-sh/cli
TransportStateless Streamable HTTP, JSON responsesNewline-delimited JSON-RPC over stdioTerminal commands
InstallNonenpx -y @epure-sh/mcpnpm install -g @epure-sh/cli
Sign-inThe MCP client's OAuth flow (discovery, PKCE, automatic client registration)npx -y @epure-sh/mcp loginepure auth login
ClientsClaude Code, Claude web and mobile (custom connector)Cursor, Claude Desktop, Codex, Claude CodeAny shell
Self-hostedOnly with EPURE_MCP_ENABLED=true (default false)--url https://errors.example.com--url or EPURE_URL
FiltersOAuth scopesScopes, --read-only, --toolsetsScopes

Both MCP transports support protocol versions 2024-11-05, 2025-03-26, 2025-06-18 and 2025-11-25. Claude on the web cannot run a local stdio server, so it uses the hosted URL: Customize → Connectors → Add custom connector, name it Epure, enter https://app.epure.sh/mcp, choose Register automatically.

How do Epure MCP and the CLI sign in?

Epure MCP and the CLI sign in with OAuth only, and share one session. npx -y @epure-sh/mcp login and epure auth login open a browser approval (PKCE) on a desktop and use a device code (RFC 8628) with --device, or automatically when SSH_CLIENT is set or stdin is not a terminal. The session lives in $XDG_CONFIG_HOME/epure/credentials.json (default ~/.config/epure/credentials.json), mode 0600, written atomically and refreshed before expiry.

epure auth login [--device] [--no-browser] [--scope "read:agent write:triage write:admin"]
epure auth status      # local session metadata, never credentials
epure auth whoami      # verify the session with the server
epure auth logout      # revoke the grant and remove the local session
epure auth login --url https://errors.example.com
epure auth instances
epure auth use https://app.epure.sh

# The MCP package has the same verbs:
npx -y @epure-sh/mcp login --device --no-browser
npx -y @epure-sh/mcp status
npx -y @epure-sh/mcp logout
  • No pasted credentials. --token, --secret and --api-key are rejected, and a set EPURE_TOKEN stops both clients with OAUTH_ONLY. Tools and commands never start a login on their own; they fail at once with AUTH_REQUIRED.
  • Self-hosted instances need an HTTPS origin; plain HTTP works only on loopback for development. --url or EPURE_URL selects the instance.
  • Desktop apps must run as the same operating-system user that signed in, because the stdio server reads that user's session file.
  • Hosted clients discover OAuth from /.well-known/oauth-protected-resource/mcp. A request without a valid grant gets 401 with a WWW-Authenticate header that names scope="read:agent".
  • Revoking: logout revokes the grant remotely and deletes the local file. If revocation fails, it says so; revoke the app in Settings → Connected apps.

Which OAuth scopes do Epure tools need?

Epure has three OAuth scopes, and the default consent requests all three. read:agent covers reading; write:triage adds issue state changes; write:admin adds setup and workspace administration. Ask for less with --scope "read:agent" or --scope "read:agent write:triage". Workspace roles still apply on top: a Member gets 403 on admin routes even with write:admin.

ScopeAllowsExample tools
read:agentEvery read on /api/v1/*, except invitations and token managementepure_issues_list, epure_issues_context, epure_projects_list, epure_alerts_list, epure_auth_whoami
write:triageResolve, ignore, reopen, update and snooze issues; merge and split; update alertsepure_issues_resolve, epure_issues_snooze, epure_issues_update, epure_alerts_update
write:adminProjects, alert rules, channels, cron monitors, releases, webhooks, members, invitations, connected apps, privacy eraseepure_rules_create, epure_channels_create, epure_monitors_create, epure_projects_delete, epure_privacy_erase

On the hosted server, a tool call that needs a scope the grant lacks returns 403 insufficient_scope naming the scope, and runs nothing.

Which tools does the Epure MCP server expose?

The Epure MCP server names every product action epure_<resource>_<action>, with dots and hyphens turned into underscores. One registry generates the hosted and the npm tool lists, and CI checks them for drift. Resources: projects, issues, rules, channels, monitors, alerts, releases, members, invitations, webhooks, privacy, connected-apps and auth. Four extra tools discover and call the rest. These are the ones an agent uses most:

ToolReturnsAccessUse it when
epure_projects_listProjects and their IDsReadFirst, to get a project_id
epure_auth_whoamiAccount, workspace, role and granted scopesReadDiagnosing access
epure_issues_listPriority-ranked issue queue; filters project_id, environment, q, window; limit 20 by default, 100 at mostRead"What broke in production today?"
epure_issues_contextStack trace, culprit frame, application frames, breadcrumbs, request URL and method, release, environmentReadBefore proposing a fix
epure_issues_showOne issue summaryReadChecking status or counts
epure_issues_events, epure_issues_timeline, epure_issues_releasesEvents, timeline and releases of one issueReadRegression and frequency questions
epure_alerts_listFired alertsRead"Why did I get paged?"
epure_issues_resolve, epure_issues_ignore, epure_issues_reopenUpdated issue; optional resolved_in_releasewrite:triageAfter you confirm a fix
epure_issues_snooze, epure_issues_unsnoozeSnoozed issue; mode such as 4hwrite:triageMuting a known issue
epure_rules_create, epure_channels_create, epure_channels_testAlert rule or channel; channels_test sends a real notificationwrite:adminSetting up alerts
epure_monitors_create, epure_monitors_check_inCron monitor; a check-in changes its statewrite:adminSetting up cron monitoring
epure_discoverTool names and descriptions for task keywords; exact schemas with include_schema: true; no sign-in neededReadThe agent doesn't know which tool fits
epure_actionRuns one discovered operation with validated argumentsPer operationCalling a tool by operation ID
epure_api_catalog, epure_apiRemaining REST routes, called through OAuthPer routeNo named tool fits

Older names. epure_get_issue_context and get_crash_context still call epure_issues_context; epure_list_issues and list_unresolved_issues call epure_issues_list; mark_issue_resolved calls epure_issues_resolve; epure_triage_issue calls epure_issues_update. The 0.1.x names epure_queue and epure_issue_context no longer exist.

The server also offers two prompts, epure-triage and epure-monitoring, and one resource, epure://guide, which explains discovery and safe operation. Every result carries structuredContent plus the same JSON as text.

What does epure_issues_context return?

epure_issues_context returns one issue's brief for the latest event, or for the event ID passed as event. The JSON holds issue (title, status, level, event_count, environment, release, first and last seen), exception_text, culprit, app_stack with vendor frames filtered out, breadcrumbs, request, user_journey, runtime_tags and custom_tags. With format: "markdown" the same facts come as a fix-oriented Markdown brief.

{
  "name": "epure_issues_context",
  "arguments": { "id": "ISSUE_ID", "format": "json" }
}
  • include_payload: true adds the raw event as payload_json. Off by default.
  • include_user: true returns end-user identifiers as stored. Off by default.
  • In a terminal, epure issues context ISSUE_ID prints the Markdown brief; piped or with --json, it prints JSON.

Readable JavaScript frames need source maps: upload source maps.

How do I limit what an agent can do with Epure?

Epure limits an agent at three layers, and the server-side ones always win. The OAuth scope decides what the session may call. On the stdio server, --read-only exposes only read tools (epure_action and epure_api accept GET only), and --toolsets keeps the resources you list. Workspace roles apply last, whatever the client asks for.

npx -y @epure-sh/mcp login --scope read:agent
npx -y @epure-sh/mcp --read-only
npx -y @epure-sh/mcp --toolsets issues,projects
  • Destructive tools (deletes, epure_privacy_erase, epure_webhooks_rotate_secret) refuse to run without confirm: true; the CLI needs --yes, scripts included.
  • Each tool carries readOnlyHint and destructiveHint annotations, so clients can ask before a write.
  • Results larger than 64 KiB are refused with RESPONSE_TOO_LARGE and a hint to narrow the query.

How does Epure handle untrusted event data?

Epure treats everything inside an event as untrusted input, because your users, their browsers and any attacker can write into exception messages, URLs and breadcrumbs. Every MCP session starts with server instructions that say application content is data, never instructions. epure_issues_context leaves out the raw payload and end-user identifiers unless asked. The older hosted tool epure_get_issue_context also wraps its Markdown in an <untrusted_exception_data> block after neutralising code fences, prompt-style tags such as <system> and shell command words.

No filter stops every prompt injection

The MCP specification asks servers to sanitize tool outputs and clients to validate results before they reach the model (MCP tools, security considerations). Keep write tools behind your client's approval prompt, and don't let an agent that reads production errors also run shell commands or send data out without review. The reasoning: give your coding agent production errors safely.

What Epure stores in the first place, including the IP and end-user defaults: Data and privacy.

Which CLI commands does @epure-sh/cli provide?

The Epure CLI @epure-sh/cli provides the epure command, with one verb per resource action and the same names as the MCP tools. Output is a table in a terminal and JSON when redirected, so an agent can parse stdout while diagnostics go to stderr. Destructive commands need --yes, and network failures are never retried on writes.

epure projects list --json --fields id,name
epure issues list --project-id PROJECT_ID --q 'status:unresolved' --limit 20
epure issues context ISSUE_ID
epure issues resolve ISSUE_ID --resolved-in-release v2.1
epure issues snooze ISSUE_ID --mode 4h
epure rules create --project-id PROJECT_ID --name "New errors" --kind issue_created
epure channels test CHANNEL_ID
epure monitors create --project-id PROJECT_ID --slug backup --schedule '0 * * * *' --timezone UTC
epure projects delete PROJECT_ID --yes

# discover flags and schemas, signed out
epure issues --help
epure schema issues.context
epure api-catalog --search noise-policy --limit 10
epure api GET /api/v1/projects/PROJECT_ID/noise-policy
  • Output: --json, --output with json, table or ndjson, and --fields with dotted paths.
  • Input: flags, or --data '{...}', --data @request.json, --data - for stdin. Unknown fields fail before the request.
  • Aliases kept from 0.1.x: login, logout, queue, context, issue show, triage resolve|ignore|reopen|snooze.
Exit codeMeaning
0Success
1Request or runtime failure
2Usage error, missing confirmation, or cancelled
4Sign-in required
5Forbidden

Errors are JSON on stderr with a stable error.code.

When should I use a personal access token instead?

Epure personal access tokens (epure_pat_…) are for scripts and HTTP calls to the Agent API, not for MCP or the CLI. Create one in Settings → Agent tokens (Admin or Owner); it is shown once and carries the same three scopes. Send it as Authorization: Bearer epure_pat_…, keep it out of repositories and agent configuration files, and revoke it there if it leaks. Authentication compares DSN, session and token.

AUTH_REQUIRED (exit code 4)

AUTH_REQUIRED means the Epure client found no session for this instance and this operating-system user. Confirm with npx -y @epure-sh/mcp status (or epure auth status): "authenticated": false. Fix it by running login as the user that starts the MCP client, with the same --url. Verify with npx -y @epure-sh/mcp doctor, which returns "ok": true and your identity.

OAUTH_ONLY

OAUTH_ONLY means a manual credential reached an Epure client that only accepts OAuth: EPURE_TOKEN is set in the environment, or a --token, --secret or --api-key flag was passed. Remove it from the shell profile or the MCP client's env block, then sign in with login. Old 0.1.x setups that passed EPURE_URL and EPURE_TOKEN to a locally built server need this change.

403 insufficient_scope and PERMISSION_DENIED

403 insufficient_scope comes from the hosted Epure server when a tool needs a scope the grant lacks; the WWW-Authenticate header names it. The stdio server and the CLI report the same refusal as PERMISSION_DENIED (exit code 5). Check the granted scopes with epure_auth_whoami, then sign in again with the scope, or keep the task read-only. When the scopes are right and the call still fails, your workspace role blocks the route; an Owner or Admin can change it.

CONFIRM_REQUIRED and TOOLSET_DISABLED

CONFIRM_REQUIRED means an Epure destructive action was called without confirm: true (MCP) or --yes (CLI). Review the action, then repeat it with the flag. TOOLSET_DISABLED, or Unknown or disabled tool, means --read-only or --toolsets hides the operation; change the server arguments, or call epure_discover to see what is enabled.

RESPONSE_TOO_LARGE

RESPONSE_TOO_LARGE means an Epure result passed the 64 KiB ceiling. Narrow it: pass a project_id, lower limit, shorten the window, or fetch one issue's context instead of a list. The ceiling keeps one tool call from filling the agent's context window.

Do I need to paste an API token into Cursor or Claude Code?

No. MCP and the CLI sign in with OAuth in the browser, and the configuration printed by init holds no credential. Personal access tokens exist only for scripts that call the HTTP Agent API.

Can the agent change or delete my data?

Only within the scopes you grant and your workspace role. Sign in with --scope read:agent and run the server with --read-only to give the agent reading only. Destructive tools always need confirm: true.

Do MCP or the CLI send errors to Epure?

No. They read and manage issues. Errors travel from your Sentry SDK through the DSN: point your Sentry SDK at Epure.

The docs I found mention epure-mcp, epure-cli or EPURE_TOKEN. Are those current?

No. The npm packages are @epure-sh/mcp and @epure-sh/cli. The 0.1.x local server built from tools/epure-mcp and the EPURE_TOKEN variable were replaced by OAuth sign-in in 0.2.

Do MCP and the CLI work with self-hosted Epure?

Yes. Pass --url https://errors.example.com to login and to the server or command; the hosted /mcp endpoint stays off on a self-hosted instance unless EPURE_MCP_ENABLED=true. Apache-2.0 covers the client packages; the engine is AGPL-3.0. Cloud plans and the 14-day trial: Epure pricing. How the agent workflow fits the product: read production errors from Claude Code or Cursor.