Durabull Documentation

BullMQ & Redis MCP Server

Manage BullMQ queues and monitor Redis from ChatGPT, Claude and Codex with Durabull. Inspect jobs, workers, cron schedules, alerts and failure evidence, then recover work with scoped tools.

Durabull exposes a Model Context Protocol (MCP) server on the same origin as the web app and API. The default consent bundle contains read scopes; a small set of non-destructive write tools sits behind dedicated scopes you approve explicitly.

{APP_BASE_URL}/mcp

Example: https://app.durabull.io/mcp

MCP runs inside the unified Durabull API process. The server implements protocol 2026-07-28 with the stable TypeScript SDK v2, and supports older Streamable HTTP clients through a stateless initialize handshake. No transport session ID is required. Clients should reconnect after upgrading; session GET/DELETE return 405.

Connect your assistant

  1. Add a remote MCP server in your client with URL {APP_BASE_URL}/mcp.
  2. Complete the browser sign-in and consent flow when the client opens it.
  3. Start with ping, then list_connections, and pass the chosen connectionId to queue tools.
  4. Request write scopes only for the actions you intend to authorize. Retrying or promoting a job can run application side effects again; review the job before approving those actions.

In Durabull Cloud, use https://app.durabull.io/mcp. For a self-hosted instance, use its public app origin. Clients that support remote OAuth can handle discovery and registration; the authentication section describes the protocol for custom clients.

Claude, ChatGPT, and Codex

Connect the HTTPS endpoint above through Claude's connector settings or ChatGPT's Plugins → Add custom MCP server, then complete OAuth. Start with “Show my Durabull connections.” In MCP Apps hosts, list_connections opens the queue explorer with connection health, queues, jobs, logs, alerts and metrics. It supports light/dark themes, pagination, refresh and fullscreen when the host allows it. ChatGPT Work also exposes sidebar and conversation-panel entrypoints on supported surfaces. Claude Code is text-only; the tools and bundled skills work there without the embedded UI.

The portable plugin and Claude compatibility package live together at plugins/durabull. Install locally in Claude Code with claude --plugin-dir ./plugins/durabull. For Codex/ChatGPT desktop, use the repository marketplace at .agents/plugins/marketplace.json. These files are source packages, not claims of public-directory approval.

For self-hosting, generate both platform configurations from the same endpoint:

bun run mcp:plugin --endpoint https://queues.example.com/mcp --out /tmp/durabull-plugin

The plugin includes nine focused skills:

WorkflowTry asking
Setup“Connect Durabull and show my environments.”
Fleet health“Which production queues need attention?”
Queue triage“Why is the receipt queue backing up?”
Job inspection“Find job 1042 and explain why it failed.”
Recurring schedules“Show cron jobs, timezones and next runs.”
Redis health“Is Redis memory pressure affecting our workers?”
Alert triage“Why did this incident's notification fail?”
Job recovery“Retry this failed job once.”
Queue control“Pause this queue during maintenance.”

The visual explorer includes exact job-ID search across queues, scheduler details, alert delivery attempts, incident breakdowns and rule inspection. Redis views show capacity, CPU, clients, evictions, rejected connections and history coverage; unavailable samples remain gaps. Alert triage also supports requested acknowledgement, resolution and timed rule snoozes.

UI buttons labeled “Ask to…” send a request to the assistant; data-changing tools retain their dedicated scopes and host approval flow. No browser credentials or direct Redis access are used.

What MCP provides

Every tool has a description, behavioral annotations (readOnlyHint, destructiveHint, idempotentHint), and a JSON input schema. All tools except ping also have a JSON output schema and return structuredContent alongside JSON text.

GA status: MCP is implemented on the unified deployment. Before announcing production use, complete the release checklist (staging smoke, config verification). Full GA doc set: GA index (ADR, compliance, security closure, validation evidence).

Read tools

ToolScopePurpose
pingmcp:discoverTransport smoke check
list_connectionsmcp:jobs:readConnections visible to the principal
list_queuesmcp:jobs:readQueue inventory with live counts
get_queuemcp:jobs:readQueue detail, counts, workers
get_connection_overviewmcp:jobs:read (+ optional mcp:failures:read, mcp:diagnostics:read)One-call health check across up to 100 queues
list_jobsmcp:jobs:readPaginated job summaries with state/name/id filters
find_jobmcp:jobs:readLocate a job id across queues
get_jobmcp:jobs:readSafe job detail (redacted payload)
get_job_logsmcp:logs:readPaginated job logs
get_job_stacktracesmcp:logs:readAttempt-indexed stacktraces
explain_job_failuremcp:diagnostics:read + mcp:jobs:read (+ optional mcp:logs:read, mcp:failures:read)Deterministic failure summary; reports skipped evidence
list_scheduled_jobsmcp:jobs:readJob schedulers per queue or across the connection
get_scheduled_jobmcp:jobs:readOne scheduler with template and failure stats
get_workersmcp:jobs:readWorker snapshots
get_queue_metricsmcp:diagnostics:readThroughput metrics window
get_redis_healthmcp:diagnostics:readRedis health sample, thresholds, bounded history
get_failure_eventsmcp:failures:readAlert/failure events with filters
get_alert_eventmcp:failures:readEvent detail with acknowledgement and deliveries
get_alert_summarymcp:failures:readOpen alert counts by queue and rule
list_alert_rulesmcp:failures:readAlert rules with state and open counts
get_alert_rulemcp:failures:readOne rule with recent events

Write tools

