Skip to content

MCP Control Surface for Orcho

MCP is a control surface for Orcho. It lets a client start, observe, diagnose, and decide runs without scraping terminal output.

The shortest complete model is:

Act -> Observe -> Route -> Decision support -> Decide -> Inspect -> Measure

The client drives these capabilities. Orcho core remains the lifecycle authority and durable system of record.

If you have not configured MCP yet, start with Start with MCP. If you are deciding whether MCP is worth the extra orchestration cost, read LLM captain mode. If you are building a client-side lifecycle flow, read Expert MCP control loop.

The same catalog is published to clients as machine-readable workflow recipes and orcho:// resources — see Workflow recipes and resources.

Orientation calls. Run these first so the client knows where runs live and what already needs attention.

ToolPurposeNotes
orcho_workspace_infoWhere Orcho reads/writes runs and which projects appear in recent history.Read-only. Good initial discovery call before tools that need project_dir.
orcho_workspace_stateAdvisory last-observed event cursor per run.Read-only. After a client restart, reuse each run’s last_seq as since_seq instead of replaying from zero.
orcho_workspace_pending_decisionsThe operator’s decision inbox: runs paused on awaiting_phase_handoff.Read-only; limit, include_stale. Recovers pending decisions without chat memory.
orcho_run_historyMost recent runs, newest first.Read-only; limit (default 10), optional project_dir filter.

Pure reads over durable run state — safe to poll on a tight loop.

ToolPurposeNotes
orcho_run_statusSummary snapshot: status, metrics, lineage, next steps.The primary “is this done yet?” check. Merges supervisor truth into meta.status when the pipeline exits early.
orcho_run_metricsRaw metrics.json for one run.Token counts, durations, per-phase breakdown.
orcho_run_events_tailEvents with seq > since_seq, newest last.since_seq, limit (default 25). Cursor-based catch-up after a reconnect; eof=True means nothing remains past next_seq.
orcho_run_events_summaryBounded summary of recent events: what changed, what to do next.since_seq, limit, last_n. The polling default — avoids raw-event spill in the client.
orcho_run_live_statusOne bounded live-status card for a mono run.Branch on state_class: running_phase, running_subtask, awaiting_handoff, terminal_success, terminal_halted, terminal_inconsistent.
orcho_run_watchLong-poll until something meaningful happens.Blocking up to timeout_s (default 3600, ceiling 7200). until = next_event, phase_change, subtask, handoff_or_terminal (default), or terminal.

Lifecycle mutations. Each spawns or signals a detached pipeline process.

ToolPurposeNotes
orcho_run_startSpawn a pipeline run in the background; returns run_id immediately.Async. task or task_file; profile (default feature, supports the auto-detect selector); mock; max_rounds; from_run_plan (reuse a parent run’s approved plan); attach / attach_text / attach_image / attach_binary.
orcho_run_resumeContinue an interrupted run from its checkpoint in a new subprocess.Async spawn. Default is a plain checkpoint resume under the original per-phase runtimes; runtime_override delivers an operator replace decision. See Resume outcomes.
orcho_run_cancelStop a running pipeline.mode="graceful" (SIGTERM: checkpoint flushed, run.interrupted emitted) or mode="hard" (SIGKILL: only completed phases survive). Works on orphans from earlier server lifetimes.

Pure state transitions — these never spawn a process.

ToolPurposeNotes
orcho_phase_handoff_decideResolve a run paused at status=awaiting_phase_handoff.Requires run_id, handoff_id, action; the action is validated against the handoff’s available_actions. Optional feedback, note.
orcho_handoff_adviceAsk the read-only advisor for a recommendation on a paused handoff.Read-only. Returns recommended_action (continue / retry_feedback / halt / continue_with_waiver), confidence, rationale.
orcho_delivery_decideResolve a parked post-release delivery or correction gate.action = approve, apply, fix, skip, or halt. Inspect with orcho_delivery_gate first and honor its available_actions.

Typed projections over evidence the run already recorded — no log scraping.

ToolPurposeNotes
orcho_run_evidenceRead typed evidence slices.slice = all, plan, findings (with severity_min, phases filters), commands, artifacts, errors, sub_runs, receipts, verification_receipts, verification_timeline, verification_cockpit.
orcho_run_diffRead a captured diff.patch artifact.mode = preview (default grouped view), stat, or full; phase, path, max_bytes. Missing artifact is a typed found=False, not an error.
orcho_run_diagnoseClassify a run’s resume situation before acting.Read-only. Call before any risky resume. Returns a typed condition plus the orthogonal control axis (mcp_controllable / inspect_only) with control_reason.
orcho_delivery_gateInspect the post-release delivery / correction gate.Read-only. Returns the gate kind, available_actions, blocked_actions, and default action — the required read before orcho_delivery_decide.

Helpers for preparing runs and discovering what the engine offers.

ToolPurposeNotes
orcho_plan_validateValidate an architect plan document.Exactly one of markdown or path. Same semantics as the pipeline’s own plan-QA gate; parse/DAG failures come back as ok=False with a readable error.
orcho_skills_listDiscover Agent Skills packages visible to a project.Requires project_dir. Walks the multi-source chain; read-only, safe trust gating by default.
orcho_prompts_resolveResolve a prompt template through the project → workspace → core chain.name, optional project_dir. Returns the chain with exists flags and the winning content.
orcho_profiles_listThe catalogue of pipeline profiles.Read-only; reads the canonical v2 profile catalogue and reports a typed diagnostic if it is missing or invalid.
orcho_workflows_listMachine-readable catalogue of workflow recipes.Read-only. Recipes describe how tool calls fit together; the client reads the steps and decides — the server never executes them.

A timed-out orcho_run_watch returns triggered=False with trigger.kind == "timeout". That is observer loss, never run failure: the run keeps executing in its detached process regardless of who is watching. Reconnect with orcho_run_events_summary(since_seq=trigger.seq) and continue from the returned next_seq. Clients whose transport caps tool-call duration should prefer a short bounded watch and reconnect on the cursor rather than holding one long request open.

orcho_run_resume returns a typed resume_outcome instead of guessing:

  • applied — the run was genuinely resumable; the result carries the fresh spawn handle (pid, run_dir, command).
  • Resume blocked, one of three reasons: rejected_terminal (the run is terminal with no resumable lineage — resuming is inert; inspect instead), superseded_by_child (a newer follow-up child continues this run — recommended_run_id names the child to resume instead), or recover_via_source_run (this is a terminal recovery run; durable lineage points at the resumable source run that still owns the retained checkpoint).
  • Pending decision — the run is paused on awaiting_phase_handoff; resolve the handoff with orcho_phase_handoff_decide first, then resume.

Runs started outside this MCP server (for example from the CLI) classify as inspect_only: every observation and inspection tool works, and every mutation tool refuses safely with a typed result before touching the run. orcho_run_diagnose reports this boundary on its control field.

BoundaryWhat works todayWhat not to assume
live statusbounded state card for mono runsno dedicated cross-gate state class in orcho_run_live_status
pending inboxphase handoffs across the workspacenot every delivery or cross-gate decision appears in one inbox
foreign runsstatus, events, evidence, diff, metricsmutation remains inspect_only when this server does not own the supervisor record
cross-project topologystatus/evidence and sub-run inspectiondo not assume mono-run mutation parity through MCP

Use these typed boundaries instead of widening control from prose. When a run is inspect_only, manage it through the surface that owns it and keep MCP as the read/decision-support layer.

The canonical engineering docs live with the code: