MCP agent operations
This page lives in Guides because the Agents group documents coding agents Shipper launches, while this guide is for agents that consume Shipper over MCP and the people who configure them.
Next-step presentation
Section titled “Next-step presentation”MCP listings group next work as Design, Plan, Implement, Review, Rework, and Ready. Designed simple issues next need Implement; complex or undecided issues next need Plan. Packaged work next needs Review with or without a pull request. Ready means ready for final integration, not shipped. Existing records receive this presentation without migration or reprocessing.
Blocked issues remain in their next-step group with blocker details. New is separate; held and
failed leave the six groups, and closure hold takes precedence. Attention counts overlap pipeline
membership. nextStep and nextStepPipeline add presentation information while completed-stage
fields, filters, reset arguments, and historical records retain their meanings.
Reset previews lead with next work and the literal completed-stage target. Plan drops target
designed for complex or undecided routes; --to planned next needs Implement. A simple Plan drop
refuses without changing route, and a non-failed same-column drop does nothing. Existing eligibility,
confirmations, warnings, and work-preservation guarantees apply.
See Next-step presentation for full count and reset rules and label-description rollout. Descriptions refresh during normal label setup or maintenance; read-only status, list, and view make no label writes.
One source of truth
Section titled “One source of truth”Shipper owns issue identity and content, workflow state, lifecycle history, and issue actions. A GitHub issue mirror is an optional projection of that state, not a peer authority or a fallback when an operation is unavailable.
Start from the intent you need to accomplish and use a Shipper capability. Do not treat a projected GitHub issue as an alternate interface to Shipper-managed state.
Start from effective capabilities
Section titled “Start from effective capabilities”S#42 is a complete, valid Shipper issue reference. A local issue does not need a GitHub issue
number to exist or move through the workflow.
Shipper reports one of three exact postures: GitHub-backed, Remote git without pull requests, or Fully local. Read the operating model in Repository postures instead of reconstructing it from the presence of a remote or issue mirror.
Server startup and local tools support a committed Shipper repository with no remote. They require
neither an authenticated gh nor GitHub reachability. GitHub access is checked only when the
invoked operation needs effective transport, pull-request, or issue-projection
capability. A failure in such an operation does not make local tools unavailable.
Protected workflow operations invoked through MCP spawn protected Shipper CLI stages and therefore inherit the Shipper license boundary. See Licensing and authentication for sign-in, revalidation, and cached-grace behavior.
An initialization failure still starts the MCP server with one stable tool catalog.
shipper_switch_repo remains callable as in-band recovery. Repository reads without
repository_path and all
mutations keep returning the original startup error until recovery succeeds. A valid explicit
repository_path on a repository-scoped read remains usable against that checkout without repairing or
changing the degraded active state.
Recover from a degraded repository startup
Section titled “Recover from a degraded repository startup”Invoke shipper_switch_repo while treating untargeted
repository operations’ original startup error as authoritative until a switch succeeds. Recovery
targets may be absolute paths or paths relative to the server’s current working directory. A target
must already be an existing readable local Git checkout with at least one commit that passes the
same settings, policy, and preflight readiness as a normal startup. A committed local repository
without a remote is a valid switch target; a remote is not required. Never clone, initialize, or
otherwise prepare a checkout as part of recovery.
A failed attempt returns that target’s error, preserves degraded state and the original startup
error, and can be retried immediately. Successful recovery takes effect on the same connection
without restarting the server. Capable clients may receive a tools/list_changed notification, but
clients do not need to relist tools before calling the previously advertised names. The recovered
selection is runtime-only: it does not persist across a server restart.
Every currently delivered repository-scoped read accepts the same optional local-checkout
repository_path:
status, monitor, watch listing/inspection, issue listing/detail/review/session logs, and pull-request
inspection. Omit it to use the active repository. An explicit repository_path uses that checkout’s
local identity and settings for one call, changes no cwd or active/committed server state, does not
count as active-repository work, and preserves the existing successful response shape. Preparation
does not contact GitHub, run preflight, or start a daemon; after preparation, live issue/PR/check
reads retain their ordinary external behavior. Documentation search/get remain target-free.
Switches never wait for active work. A different-repository request immediately refuses with the exact current active-operation count, leaves the active repository unchanged, and queues nothing. The already-active checkout remains an immediate success even while busy. Unrelated calls continue during switch preparation; if one is still active at the final pre-commit recheck, the switch refuses instead of draining it. A concurrent different switch is also refused without queuing.
Issue-stage timeout lifecycle
Section titled “Issue-stage timeout lifecycle”shipper_advance, fresh shipper_groom, and grooming reconstructed by
shipper_answer_question have no MCP-specific whole-run deadline. agentTimeoutMinutes is enforced
independently for each agent attempt; ordinary retries, correction agents, answer waits, projection,
cleanup, recorded-run finalization, and lock release remain part of the child-owned lifecycle. Time
paused awaiting a product-owner answer consumes no agent-running timeout.
A terminal timeout response means the authoritative local agent_timeout record and failed workflow
state already exist, the MCP-attributed run is terminal, and the timed-out run no longer owns the
issue lock. Mirror-on projection failure is repairable debt, not a rollback: the response preserves
the shipper issue reconcile --repair warning while local failure and unlock remain complete. The
report names discarded staged, unstaged, and untracked work and the exact reset action. When it also
names a workflow branch and full revision, only an unchanged ref at that revision survives the
matching same-stage reset; the ephemeral worktree is removed, and the next groom or scaffold run
continues from the commit. Never infer preservation from a branch name alone.
Issue projection is independent
Section titled “Issue projection is independent”Mirror-on adds a GitHub issue view without changing which system is authoritative. A Shipper-managed
issue is one that carries a Shipper local ID such as S#42. mirrorMode is independent of the
repository posture wherever policy validation permits it. In both mirror modes, never use direct
GitHub issue reads or writes as substitutes for Shipper capabilities for a managed issue.
The write and read hazards are different:
- Writes: store-only has no GitHub issue mirror to write. Under mirror-on, a direct GitHub issue write can succeed, exit zero, and render correctly, then be silently reconciled away because the local store governs the issue.
- Reads: store-only has no GitHub issue mirror to read. Under mirror-on, the mirror is a projection that can lag the local store that governs workflow behavior.
This restriction does not apply to ordinary GitHub issues in the same repository that Shipper has never adopted. Those issues do not carry a Shipper local ID and remain ordinary GitHub objects.
For configuration and transition mechanics, use Settings and the State Machine rather than deriving policy from a mirror’s current shape.
Discover the posture and act by intent
Section titled “Discover the posture and act by intent”Call shipper_status and read
configuration.effective.posture, configuration.effective.transport,
configuration.effective.pullRequests, configuration.effective.reviewDelivery (always local), and
configuration.effective.mirrorMode. The posture gives the operating picture; the individual
capabilities tell an agent whether the requested side effect is enabled. Do not infer them from how
an issue reference renders, and do not inspect committed settings out of band.
The map below names unsupported intents explicitly. Omitting them would make the map look incomplete
and encourage an agent to improvise with gh; an explicit absence closes that unsafe fallback and
states the available alternative.
| Intent | Shipper capability and effective boundary |
|---|---|
| Discover posture, capabilities, and mirror mode | shipper_status |
| Switch repositories or recover from startup failure | shipper_switch_repo remains callable after a repository initialization failure and restores the same connection without a restart. |
| Observe auto-ship desired state and suppression | Read shipper_status.autoShip during orientation. This is a read-only view of enabled, worker-count, halt-request, and durable safety-stop suppression for the active repository. |
| Observe or recover dispatch ownership | Read shipper_status.dispatchOwnership. If held ownership must be discarded, call shipper_clear_dispatch_ownership without input, review the holder and warning, then echo its confirmation_token. |
| Change auto-ship desired state | shipper_set_auto_ship is an explicit machine-local state mutation. Do not call it speculatively during orientation. |
| Resume auto-ship after a safety stop | shipper_resume_auto_ship clears only the active repository’s durable stop. The active repository is selected at startup or by shipper_switch_repo. |
| Create, read, list, or triage local issues | shipper_create_issue, shipper_get_issue, and shipper_list_issues work in all three postures. |
| Browse a locally held review round | Read compact Reviews with shipper_get_issue, then pass a stable round identity to shipper_get_review_round for full detail. |
| Find issue session transcripts | shipper_get_session_logs returns per-run paths and context for open or closed issues; transcript contents and consolidated workflow logs are outside this capability. |
| Record or retract a durable note | shipper_comment and shipper_retract_comment remain local; mirror-on projects them only when issue projection is enabled. |
| Set priority, close, block, or unblock | Use shipper_set_priority, shipper_close_not_planned, shipper_block, and shipper_unblock. |
| Advance workflow, package, review, or rework | Use shipper_groom at intake and shipper_advance afterward. PR-disabled postures package a local change and retain review and implementation rework locally. |
| Reset or unlock | shipper_reset and shipper_unlock work on local workflow state. |
| Merge the ready change | shipper_merge merges a GitHub PR when PRs are enabled or the recorded local change when they are disabled. |
| Recover a failed packaged change | shipper_recover works in all three postures and dispatches from the raw stored artifact. It commits locally first and reports projection warnings without rolling recovery back. |
| Inspect a pull request and its checks | shipper_get_pr requires effective pullRequests: "github"; omission of mode returns the comprehensive view, while mode: "checks" fetches only checks and applies up to three ten-second retries after an initial no-checks observation; there is no gh fallback when pull requests are disabled. |
| Adopt an existing GitHub issue or pull request | shipper_adopt requires the corresponding GitHub issue or PR capability. It is absent in a fully local repository. |
| Arbitrarily edit a managed issue title or body | No general MCP capability. GitHub is not a fallback. Use grooming at intake, add a durable note for additive context, or report that MCP cannot perform the canonical edit. |
| Have a human author a durable Shipper note | No capability. GitHub is not a durable-note fallback. A linked issue or pull-request comment is transient steering only; purely local work has no external advisory target. |
This table is intentionally organized by intent. The generated MCP reference is the sole authority for the complete, current operation inventory, schemas, results, and errors.
Review browsing is read-only, local-only, unbounded, and available for active, completed, and not-planned issues. Compact Reviews includes optional handling state; full locally held review round reads include complete feedback, stable finding identities and locations, comments, replies, optional handling enrichment, and partial coverage. An issue with no rounds returns explicit empty Reviews, while an unreadable review record reports that section as unavailable without hiding ordinary issue detail. GitHub-sourced inline PR review threads are not shown here; locally retained Shipper review rounds are shown under Reviews.
Auto-ship supervision evidence
Section titled “Auto-ship supervision evidence”Read shipper_status.supervision alongside autoShip, automaticWork, and
supervisorAvailability from an enable response. Registration, enabled intent, pickup, and running
work are separate facts. The diagnosis distinguishes unregistered, unresolvable,
pickup-unconfirmed, supervised, and unknown.
For missing registration: Switch to owner/repo’s checkout and explicitly enable Auto-ship.
For an unavailable registration, correct the reported path/access/identity problem or register its
replacement. Pickup unconfirmed is neutral: check status after roughly five seconds. Available
evidence may not establish the cause. A host connection or a live dispatch owner alone does not
confirm pickup, and a supervised repository may have zero running work. When an enabled repository
leaves supervision, the daemon emits a named warning and auto-ship-supervision-lost diagnostic.
Unreadable registrations are preserved unchanged. Use a build able to read newer records, restore damaged files from a valid copy, or correct the reported storage/lock problem. Do not delete/reset registration information. Readable peers remain visible. Discovery of legacy schema-1 saved intent requires a verified identity mapping; otherwise Desktop reports an unidentified enabled saved record by path. Without surviving identifying evidence, the original name cannot be recovered.
Auto-ship desired state
Section titled “Auto-ship desired state”shipper_status.autoShip observes the active repository without mutation. Its available form has
four required fields: enabled, workerCount, haltRequested, and suppression. The suppression
union is either { suppressed: false } or an engaged value with suppressed: true, engagedAt,
lifetime engagementCount, exactly three distinct qualifying failures, and
resumeTool: "shipper_resume_auto_ship". Each failure is a strict scope variant. Issue conditions
name the Shipper issue with localId, nullable githubIssueNumber, and title; repository
conditions name only the affected objectKey; migrated legacy conditions explicitly say their
identity is unavailable. Every variant exposes a human summary,
cause, qualifying kind, and initial/changed/recurred relation, but no opaque revision, progress
generation, or raw observation count. engagementCount > 1 identifies a recurring
engage/clear/re-trip loop. If the machine-global record cannot be read, the entire section is an
explicit unavailable marker rather than false, one worker, no halt, and no suppression. That
degradation is independent of issue-state degradation and does not carry the issue-reconcile
recovery command. A repository with no record and one explicitly recorded as not enabled have the
same effective observation.
Agents must check suppression before concluding that an enabled repository is dispatching.
Disabled, halted, suppressed, daemon availability, and automatic-work counts are independent facts;
do not collapse them into one dispatch state. The durable stop remains visible even after a daemon
idle-exits.
Halt, disable, and the safety stop are three distinct states:
- Halt is a persistent operator-requested repository hold recorded in
haltRequested. It preserves enablement and worker settings, withdraws queued automatic starts, drains running automatic Ships to their safe checkpoints, blocks every later automatic stage and merge, and survives an idle repository, wind-down completion, and daemon, Desktop, CLI, or machine restart. It ends only through an explicit clear withshipper_clear_auto_ship_haltor ahalt_requested: falseMCP patch. - Disable is
enabled: false. It drains current automatic work and prevents dispatch until Auto-ship is enabled again. Neither disabling nor enabling clears a halt. - The safety stop is the automatic failure safeguard, with its own status and its own recovery
gesture,
shipper_resume_auto_ship. Safety recovery never clears a halt.
Explicit manual work stays available under a repository halt, including hand-driven workflow advances and per-run Pause and Stop actions.
Use shipper_set_auto_ship deliberately to record one or
more values in a single write:
- Every field is literal: fields the patch does not supply are preserved exactly.
- Supply only
worker_countto preserve both enablement and the halt. - Supply
halt_requested: trueto record the persistent hold; enabled and halted is a valid state. - Supply
halt_requested: falsealone as an explicit halt clear without changing enablement. - Supply
enabled: trueandhalt_requested: falsetogether for an atomic enable-and-clear. - Supplying
enabled: truealone never clears a halt. - Repeating enabled over an already-enabled record does not clear an engaged safety stop. Use
shipper_resume_auto_shipfor direct recovery. A genuine not-enabled-to-enabled transition remains the other gesture that clears the stop.
Interpret the result as durable intent plus explicit runtime evidence:
- Enable attempts and reports. Explicit enable registers the resolved checkout before the entire
desired-state patch, then makes a bounded attempt to provide a supervisor. Registration refusal
is a tool error: enablement did not complete, no supplied worker or halt field is written, the
prior enabled setting is unchanged, and no startup is attempted. If a later intent write fails,
registration remains recorded and is disclosed, including in compatibility-refusal text. The result contains exactly one
supervisorAvailabilityoutcome:available,not-started,incompatible, orindeterminate. An incompatible outcome includes the client, daemon, and minimum daemon versions plus which side is stale; a human operator should re-run Shipper installation and surface the result to the agent. Other mutations do not start or attach to a supervisor. A running supervisor normally observes those changes within roughly five seconds. - Halt and disable request safe-checkpoint Stops. A supervisor withdraws queued automatic work
and arms running automatic Ships with
repository-control. Once enabled and unhalted is observed, it retracts only unconsumed repository-control requests; explicit per-run Pause and Stop survive. Runs that already stopped and queue entries already withdrawn are not revived. - Halt responses report intent plus observed evidence. Any patch that sets
halt_requested: truestates whether durable halt intent changed or was already set, states that the hold persists until it is explicitly cleared, and includes the normalizedautomaticWorkstatus the tool actually observed: draining, idle and held, in flight without confirmed draining, or unavailable. No response describes a halt as consumed or automatically cleared. - Clear output is intent, not observation. A halt clear can be recorded with no live supervisor.
It reports
clearedoralready-clear, reports no retraction count, and does not prove which runs were released; use later status observations for runtime evidence. Clearing never restarts already-stopped runs, restores withdrawn queue entries, or replays prior work. - Non-enable changes to untracked repositories persist. A supervisor acts only on repositories it tracks, and the operator has no board surface on which to observe or stop work for an untracked repository. Explicit enable registers the active resolved checkout before its availability attempt.
- Enabled means requested, not dispatching. A persistent halt or a durable safety stop prevents
automatic dispatch across daemon exit and restart without changing the recorded enabled value.
Check
autoShip.haltRequestedandautoShip.suppression; only anavailableoutcome proves a usable supervisor was reached during an enable call. - Auto-merge is separate. Enabling auto-ship advances stages, but nothing merges unless the operator separately enabled Auto-merge.
- The state is machine-global. This machine-global operator state follows the machine and its operator, is not committed repository configuration, and is not shared with collaborators.
shipper_status adds two read-only runtime views. daemon reports advisory instanceId, version,
generation, superseded, and updatedAt facts when running; plain not-running is an ordinary
value. automaticWork reports only the active repository’s inFlight count and drainInProgress
boolean. Combine it with autoShip.haltRequested to distinguish a repository still draining from one
fully held: available evidence with drainInProgress: true is draining, available evidence with no
in-flight work and no drain is fully held, and an unavailable marker means report durable halt intent
only without claiming drain completion. Its unavailable marker is independent from daemon,
issue-state, and desired-state markers, and it never substitutes another repository’s row or
identities. Status reads local ownership and
status files only: it never starts or attaches to a daemon, creates a client, or affects daemon
lifetime.
shipper_resume_auto_ship performs one atomic safety-stop clear for the active repository. It
succeeds with outcome: "cleared" when a stop was engaged and with outcome: "not-engaged" as an
idempotent no-op otherwise. It never enables a disabled repository, changes workerCount or
haltRequested, registers a checkout, or starts or coordinates a daemon.
shipper_clear_auto_ship_halt is the separate halt-specific gesture. It takes no input, performs one
{ haltRequested: false } patch for the active repository, and succeeds with outcome: "cleared"
when a halt was recorded and outcome: "already-clear" as an idempotent no-op otherwise. It never
enables Auto-ship, changes workerCount, resumes an engaged safety stop, registers a checkout, or
starts or coordinates a daemon.
Dispatch ownership recovery
Section titled “Dispatch ownership recovery”shipper_status.dispatchOwnership is independent of desired state, suppression, daemon advisory
state, and automatic-work counts. It is not-held, held, or unavailable. A held value contains
exactly five public facts: surface, pid, acquiredAt, liveness, and lastRefreshAt. Surfaces
are desktop, daemon, terminal, or unrecognized; liveness is running or
could-not-determine. Last refresh is diagnostic context only. While dispatch ownership is held,
any other scheduler on this machine stands down rather than dispatching for this repository.
An unrecognized surface is still clearable held ownership. An unavailable value is unknown,
names no holder, and must never be treated as not-held; resolve its local read failure before
recovery. Status reads the active repository’s record locally and neither attaches to or creates a
daemon nor calls GitHub.
shipper_clear_dispatch_ownership is a guarded
two-call operation:
- Call
{}.confirmation_requiredreturns the same five facts, an opaqueconfirmation_token, and this warning: Discarding dispatch ownership held by a genuinely running holder means two schedulers will dispatch for this repository concurrently. The first call never mutates.nothing_to_clearis the successful no-op when that preview finds no holder. - After reviewing the facts, call
{ "confirmation_token": "<opaque>" }.clearedreturns the removed holder.unavailablestates that nothing was cleared and requires the read failure to be resolved. - If the stable holder identity changed or the reviewed record vanished,
changedreturns the current observed status and states that nothing was cleared. Discard the prior token and make a fresh tokenless preview; never retry blindly.
The token covers stable repository and holder identity, not renewedAt, liveness, schema version,
or future members. A same-owner refresh therefore remains confirmable, while a successor owner does
not. The tool scopes both calls to the active repository, does not change desired state, and calls
local core storage directly without daemon or GitHub side effects. After a clear, the affected
supervisor reacquires on its normal four-second observation cadence and resumes dispatch; other
repositories remain unchanged.
PR-enabled behavior
Section titled “PR-enabled behavior”In GitHub-backed, packaging produces a GitHub PR and the
stored stage displays as Review. shipper_get_pr without mode loads the
comprehensive summary, merge-state, checks, review, and thread view. Its mode: "checks" branch is
materially lighter: it loads only checks, retaining the no-check startup grace without requesting
summary, review submissions, or inline threads. A direct GitHub pull-request read consults the PR
source of truth and is acceptable only for observations that
shipper_get_pr does not expose.
Anything that changes pull-request or workflow state must go through Shipper. Merge with
shipper_merge, advance stages with
shipper_advance, and establish or restore the pull-request-to-issue
association through the normal Shipper workflow or shipper_adopt.
Merging directly on GitHub leaves the local store believing the work is still in flight.
Acquisition uses the real PR, and Shipper keeps the review as a locally held review round; read it
with shipper_get_review_round.
PR-disabled behavior
Section titled “PR-disabled behavior”In Remote git without pull requests and Fully local, packaging records a pinned local change and displays Review. Review reads its local three-dot diff, retains a locally held review round, and displays Review. Implementation review-rework consumes that held round locally.
shipper_merge operates on the recorded local change and advances
the target branch. With effective transport: "origin", Shipper publishes the advanced target
branch; with transport: "none", the merge remains local. PR inspection, checks, and PR adoption
are unavailable in both postures, and agents must not replace them with direct GitHub
operations. Packaged-change recovery remains available through shipper_recover: it inspects the
pinned local artifact and uses posture-neutral Change Packaged output containing no pull-request
terminology. Remote git without pull requests can still adopt GitHub issues because its origin
transport provides that source; Fully local has no GitHub issue or PR adoption source.
Notes and advisory steering
Section titled “Notes and advisory steering”Shipper has three distinct annotation and steering channels, as described by Protocol:
- Agent-authored
shipper_commentnotes are the durable, retractable, Shipper-owned agent-to-agent record. Use a note to preserve a decision or context that later stages must retain. - Ordinary GitHub issue and pull-request conversation comments are refreshed once at agent-stage entry as transient advisory input. They can steer an agent, but they cannot change Shipper issue or workflow state and are not a durable Shipper decision record.
- Inline pull-request review threads are the separate input channel for implementation review-rework.
Under mirror-on, a human can read an agent-authored note through its GitHub comment projection, but cannot author a durable note that agents treat as Shipper-owned history. The lack of a first-class human writer for durable Shipper notes is a known, deliberate gap. A human can instead leave a comment on a linked GitHub issue or pull request for transient advisory steering. Purely local work with no GitHub issue and no linked pull request has no external advisory target.
Shipper’s deliberate ingestion of those comments at stage entry does not permit an agent to replace a Shipper capability with direct GitHub issue reads. Ordinary comments are bounded advisory input, not an alternate issue-state interface.