Write tools are annotated as non-destructive. State-sensitive actions refuse the wrong state (conflict). They never change job payloads. Removing or purging jobs, obliterating queues, editing job data, and managing schedulers or rules have no MCP scope and cannot be granted.

ToolScopePurpose
retry_jobmcp:jobs:retryRe-enqueue a failed job
promote_jobmcp:jobs:promoteRun a delayed job now
pause_queue / resume_queuemcp:queues:pausePause or resume a queue
resolve_alert_eventmcp:failures:writeManually resolve a firing alert
acknowledge_alert_eventmcp:failures:writeAcknowledge on behalf of the signed-in user (user tokens only)
unacknowledge_alert_eventmcp:failures:writeClear an acknowledgement (user or service-account tokens)
snooze_alert_rule / unsnooze_alert_rulemcp:failures:writeSilence a rule for up to 7 days

Resources and prompts

Resources use durabull:// URIs and are authorized with the same scopes as tools: durabull://server (catalog and granted scopes), durabull://connections, durabull://connections/{connectionId}/queues, durabull://connections/{connectionId}/queues/{queueName}, durabull://connections/{connectionId}/alerts.

ui://durabull/queue-explorer-v1.html is the static MCP App resource (text/html;profile=mcp-app). It requires authenticated discovery access and contains no customer data. Every data request from the app passes the normal tool authorization, redaction, rate limits and audit path.

Prompts package common workflows: triage_failed_jobs, investigate_queue_backlog, alert_activity_review, connection_health_check.

Authentication

Remote MCP clients authenticate with OAuth 2.1 bearer tokens issued by Durabull (Better Auth MCP plugin).

  1. Discover protected resource metadata at GET /.well-known/oauth-protected-resource (or /api/auth/.well-known/oauth-protected-resource).
  2. Register an OAuth client (POST /api/auth/mcp/register). On internet-facing deployments, registration is unauthenticated (rate-limited only) — monitor volume at the edge and prefer pre-provisioned clients where possible.
  3. Send the user through authorization code + PKCE at /api/auth/mcp/authorize with prompt=consent and resource={APP_BASE_URL}/mcp.
  4. The user signs in (if needed) and approves scopes on /consent.
  5. Exchange the authorization code at /api/auth/mcp/token with the same resource value.
  6. Call MCP with Authorization: Bearer <access_token>.

Canonical resource URI:

{APP_BASE_URL}/mcp

APP_BASE_URL must match the public origin clients use to reach /mcp (including port in local dev). Missing operation scopes return 403 with a WWW-Authenticate: Bearer insufficient-scope challenge. Reconnect with the required scopes; tenant and service-account policy denials cannot be fixed by adding scopes alone.

See the MCP OAuth operator guide for HTTP status semantics and discovery endpoints.

Scopes

ScopeGrants
mcp:discoverTransport, ping, prompts, durabull://server
mcp:jobs:readConnection/queue/job/worker/scheduler reads
mcp:logs:readLogs and stacktraces
mcp:failures:readAlert events, rules, summaries
mcp:diagnostics:readQueue metrics and Redis health; required (with mcp:jobs:read) for explain_job_failure
mcp:jobs:retryretry_job
mcp:jobs:promotepromote_job
mcp:queues:pausepause_queue, resume_queue
mcp:failures:writeResolve, acknowledge, and snooze alerts

Authorization requests for the canonical MCP resource always include the five read scopes. Write scopes must be requested explicitly and appear on the consent screen marked "can make changes". Delegated users receive scopes from OAuth consent. Service accounts additionally require explicit policy bindings per tool/scope.

Upgrading from the initial diagnostic release: resolve_alert_event now requires mcp:failures:write. Re-authorize the client with that scope to keep using it; all read tools continue to work with existing tokens.

Safety controls

Authenticated callers still receive:

  • Output redaction — known sensitive keys and URL/token patterns redacted; _mcpSafety.redactionCount when redactions occur
  • Rate limits (production) — independent, continuously refilled budgets for setup/discovery (120 burst, 10/sec), ordinary reads (180 burst, 6/sec), diagnostics (90 burst, 3/sec), and writes (30 burst, 1/sec), keyed by validated user and OAuth client. HTTP ingress has a 600-request burst and 20/sec refill. A 429 reports the next-token delay in Retry-After; it does not impose a fixed one-minute lockout. Limits are per process, and OAuth registration retains its separate limit.
  • Typed errors — tool failures return { error: { code, message } } with code in not_found, validation_error, conflict, forbidden, internal_error; messages are redacted before they leave the server
  • Audit — best-effort mcp_audit_event rows for tool calls (may drop under backpressure; see runbook)

Operators: telemetry signals, SQL examples, and incident playbooks are in the MCP operations runbook.

Local development

Authless mode (DURABULL_AUTHLESS=true) is for local/private setups only. Never enable authless mode on Durabull Cloud. If authless is reachable from a network, set a strong MCP_AUTHLESS_BEARER_TOKEN — the non-production default token is for localhost dev only.

For monorepo dev with the Vite app, set APP_BASE_URL to the web origin (http://localhost:5173) so /mcp and OAuth discovery share one origin (the dev server proxies to the API). For API-only smoke scripts, use the API port (http://localhost:3001 or http://localhost:3000 in Docker).

For test commands and CI evidence, see validation evidence. Run mcp:e2e only against local or staging databases (see runbook).

Deployment and operations

MCP is always on when the Durabull API runs. Platform-specific deploy notes:

Post-deploy smoke and operations: MCP operations runbook.