MCP Queue Doctor
概要
作者による説明(英語の原文)
Diagnoses pg-boss and graphile-worker job queues: retry storms, stuck workers, missed schedules.
PopNx MCPの3つの柱
この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。
- 利用者の声iレビューはまだありませんレビューは今後のステップで、アカウント機能と一緒に始まります
- 私たちの基本チェックi2項目中2項目に合格公開情報からチェック。コードはまだスキャンしていません
- 利用状況iとても新しい↓ 54/週 · ★ 0
できること
このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。
- 接続方法: パソコンで動く
- トランスポート: stdio
- カテゴリ: クリニック・健康
インストール
使っているAIアプリを選んで、設定をコピーしてください。
インストールの前に
- 基本チェック:2項目中2項目に合格
- あなたのパソコンで、あなたのユーザーと同じ権限(ファイル、ネットワーク、アプリ)で動きます。
- レジストリには、入力が必要なキーは載っていません。
必要なもの
どのアプリを使っていますか?
上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。
Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます
{
"mcpServers": {
"queue-doctor": {
"command": "npx",
"args": [
"-y",
"mcp-queue-doctor"
]
}
}
}ターミナルでこれを実行します
claude mcp add queue-doctor -- npx -y mcp-queue-doctorまたは、設定を自分でコピーする
プロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます
{
"mcpServers": {
"queue-doctor": {
"command": "npx",
"args": [
"-y",
"mcp-queue-doctor"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
または、設定を自分でコピーする
プロジェクトの .vscode/mcp.json に貼り付けます
{
"servers": {
"queue-doctor": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-queue-doctor"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。
選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。
この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。
使えるアプリ
このサーバーのつなぎ方と、各アプリの公式ドキュメントに基づきます。2026年11月10日に確認。
パソコン上で動かせるアプリ
ClaudeGooseLM StudioMsty StudioCherry StudioCursorVS Code + GitHub CopilotVisual StudioWindsurf (Devin Desktop)ZedKiroClineContinueJetBrains AI AssistantClaude CodeCodex CLIGemini CLIOpenCodenodecodeWarpLibreChatRaycast
できること
パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。
基本チェックi
誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月10日にチェック
- ✓ 合格
作者とリポジトリが一致
レジストリ名は、リポジトリを所有するGitHubアカウント ethanasm で確認済みです
- ✓ 合格
今もメンテナンスされている
コードの最終更新:3 か月前
- … 未チェック
ライセンスがある
このリポジトリはまだGitHubから読み取っていません
- – 対象外
エンドポイントが応答する
これはパソコンで動くため、インターネット上のエンドポイントはありません
- – 対象外
OAuthでサインイン
パソコンで動き、代わりにローカルの設定を使います
- … 未チェック
ツールの説明に隠れた指示がない
パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです
クリニック・健康のほかのサーバーとの比較i
- このカテゴリのほかの1066件のうち0%よりスターが多い
- このカテゴリのほかの1066件のうち25%より最近レジストリに公開
- 基本チェックの結果が、このカテゴリのほかの1066件のうち100%と同じかそれ以上
レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。
よくある質問
MCP Queue Doctorは安全ですか?
当てはまる基本チェック2項目のうち2項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。
どんなキーやコードが必要ですか?
レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。
パソコンで動きますか、それともクラウドですか?
あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。
今もメンテナンスされていますか?
GitHubリポジトリの最終更新は3 か月前、最新バージョン(0.2.2)がレジストリに届いたのは3 か月前です。
どのアプリで使えますか?
Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにNode.jsも必要です。
代わりに使えるものは?
同じカテゴリには:Medplum MCP, Mirobody, Apple Health
代わりの候補
同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。
カードの見方:↓ 週あたりのダウンロードi★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i
Mirobody
Lab results to LOINC codes and UCUM units, symptoms and diagnoses to ICPC-3. Offline, no API key.
Apple Health
Local-first Apple Health MCP server for questions about your sleep, workouts and heart data.
作者のREADME
READMEを開く
作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。
mcp-queue-doctor
An MCP server that diagnoses Postgres job queues — pg-boss and graphile-worker. Retry storms, stuck workers, missed schedules, expiry overruns: what is broken, why, and the safest way to recover.
❌ "3 jobs in enrichment/corpus-fill are in state 'failed'."
✅ "enrichment/corpus-fill failed 140 times over 3m, peaking at 50 failures in a single minute. 91% share one error, which looks like an upstream rate limit. This is one fault reproduced many times, not many separate faults — so the fix belongs at the source, and retrying the jobs individually will reproduce it.
Recovery, safest first:
- Stop enqueuing to this queue — every new job feeds the same failure.
- Confirm when the upstream quota resets; treat that as the time to resume.
- Add a cooldown gate after N consecutive 429s. ⚠ Do NOT bulk-retry yet — the upstream is still limited.
Evidence: 140 failures, 91% 'HTTP 429 Too Many Requests (daily quota exceeded)', peak 50/min, busiest minutes [...], 12 other errors [...]"
The second answer is the product. Every finding carries the evidence it was drawn from, so you — or an agent — can check the reasoning instead of trusting it.
Where the heuristics come from
The rules are extracted from a morning health check that has run daily in production since April 2026 against a pg-boss instance driving ~30 cron queues. Every threshold was tuned by a real false positive or a real missed failure, and each rule below names the incident that motivated it. That provenance is the point: these are not heuristics invented for a README.
Install
npm install -g mcp-queue-doctor
{
"mcpServers": { "queue-doctor": { "command": "mcp-queue-doctor", "env": { "QUEUE_DOCTOR_DATABASE_URL": "postgres://readonly:pw@localhost:5432/app" } } } }
Then ask: *"Is anything wrong with my job queue?"*
Want to see it work first? examples/demo spins up a throwaway Postgres and manufactures seven failures in about a minute. It also plants a graphile-worker instance in the same database, where four of the seven rules go deliberately silent — the clearest way to see what capability declaration actually buys you.
Connecting it
The server speaks stdio, so every MCP client starts it as a subprocess. The only thing that varies is where the config lives — and whether that process can reach your database.
Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows. Use the mcpServers block above, then restart the app.
Desktop launches its subprocesses from the app bundle, not a login shell, so PATH is minimal and a bare mcp-queue-doctor or npx often fails to resolve. Give it an absolute path — which mcp-queue-doctor after a global install, or the absolute path to npx with ["-y", "mcp-queue-doctor"] as its args.
Claude Code — one command, no file editing:
claude mcp add queue-doctor -e QUEUE_DOCTOR_DATABASE_URL=postgres://... -- npx -y mcp-queue-doctor
Add -s project to write a checked-in .mcp.json at the repo root instead of your personal config, so everyone working in that repo gets the tool.
Cloud / remote sessions (Claude Code on the web, and any other headless runner) — a checked-in .mcp.json is the only mechanism that works, because nobody is there to answer an approval prompt. Reference the connection string rather than committing it; Claude Code expands ${VAR} and ${VAR:-default} in .mcp.json:
{
"mcpServers": { "queue-doctor": { "command": "npx", "args": ["-y", "mcp-queue-doctor"], "env": { "QUEUE_DOCTOR_DATABASE_URL": "${QUEUE_DOCTOR_DATABASE_URL}" } } } }
Project-scoped servers still need to be trusted before they start. In a headless session that means setting enableAllProjectMcpServers: true in the repo's .claude/settings.json, since the interactive approval never arrives.
Reachability is the real constraint, not the config. The server runs wherever the client runs, and it connects to Postgres directly — there is no hosted component in between. A cloud sandbox can therefore only diagnose a database inside that sandbox: the demo stack, or a dev stack the session brought up itself. A production queue bound to loopback on your own host is not reachable from a sandbox at all, and exposing it to make it reachable is the wrong trade.
Diagnose production from a client on a machine that already has a route to it — your laptop, over an SSH tunnel:
ssh -N -L 5432:127.0.0.1:5432 prod-host
and point QUEUE_DOCTOR_DATABASE_URL at 127.0.0.1:5432. The tunnel is the access grant, it lasts exactly as long as the terminal stays open, and the credentials never leave your machine.
Tools
| Tool | Answers |
|---|---|
diagnose | Start here. Runs the whole rule catalog, returns ranked findings with evidence and recovery steps |
queue_overview | Per-queue counts by state, stuck jobs, and each queue's expiry/retention/retry config |
failed_jobs | Failures in a window with error messages, plus a per-queue error-frequency breakdown |
stuck_jobs | Jobs active past a threshold, with age, expiry, and heartbeat staleness |
missed_schedules | Cron queues whose latest firing is older than their expression implies |
schedule_status | Every registered schedule with cron, timezone, last firing, and next expected |
job_detail | One job's full record: state, timings, retries, payload, output |
server_info | Connectivity, detected schema, matched dialect, and reduced capabilities |
Schedule expectations are derived from pg-boss's own schedule table by parsing each cron expression, so the common case needs no configuration. The health check this was extracted from carried a hand-maintained list of expected jobs that silently stopped covering whatever nobody remembered to add.
The rule catalog
| Rule | Fires when | Motivating incident |
|---|---|---|
retry-storm | Many failures, densely packed, dominated by one error | A daily API quota tipped over and 875 corpus-fill jobs failed in one night. The count suggested 875 problems; the shape showed one |
expiry-overrun | Failure durations cluster at the queue's expiry | A full-corpus sweep couldn't finish inside a 30-minute expiry once upstream throttling slowed it. It reported as a job failure nightly; the fix was an internal wall-clock budget |
stuck-jobs | Jobs active far too long, or heartbeats stopped | A worker killed without graceful shutdown leaves rows active until maintenance reclaims them |
missed-schedule | Latest firing predates the last expected tick | Distinguishes "never fired" (scheduler never booted) from "stopped firing" |
duplicate-registration | A cron queue enqueued twice for one tick | An instrumentation hook invoked job registration twice per process, so every cron ran double for weeks |
retention-window | Failed-row count disagrees with the windowed count | A health email stayed yellow for days after the bug was fixed, counting rows that failed days earlier |
dead-queue | Registered long ago, unscheduled, holds nothing | A producer that stopped, or a registration dropped in a refactor |
Failures are classified (rate_limit, transient_transport, auth, not_found) because the class changes the advice: the right response to a storm of 429s is close to the opposite of the right response to connection resets.
Backends
| Backend | Support | Verified against |
|---|---|---|
| pg-boss v11+ | Full | 11.1.2 (schema 26), 12.27.0 (schema 37) |
| pg-boss v10 | Recognised, refused — see below | 10.4.2 (schema 24) |
| pg-boss v9 and earlier | Recognised, refused | — |
| graphile-worker 0.17 | Partial, capability-declared | 0.17.3 |
Select with QUEUE_DOCTOR_BACKEND=pgboss (default) or graphile; the schema default follows the backend.
Capabilities, not zeros
Backends don't just name columns differently — they model work differently. graphile-worker deletes a job when it succeeds, has no per-job expiry, no worker heartbeats, and keeps cron expressions in a file rather than the database. So "how many completed in the last day" has no answer there at any price.
Every backend therefore declares what it can answer, and rules that depend on missing data stay silent rather than reporting a zero — a zero reads like a measurement.
| Rule | pg-boss v11+ | graphile-worker |
|---|---|---|
retry-storm | ✅ | ✅ |
stuck-jobs | ✅ (with heartbeats) | ✅ (age only) |
expiry-overrun | ✅ | — no expiry exists |
missed-schedule | ✅ | — cron lives in a file |
duplicate-registration | ✅ | — no firing history |
retention-window | ✅ | — nothing is retained |
dead-queue | ✅ | — no queue registry |
server_info reports the capability set and spells out each limitation.
Versioned against pg-boss
pg-boss's tables are not a stable API. Across versions it has renamed every timestamp column (createdon → created_on), dropped a whole table (archive, removed in v11), changed a duration from an interval to an integer (expire_in → expire_seconds), partitioned the job table, and added columns (heartbeat_on) that materially change what can be diagnosed.
A tool that hard-codes one shape breaks on the next upgrade — silently, if it is unlucky. That is exactly how the health check this is extracted from spent weeks emitting a confident, wrong "missed schedules" warning that was really SQLSTATE 42P01 after pgboss.archive disappeared.
So schema knowledge lives in one file, src/pgboss/dialect.ts, as data:
- Every relation and column name is declared in a dialect. Query builders emit identifiers from it, so supporting a new pg-boss layout is an edit to that file — no SQL elsewhere mentions a pg-boss table by name.
- Dialects are matched on observed shape, not on a version number. pg-boss's release→schema-version mapping is not published as a contract, and a guessed mapping would reintroduce the very failure this guards against. The version integer is read, reported, and used to say *"this is newer than anything we have verified"* — but it never decides which SQL runs.
- Optional columns are feature-detected. No
heartbeat_on? Stuck-job detection degrades to age-based and says so, instead of failing. - Unknown layouts are refused, by name. A pre-v10 schema is recognised specifically and rejected with the reason, because diagnosing it against modern queries would silently miss every archived job. A wrong diagnosis is worse than a refusal.
server_info reports the matched dialect, the schema version, whether that version has been *verified* against real pg-boss, and any reduced capabilities.
This is not a theoretical concern — it has already caught a real bug. The dialect originally claimed a v10 floor, on the belief that v10 removed the archive table. Booting pg-boss 10.4.2 showed the archive table still present and expiry still an expire_in interval, so the dialect was rejecting v10 outright and matching nothing at all for it. The real floor is v11, and v10 now has its own dialect: recognised, and refused by name, because reading the job table alone on v10 silently misses everything already archived.
CI keeps this honest. The integration suite boots pg-boss 10, 11 and 12 into separate schemas and asserts that the observed schema version appears in the dialect's verified list — so a future pg-boss that changes the schema fails loudly rather than running unverified SQL.
Read-only, by construction
Every query runs inside a BEGIN READ ONLY transaction with a statement_timeout