shipper_status
shipper_status
Section titled “shipper_status”Return a structured, repository-level Shipper overview with additive nextStepPipeline counts alongside unchanged completed-stage pipeline counts, including observation health, workflow, configuration, auto-ship posture, Ready merge waits, quota pressure, and supervision delivery health. Ready waits remain non-agent deferrals until their release condition changes. Use shipper_list_issues to drill down to individual issues. Optional repository_path selects an existing local git checkout for this call only; omit repository_path to use the active repository. Target preparation uses that checkout’s local identity and settings without changing active server state, and successful result payloads are unchanged.
When to use
Section titled “When to use”Omit repository_path to use the active repository, or supply a local checkout path in repository_path to select that repository for this call only. Explicit targets remain usable when active startup is degraded, do not count as active-repository work, and never change ambient server state. The successful response shape is identical for active and targeted calls. Design, Plan, Implement, Review, Rework, and Ready name next work. Designed simple issues next Implement; complex or undecided issues next Plan. Packaged work next Review in either PR mode. Ready means ready for final integration, not shipped. New stays separate; held and failed are excluded (hold wins), while blocked, locked, paused, and running retain membership. CLI/MCP retain six next-step groups; desktop has five columns, with Implement combining Implement and Rework for the same population and attention exclusions. Current nextStep and nextStepPipeline are additive; completed-stage pipeline fields, labels, filters, commands, reset arguments, and historical records retain their meanings. Maintained label descriptions automatically refresh during next normal setup or maintenance, without separate initialization; successful cache skips repeats and force refresh reads again. Read-only status makes no label writes. observationHealth carries only this repository’s normal/waiting/busy/warning/error/inactive/unconfirmed evidence, continuous episode age, latest reason, unfinished phase, and actual next observation or no next observation scheduled. Healthy busy means one or more automatic workflows are running; the reason gives their count and says remote observation resumes when idle. Healthy busy has no observation-recovery actions. After the last workflow ends, an unresolved ordinary remote observation gets a fresh five-minute warning grace. Independently evidenced local-read failures, known observation errors, and stuck inspections retain their timing and applicable recovery guidance. Unrelated known errors appear immediately; unexplained or overdue observation warns after five minutes with spare capacity. Local eligibility is unverified immediately after a failed local read, with immediate diagnostics, warning after 30 seconds, and error after 120 seconds. Ordinary local checks retry approximately every four seconds; the first successful local check clears this condition automatically without Resume, acknowledgement, or restart, even if later GitHub work fails. localEligibility records verification, last success, first/latest failure, consecutive failed checks, cause, severity, and the separate next local check or blocking reason. heartbeat retains the original deadline, blocked/observing progress, last attempt, next remote opportunity, and last completed observation; overdue work completes once without catch-up bursts. Existing quota, ownership, safety, halt, pause, and capacity controls still apply. Disabled health is inactive with no retry promise; restart or re-enable begins unverified with a fresh episode while diagnostic history remains. Unrelated unexplained observation still warns after five minutes. Legacy and restarted health remains unconfirmed until fresh evidence. Use terminal shipper auto-ship retry-observation or the board’s Retry observation; persistent unfinished work offers shared-daemon Restart daemon if idle. Stop first and run again only after confirmed normal stop; real workflow/persistence blockers are shown only by that deliberate action. Status itself never retries, starts a daemon, or changes controls. Inspect dispatchOwnership as a distinct local repository fact: not-held, held, or unavailable. Held includes only surface, PID, acquiredAt, liveness, and lastRefreshAt. Desktop, daemon, Terminal, and unrecognized are valid surfaces; running and could-not-determine are valid liveness values. Last refresh (diagnostic context only). While dispatch ownership is held, any other scheduler on this machine stands down rather than dispatching for this repository. Unavailable means unknown and names no holder; never infer not-held. Use shipper_clear_dispatch_ownership for the guarded two-call recovery. Status reads ownership locally without GitHub, daemon startup, or daemon attachment. autoShip.launchFailureRetries reports scheduled versus recovery-only posture, repository or issue scope, consecutive attempts, latest issue/reason/command, and either nextAttemptAt or cooled-scope-change/heartbeat triggers. Episodes persist across restart and notice dismissal; successful starts, issue ineligibility, and disable followed by re-enable apply the selective reset rules, with no manual recovery gesture. autoShip.mergeAttemptability reports durable Ready merge waits. Backoff entries include PR, reason, attempt N of 5, and exact nextAttemptAt. Parked entries include the last reason, firstObservedAt, retained Ready state, that no agent stage ran, and automatic re-evaluation when the pull request is attemptable or its head changes. Concurrent parked waits share one upstream-merge-wait safety occurrence until every included PR releases. Use this repository-orientation tool first to understand workflow counts, work needing attention, operational facts, configuration, resolved repository policy, the active repository’s machine-global auto-ship desired state and durable safety-stop suppression, advisory daemon identity and freshness, active-repository automatic-work counts, repository remoteWatch, and runtime-global quotaPressure. The server block identifies the running MCP process with its semantic version, frozen UTC start time, and an available SHA-256 digest of the loaded bundle or an explicit unavailable identity. The issueState block always reports the supported schema, the observed positive integer or null, and compatible, unknown, or stale-reader compatibility. A stale reader remains a successful structured result: store-dependent facts are unavailable, independent facts remain truthful, and its canonical guidance directs restart or reconnection followed by update or rebuild if a fresh process remains behind. Remote watch is inactive when disabled, active while observing, or quietly quiescent with nextHeartbeatAt; quiescence self-resolves, leaves autoShip.enabled true, is not safety suppression, and has no resume tool. Quota pressure is healthy, guarded, severe, floor, or unknown, always with nextObservationAt; 0 means observation is due now, and the band describes policy without redundant effect booleans or raw counters. Unavailable operational markers mean unknown, never zero or false. Always inspect autoShip.suppression before treating enabled: true as dispatching: { suppressed: false } means no stop is engaged, while the true variant includes engagedAt, lifetime engagementCount, exactly three distinct qualifying failures, and resumeTool: "shipper_resume_auto_ship". Each failure is a strict scope variant: issue conditions contain issue identity, repository conditions contain only the affected objectKey, and migrated legacy conditions state that identity is unavailable. relation identifies an initial, changed, or post-progress recurrence; opaque revisions and raw observation counts are never exposed. An engagement count greater than one identifies a recurring engage/clear/re-trip loop. Suppression remains accurate when daemon.status is not-running, which is an ordinary value. Daemon, automatic-work, remote-watch, and quota unavailable markers are independent of desired-state, suppression, and issue-state degradation. Daemon facts are advisory. Status may briefly attach to a reachable daemon for current supervision delivery health, closes that read-only connection, never starts or mutates the daemon, and may reset the existing client-free idle grace period. Healthy, degraded, and unknown delivery states are all successful structured responses. It makes no GitHub calls and reports counts only except that the three distinct qualifying suppression conditions include their scope-specific operator context and cause; inventory, run, session, lock, and other-repository identities remain excluded; use shipper_list_issues when issue identities are needed. Held is reserved for external-closure decisions. Durable issue-scoped operator pauses are counted separately as operational.issueLocks.operatorPaused, while compatibility held counts active run locks. Mirror pending is the fifth attention condition and reports total, repairable, and notCurrentlyRepairable across active records and retained tombstones; a nonzero count remains a successful read and is repaired with shipper issue reconcile --repair. Missing, unreconciled, malformed, or unsupported local issue state is a successful structured response: affected issue-state values carry explicit unavailable markers and never a false mirror-pending zero, while independent facts remain populated. Auto-ship unreadability independently degrades the entire available section to { status: "unreadable", message }. A future auto-ship schema or valid foreign repository identity instead returns { status: "compatibility-conflict", conflict, message } with the retained path and conflict-specific current-client/install or external-file remedy. Both unavailable forms omit desired state and suppression rather than inventing disabled, one-worker, or unsuppressed defaults, preserve retained bytes, and expose no Shipper repair, reset, or discard gesture. They do not reuse the issue-reconcile command or fail the otherwise valid response. This deliberately differs from shipper status, which exits 1 for degraded issue state. A committed local repository without a remote is supported. Invocation outside a valid inspectable Git repository with at least one commit is an initialization error. mergeStatus reports the durable registry Auto-merge choice even when observation is unavailable, locally observed Ready-stage work separately from verified merge eligibility, and every known active merge hold with its clearing action. Retry timestamps appear only when an admission retry is actually scheduled. Use shipper_set_auto_merge to change the choice; new registrations start off. supervision reports unregistered, unresolvable, pickup-unconfirmed, supervised, or unknown, with enabled intent, address/source/attribution evidence, pickup host identity, reasons, recovery actions, and observedAt. Missing registration says “Switch to owner/repo’s checkout and explicitly enable Auto-ship.” Unresolvable registrations show the actual checkout path/cause and correction. Pickup unconfirmed is neutral and asks for status after roughly five seconds; evidence may not establish its cause. A daemon connection or live owner alone never proves repository pickup or running work. An enabled supervision loss produces a named daemon warning and auto-ship-supervision-lost diagnostic.
Behavior hints
Section titled “Behavior hints”- readOnlyHint: true — The tool only reads state and does not intentionally modify the repository.
- idempotentHint: true — Retrying the same call is expected to be safe once the target state is reached.
- openWorldHint: false — The tool does not reach GitHub or other external systems outside the MCP server.
Input schema
Section titled “Input schema”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| repository_path | string | no | - | Optional repository path to an existing local git checkout to select for this read only. Omit it to read the active repository. |
Output schema
Section titled “Output schema”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| repository | string | yes | - | - |
| automaticStageFailures | array | object (replica unavailable marker) | object (stale-reader unavailable marker) | object (retired snapshots unavailable marker) | yes | - | - |
| issueState | object | yes | - | - |
| configuration | object | yes | - | - |
| nextStepPipeline | object (route-aware next-step counts) | object (replica unavailable marker) | object (stale-reader unavailable marker) | object (retired snapshots unavailable marker) | yes | - | - |
| pipeline | object (workflow-stage counts) | object (replica unavailable marker) | object (stale-reader unavailable marker) | object (retired snapshots unavailable marker) | yes | - | - |
| needsAttention | object (attention counts) | object (replica unavailable marker) | object (stale-reader unavailable marker) | object (retired snapshots unavailable marker) | yes | - | - |
| operational | object | yes | - | - |
| noShipperManagedIssues | boolean | object (replica unavailable marker) | object (stale-reader unavailable marker) | object (retired snapshots unavailable marker) | yes | - | - |
| server | object | yes | - | - |
| autoShip | object (available auto-ship status) | object (invalid auto-ship record marker) | object (unreadable auto-ship record marker) | object (auto-ship compatibility conflict marker) | yes | - | - |
| daemon | object (running advisory daemon status) | object (not-running advisory daemon status) | object (daemon unavailable marker) | yes | - | - |
| automaticWork | object (available automatic-work status) | object (automatic-work unavailable marker) | yes | - | - |
| dispatchOwnership | - | yes | - | - |
| observationHealth | object | object | yes | - | - |
| mergeStatus | object | yes | - | - |
| supervision | object | yes | - | - |
| remoteWatch | object (inactive remote-watch status) | object (active remote-watch status) | object (quiescent remote-watch status) | object (remote-watch unavailable marker) | yes | - | - |
| quotaPressure | object (available quota-pressure status) | object (quota-pressure unavailable marker) | yes | - | - |
| supervisionDeliveryHealth | - | yes | - | - |
Example call
Section titled “Example call”{ "repository_path": "/absolute/path/to/selected/checkout"}Example result
Section titled “Example result”{ "content": [], "structuredContent": { "repository": "owner/repo", "server": { "version": "4.3.2", "buildIdentity": { "status": "available", "value": "sha256:<bundle digest>" }, "startedAt": "2026-09-04T12:00:00.000Z" }, "issueState": { "supportedSchemaVersion": 9, "observedSchemaVersion": 9, "compatibility": { "condition": "compatible" } }, "configuration": { "committedSetup": { "present": true, "trackedPaths": [".shipper/settings.json"] }, "sources": [{ "name": "defaults", "present": true }, { "name": "repo", "present": true, "path": "/repo/.shipper/settings.json" }], "activeSources": ["defaults", "repo"], "effective": { "conventions": "shipper", "mirrorMode": "store-only", "transport": "origin", "pullRequests": "github", "reviewDelivery": "local", "baseIntegration": "rebase", "posture": "GitHub-backed" } }, "nextStepPipeline": { "new": 1, "design": 0, "plan": 0, "implement": 2, "review": 0, "rework": 0, "ready": 1 }, "pipeline": { "new": 1, "groomed": 0, "designed": 0, "planned": 2, "prOpen": 0, "rework": 0, "ready": 1 }, "needsAttention": { "blocked": 1, "held": 1, "failed": 0, "locked": 1, "mirrorPending": { "total": 1, "repairable": 1, "notCurrentlyRepairable": 0 } }, "operational": { "agent": "codex", "cliVersion": { "installed": "4.0.0", "recorded": "4.0.0", "state": "up_to_date" }, "issueLocks": { "held": 1, "operatorPaused": 1, "stale": 0 }, "worktrees": { "active": 1 } }, "noShipperManagedIssues": false, "autoShip": { "enabled": true, "workerCount": 2, "haltRequested": false, "suppression": { "suppressed": false }, "launchFailureRetries": { "recoveryTriggers": ["cooled-scope-change", "heartbeat"], "repository": null, "issues": [] }, "mergeAttemptability": { "backoff": [], "parked": [], "activeOccurrence": null } }, "daemon": { "status": "running", "advisory": true, "instanceId": "550e8400-e29b-41d4-a716-446655440000", "version": "4.0.0", "generation": "generation-123", "superseded": false, "updatedAt": "2026-08-07T12:00:00.000Z" }, "automaticWork": { "status": "available", "inFlight": 2, "drainInProgress": false }, "dispatchOwnership": { "status": "held", "holder": { "surface": "terminal", "pid": 4242, "acquiredAt": "2026-08-07T11:59:00.000Z", "liveness": "running", "lastRefreshAt": "2026-08-07T12:00:00.000Z" } }, "observationHealth": { "status": "unavailable", "reason": "non-daemon-supervisor", "message": "A different live repository supervisor owns dispatch for this repository." }, "remoteWatch": { "state": "quiescent", "nextHeartbeatAt": 1786327200000 }, "quotaPressure": { "band": "guarded", "nextObservationAt": 1786323600000 }, "supervisionDeliveryHealth": { "status": "healthy", "degradedConnectionCount": 0, "attachments": [{ "client": { "kind": "cli", "instanceId": "daemon-control-123" }, "alive": true, "facts": [], "supervisionDelivery": { "status": "not-applicable", "activeScopes": [], "outstandingStateDeliveryCount": 0 } }] } }}
Retired GitHub-number snapshots also return structured degraded success: store-dependent fields carry reason "retired-snapshots" and the full refusal message naming the store and records. These markers omit recoveryCommand: use a Shipper release from before this change to migrate the store before retrying this version, rather than repairing with this version.
Degraded issue-state success example: each unavailable issue-state value is { "status": "unavailable", "reason": "malformed_store", "message": "Local issue-state replica is malformed for owner/repo. Run shipper issue reconcile --repair to import/reconcile it.", "recoveryCommand": "shipper issue reconcile --repair" }; independently available configuration, agent, CLI version, worktree, and autoShip fields remain populated.
Stale-reader success example: "issueState": { "supportedSchemaVersion": 9, "observedSchemaVersion": 10, "compatibility": { "condition": "stale-reader", "guidance": "The running Shipper issue-state reader is stale for owner/repo: observed store schema v10 is newer than supported schema v9. Restart or reconnect the MCP client and server. If a freshly launched server remains incompatible, update the installed Shipper release or rebuild the source checkout before reconnecting. Preserve the issue-state store unchanged." } }, "server": { "version": "4.3.2", "buildIdentity": { "status": "unavailable" }, "startedAt": "2026-09-04T12:00:00.000Z" }; store-dependent values use { "status": "unavailable", "reason": "stale-reader", "message": "The running Shipper issue-state reader is stale for owner/repo: observed store schema v10 is newer than supported schema v9. Restart or reconnect the MCP client and server. If a freshly launched server remains incompatible, update the installed Shipper release or rebuild the source checkout before reconnecting. Preserve the issue-state store unchanged." } with no recovery command, while independent facts remain populated.
Independent auto-ship degradation example: "autoShip": { "status": "unreadable", "message": "<underlying read error>" }. Compatibility example: "autoShip": { "status": "compatibility-conflict", "conflict": { "kind": "unsupported-schema-version", "recordPath": "<retained path>", "retainedSchemaVersion": 5, "currentSchemaVersion": 4, "readableSchemaVersions": [1, 2, 3, 4], "staleSide": "client" }, "message": "<current-client/install remedy>" }. These markers have no desired or suppression fields and no issue-reconcile command.
Dispatch-ownership holder surfaces: "desktop", "daemon", "terminal", and "unrecognized". Liveness is "running" or "could-not-determine". Every held variant has the same five public holder facts and repository-scoped scheduler consequence. An unavailable example is "dispatchOwnership": { "status": "unavailable", "message": "<underlying ownership read error>" }; it names no holder and is not absence. Use shipper_clear_dispatch_ownership for recovery.
No-daemon example: "daemon": { "status": "not-running", "advisory": true }, "automaticWork": { "status": "available", "inFlight": 0, "drainInProgress": false }, "remoteWatch": { "status": "unavailable", "reason": "daemon-not-running", "message": "Remote-watch state is unavailable because no daemon is running." }, "quotaPressure": { "status": "unavailable", "reason": "daemon-not-running", "message": "Shared quota pressure is unavailable because no daemon is running." }, "supervisionDeliveryHealth": { "status": "unknown", "reason": "daemon-not-running", "message": "Supervision delivery health is unavailable because no daemon is running." }. These unavailable values are unknown, not zero, inactive, healthy, or false.
Legacy-daemon example: "remoteWatch" and "quotaPressure" use { "status": "unavailable", "reason": "legacy-daemon-status", "message": "<legacy status explanation>" }; v1/v2 automatic-work facts remain independently usable when present.
Supervision-delivery states are "healthy", "degraded", and "unknown". A connection becomes degraded only after an accepted supervision state write remains incomplete for 10 seconds; equal accepted/completed progress stays healthy during idle or quiescent periods. A degraded result remains a successful structured response and includes degradedConnectionCount plus observed attachment identity, alive, facts, sorted activeScopes, outstandingStateDeliveryCount, and oldestOutstandingStateDelivery scope, ISO acceptedAt, and ageMs. Timing is omitted when no write is outstanding. Resolving the overdue write or removing the connection clears current degradation immediately without acknowledgement or recovery action.
Degraded supervision-delivery example: "supervisionDeliveryHealth": { "status": "degraded", "degradedConnectionCount": 1, "attachments": [{ "client": { "kind": "desktop", "instanceId": "desktop-1" }, "alive": true, "facts": [], "supervisionDelivery": { "status": "degraded", "activeScopes": ["sessions"], "outstandingStateDeliveryCount": 2, "oldestOutstandingStateDelivery": { "scope": "sessions", "acceptedAt": "2026-08-20T00:00:00.000Z", "ageMs": 10000 } } }] }.
Legacy-delivery example: "supervisionDeliveryHealth": { "status": "unknown", "reason": "legacy-peer", "message": "The daemon peer does not report supervision delivery health.", "attachments": [{ "client": { "kind": "desktop", "instanceId": "legacy-desktop" }, "alive": true, "facts": [], "supervisionDelivery": { "status": "unknown", "reason": "legacy-peer", "message": "The daemon peer does not report supervision delivery health." } }] }. Missing legacy health is never inferred healthy. Status may briefly attach to a reachable daemon for this read, closes the connection, never starts or mutates the daemon, makes no GitHub request, and may reset the existing client-free idle grace period.
Remote-watch states: { "state": "inactive" }, { "state": "active" }, or { "state": "quiescent", "nextHeartbeatAt": 1786327200000 }. Quiescence is not safety suppression; it is healthy, wakes automatically, and has no resume tool.
Quota-pressure bands: "healthy", "guarded", "severe", "floor", and "unknown"; each available value includes "nextObservationAt", where 0 means observation is due now.
Durable suppression example: "autoShip": { "enabled": true, "workerCount": 2, "haltRequested": false, "suppression": { "suppressed": true, "engagedAt": "2026-08-07T12:00:00.000Z", "engagementCount": 2, "failures": [{ "scope": "issue", "kind": "terminal-stage-failure", "conditionType": "issue-stage:agent-timeout", "localId": 41, "githubIssueNumber": 141, "title": "Timed out", "summary": "Stage execution failed (agent-timeout)", "cause": "Implementation timed out", "relation": "initial" }, { "scope": "repository", "kind": "terminal-stage-failure", "conditionType": "rewritten-ref", "objectKey": "refs/heads/main", "summary": "Rewritten repository ref refs/heads/main", "cause": "The base ref was rewritten", "relation": "initial" }, { "scope": "issue", "kind": "pending-checks-exhausted", "conditionType": "pending-checks", "localId": 43, "githubIssueNumber": null, "title": "Checks pending", "summary": "Pending checks exhausted for PR #93", "cause": "Checks stayed pending", "relation": "recurred-after-progress" }], "resumeTool": "shipper_resume_auto_ship" } }. Migrated legacy entries use scope and conditionType "legacy-unknown" and explicitly state that identity is unavailable.
Independent daemon/work degradation example: "daemon": { "status": "unavailable", "advisory": true, "reason": "status-unreadable", "message": "<underlying read error>" }, "automaticWork": { "status": "unavailable", "reason": "daemon-facts-unavailable", "message": "Automatic-work facts are unavailable because daemon facts could not be read." }.Error modes
Section titled “Error modes”- Git unavailable: Repository identity could not be established for
. Git is unavailable to the MCP process. Install Git and make it available to that process. After correcting this condition, restart or reconnect the MCP client. - Invalid or uninspectable repository: Repository identity could not be established for
. The path is not a valid inspectable Git repository. Use a valid Git repository or repair the repository’s accessibility or integrity. After correcting this condition, restart or reconnect the MCP client. - Repository has no commits: Repository identity could not be established for
. The repository has no commits. Create an initial commit. After correcting this condition, restart or reconnect the MCP client. - Unexpected local status failure:
- Invalid or unready repository target: Repository identity could not be established for
. The repository has no commits. Create an initial commit. Correct this condition and retry the repository read with repository_path.