Dumbwaiter MCP: Wait-for-Change
Goal: give Claude a single, stable way to “wait until X happens” on a code host (GitHub now; GitLab next). This skill teaches Claude when and how to use the Dumbwaiter MCP server’s tools.
Prerequisites
- Server: this repo builds a stdio MCP server (
cargo build && target/debug/dumbwaiter-mcp).
- Auth:
export GITHUB_TOKEN=… (repo read permissions are sufficient for commit statuses).
- Persistence (optional):
DUMBWAITER_DB to override ./state/dumbwaiter.sqlite.
- Await settings (optional):
DUMBWAITER_AWAIT_TTL_SECS (default 900), DUMBWAITER_WATCHER=1 to enable background polling.
When to use this skill
- You need to pause orchestration until PR checks turn green, a PR is merged, or checks fail.
- You want durable waits with a
wait_id, cancellable and recoverable after restarts.
- You want progress updates visible to the host via MCP
notify_progress.
Tools overview
wait.start → returns { wait_id } for a condition on a selector
wait.status → returns current state: pending|satisfied|failed|timeout|cancelled|unknown
wait.cancel → cancels a pending wait
wait.await → polls provider with exponential backoff; emits progress notifications; resolves to terminal state or timeout
Selectors and conditions (GitHub)
- selector:
{ "owner": "ORG", "repo": "REPO", "pr": 123 }
- Supported
condition tokens:
checks_succeeded — combined status success
checks_failed — combined status failure/error
pr_merged — merged flag true
pr_approved — at least one approved review
changes_requested — an open review with changes requested
workflow_completed — at least one completed workflow run
comment_received — any new PR comment/review/reaction event (see streaming section below)
For comment_received, optional filters refine which events count. If omitted, since defaults to the wait's created_at timestamp so Dumbwaiter streams everything posted after the wait was created.
Happy-path flow
- Start wait
- name:
wait.start
- arguments:
{ "provider": "github", "selector": {…}, "condition": "checks_succeeded" }
- capture
wait_id
- Await
- name:
wait.await
- arguments:
{ "wait_id": "…" }
- Observe progress notifications; handle final result
- Query or cancel as needed
wait.status or wait.cancel
Guidelines
- Prefer
wait.await when a host can display progress; otherwise poll with wait.status on an interval < backoff cap (default 30s).
- Always report final state back to the orchestrator and link the
wait_id in logs/notes.
- On auth errors or rate limits, surface a clear, actionable message; do not retry aggressively (respect backoff).
- On timeouts, return
timeout with elapsed seconds; let the caller decide next steps.
- Security: never echo tokens; require least scopes.
Streaming GitHub comment events
Set condition to comment_received plus optional filters:
{
"provider": "github",
"selector": { "owner": "acme", "repo": "widgets", "pr": 42 },
"condition": "comment_received",
"filters": {
"since": "2025-01-01T00:00:00Z",
"include_bots": true,
"author_allowlist": ["alice"],
"author_denylist": ["bot"]
}
}
wait.await emits notify_progress for every matching comment/review/reaction (body + URL + reaction counts + code context) before returning the terminal payload that mirrors the streamed events. Use this when an orchestrator needs to react to each individual discussion event.
Examples
- “Wait for PR 42 in acme/widgets until checks pass.”
- start →
{ provider: "github", selector: { owner: "acme", repo: "widgets", pr: 42 }, condition: "checks_succeeded" }
- await →
{ wait_id }
- “Stream every new comment on PR 42 since midnight UTC.”
- start →
{ provider: "github", selector: { owner: "acme", repo: "widgets", pr: 42 }, condition: "comment_received", filters: { since: "2025-01-01T00:00:00Z", include_bots: true } }
- await → receives per-comment progress events plus the final summary payload
Troubleshooting
unknown status: the wait_id was not found (DB purge or wrong project).
- No progress events: confirm host supports MCP notifications and server is connected.
- Auth failures: ensure
GITHUB_TOKEN is set and valid for the target repo.
1---2name: dumbwaiter-mcp3description: Provider-agnostic wait-for-change skill that uses the Dumbwaiter MCP server to wait on PR events (GitHub first) via wait.start/status/cancel/await, with progress notifications and durable state.4---5
6# Dumbwaiter MCP: Wait-for-Change
7
8Goal: give Claude a single, stable way to “wait until X happens” on a code host (GitHub now; GitLab next). This skill teaches Claude when and how to use the Dumbwaiter MCP server’s tools.
9
10Prerequisites
11- Server: this repo builds a stdio MCP server (`cargo build && target/debug/dumbwaiter-mcp`).
12- Auth: `export GITHUB_TOKEN=…` (repo read permissions are sufficient for commit statuses).
13- Persistence (optional): `DUMBWAITER_DB` to override `./state/dumbwaiter.sqlite`.
14- Await settings (optional): `DUMBWAITER_AWAIT_TTL_SECS` (default 900), `DUMBWAITER_WATCHER=1` to enable background polling.
15
16When to use this skill
17- You need to pause orchestration until PR checks turn green, a PR is merged, or checks fail.
18- You want durable waits with a `wait_id`, cancellable and recoverable after restarts.
19- You want progress updates visible to the host via MCP `notify_progress`.
20
21Tools overview
22- `wait.start` → returns `{ wait_id }` for a condition on a selector
23- `wait.status` → returns current state: `pending|satisfied|failed|timeout|cancelled|unknown`
24- `wait.cancel` → cancels a pending wait
25- `wait.await` → polls provider with exponential backoff; emits progress notifications; resolves to terminal state or timeout
26
27Selectors and conditions (GitHub)
28- selector: `{ "owner": "ORG", "repo": "REPO", "pr": 123 }`
29- Supported `condition` tokens:
30 - `checks_succeeded` — combined status success
31 - `checks_failed` — combined status failure/error
32 - `pr_merged` — merged flag true
33 - `pr_approved` — at least one approved review
34 - `changes_requested` — an open review with changes requested
35 - `workflow_completed` — at least one completed workflow run
36 - `comment_received` — any new PR comment/review/reaction event (see streaming section below)
37
38For `comment_received`, optional `filters` refine which events count. If omitted, `since` defaults to the wait's `created_at` timestamp so Dumbwaiter streams everything posted after the wait was created.
39
40Happy-path flow
411) Start wait
42 - name: `wait.start`
43 - arguments: `{ "provider": "github", "selector": {…}, "condition": "checks_succeeded" }`
44 - capture `wait_id`
452) Await
46 - name: `wait.await`
47 - arguments: `{ "wait_id": "…" }`
48 - Observe progress notifications; handle final result
493) Query or cancel as needed
50 - `wait.status` or `wait.cancel`
51
52Guidelines
53- Prefer `wait.await` when a host can display progress; otherwise poll with `wait.status` on an interval < backoff cap (default 30s).
54- Always report final state back to the orchestrator and link the `wait_id` in logs/notes.
55- On auth errors or rate limits, surface a clear, actionable message; do not retry aggressively (respect backoff).
56- On timeouts, return `timeout` with elapsed seconds; let the caller decide next steps.
57- Security: never echo tokens; require least scopes.
58
59## Streaming GitHub comment events
60
61Set `condition` to `comment_received` plus optional filters:
62
63```json
64{
65 "provider": "github",
66 "selector": { "owner": "acme", "repo": "widgets", "pr": 42 },
67 "condition": "comment_received",
68 "filters": {
69 "since": "2025-01-01T00:00:00Z",
70 "include_bots": true,
71 "author_allowlist": ["alice"],
72 "author_denylist": ["bot"]
73 }
74}
75```
76
77`wait.await` emits `notify_progress` for every matching comment/review/reaction (body + URL + reaction counts + code context) before returning the terminal payload that mirrors the streamed events. Use this when an orchestrator needs to react to each individual discussion event.
78
79Examples
80- “Wait for PR 42 in acme/widgets until checks pass.”
81 - start → `{ provider: "github", selector: { owner: "acme", repo: "widgets", pr: 42 }, condition: "checks_succeeded" }`
82 - await → `{ wait_id }`
83- “Stream every new comment on PR 42 since midnight UTC.”
84 - start → `{ provider: "github", selector: { owner: "acme", repo: "widgets", pr: 42 }, condition: "comment_received", filters: { since: "2025-01-01T00:00:00Z", include_bots: true } }`
85 - await → receives per-comment progress events plus the final summary payload
86
87Troubleshooting
88- `unknown` status: the `wait_id` was not found (DB purge or wrong project).
89- No progress events: confirm host supports MCP notifications and server is connected.
90- Auth failures: ensure `GITHUB_TOKEN` is set and valid for the target repo.