Repository navigation
feat(status-pages): API v2 and MCP tools - #1930
Merged
Merged
Maple Review Bot / Maple / review
succeeded
Oct 31, 2026 in 2m 14s
Confidence 8/10 · No issues found
🟢 Confidence 8/10 · likely safe to merge. Held at 8 because earlier reviews of this pull request found 6 defects.
no findings · tests covered · risk high −1 · 6/6 new units observable · 6 defects fixed in earlier rounds
Adds v2 CRUD for status pages, components and incidents plus six MCP status-page tools; both are org-scoped, with admin gating on settings, break-glass and publish. Safe to merge. The open McpQueryError issues surfacing from registry.ts are untouched — the diff there only registers the new tools.
/v2/status_pagesand/v2/status_page_incidentsCRUD, admin-gated writes, auditedget_status_pagereturns components, incidents and per-org probe freshness- Agent incident and maintenance writes start as drafts unless
publish=true StatusPagePublisher.heartbeatdelegates the probe query toStatusPageSnapshotBuilder.probesSeenAt
Before merge
- Manual · Confirm the prd deploy provisions and binds
StatusSnapshotsKvandStatusSnapshotsBucketto the api Worker (ApiBindingsLive)
Production impact
Open errors in the changed files (2)
| Issue | Service | Occurrences | File |
|---|---|---|---|
| @maple/mcp/errors/McpQueryError (6 issues) | maple-chat | 1.3k | apps/ai/src/mcp/tools/registry.ts |
| @maple/mcp/errors/McpQueryError (4 issues) | maple-ai | 349 | apps/ai/src/mcp/tools/registry.ts |
After this merges, Maple checks whether they stop.
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/status-pages/StatusPagePublisher.ts |
1.1k | StatusPagePublisher.sweep 526/day, 0.1% errStatusPagePublisher.heartbeat 525/day, 0.0% err |
packages/backend/src/services/status-pages/StatusPageSnapshotBuilder.ts |
525 | StatusPageSnapshotBuilder.probesSeenAt 525/day, 0.0% err |
Telemetry this change adds and removes (7)
- ➕ span name
McpTool.listStatusPages·apps/ai/src/mcp/tools/status-pages.ts:225 - ➕ span name
McpTool.getStatusPage·apps/ai/src/mcp/tools/status-pages.ts:286 - ➕ span name
McpTool.createStatusPageIncident·apps/ai/src/mcp/tools/status-pages.ts:421 - ➕ span name
McpTool.postStatusPageUpdate·apps/ai/src/mcp/tools/status-pages.ts:465 - ➕ span name
McpTool.resolveStatusPageIncident·apps/ai/src/mcp/tools/status-pages.ts:510 - ➕ span name
McpTool.scheduleStatusPageMaintenance·apps/ai/src/mcp/tools/status-pages.ts:551 - ➕ span name
StatusPagesService.listOrgIncidents·packages/backend/src/services/status-pages/StatusPagesService.ts:970
What was checked
listOrgIncidentsand every new handler filterOrgId(StatusPagesService.ts:983); a foreign page or incident id failsfindPage/requireIncident- The rotate response's
token_suffixequals the storedtoken.slice(-6)(StatusPagesService.ts:718), and the raw token reaches no span or log - Status/kind mismatches are rejected by
validateStatusForKind(StatusPagesService.ts:1094), so the exposedstatusparameters cannot create impossible states
Observability coverage: 6 of 6 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| /v2/status_pages, components, publish, break-glass routes | inbound HTTP | yes | HttpApiBuilder group handlers, same framework server spans as every other v2 group (status-pages.http.ts:141) |
| /v2/status_page_incidents routes | inbound HTTP | yes | Same framework server spans; handlers call spanned service methods (status-pages.http.ts:444) |
MCP read tools list_status_pages, get_status_page |
inbound tool | yes | Effect.fn("McpTool.getStatusPage") plus annotateCurrentSpan({ orgId, "result.rowCount" }) (tools/status-pages.ts:286) |
| MCP write tools (create/post/resolve/schedule) | inbound tool | yes | Effect.fn("McpTool.*") handlers, mutating hints and open-world marking (tools/status-pages.ts:421) |
StatusPagesService.listOrgIncidents query |
outbound DB | yes | Effect.fn span with orgId tag over dbExecute (StatusPagesService.ts:970) |
StatusPageSnapshotBuilder.probesSeenAt probe read |
outbound DB | yes | Effect.fn("StatusPageSnapshotBuilder.probesSeenAt") over dbExecute (StatusPageSnapshotBuilder.ts:386) |
90344b5 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading