Skip to content

Orchestrate engine proceeds silently when MCP server is unavailable #155

Description

@williamthorsen

Problem

The orchestrate engine (orchestrate/SKILL.md) calls MCP tools (init_run, emit_event, register_artifact, complete_run, get_run_state) throughout its pipeline. If the MCP server is not configured or not running, these calls fail silently and the engine continues without producing any structured run state — no run-index.json, no run-log.jsonl, no artifact registration.

This was discovered during ticket #152: a full strict-mode orchestrated run (architecture → planning → implementation → review cycle with 4 reviewers → holistic review) completed successfully, but the run directory contained only markdown artifacts. Zero structured state was persisted. The MCP server had never been registered with Claude Code — the configuration step was omitted during the PR #133 migration.

Root cause

init_run (Run Initialization step 4) is a hard dependency — it returns { runDir, runId, ticketId, timestamp } that all downstream operations depend on. When it fails, the engine falls back to ad-hoc behavior (manually creating directories, tracking state in conversation) without informing the developer. The only MCP call with an explicit fallback is get_run_state (documented at line 485).

Impact

  • Run telemetry is completely lost — no run-index.json for Factory visualization, no run-log.jsonl for event replay
  • Artifact files exist on disk but are not catalogued
  • The developer has no indication that anything is wrong unless they inspect the run directory afterward
  • This is a regression from pre-MCP behavior, where run-index.json was written directly by the orchestrator

Proposed solution

Add an MCP availability guard to the orchestrate engine's Run Initialization step 4, with a preference-controlled policy:

MCP policy (orchestration.mcp_policy)

Value Behavior
prompt (default) Ask the developer: "MCP server unavailable — continue without run tracking?" Default answer: abort.
required Abort immediately with a message explaining how to configure MCP or change the policy.
optional Continue silently with a one-line notice. No run-index.json or run-log.jsonl produced.

Guard mechanism

  1. The existing init_run call in step 4 serves as the probe — if it fails because the tool is not found or the server is not connected, the guard activates
  2. The resolved policy determines whether to abort, prompt, or continue
  3. When continuing without MCP, set {mcp-available} = false and skip all subsequent MCP calls silently (one policy, no per-call-site changes)
  4. Generate run context locally as fallback: resolve {base-dir} from artifact conventions, create {run-dir} via mkdir -p, derive timestamps and IDs locally

Changes scoped to two skill files

  • packages/agents/content/skills/orchestrate/SKILL.md — guard logic, MCP call policy, preference resolution, error handling, constraints update
  • packages/agents/content/skills/orchestrate/modules/review-cycle.md — add {mcp-available} to module Inputs table

No code changes. The MCP server itself is correct.

Acceptance criteria

  • When MCP is unavailable and mcp_policy is prompt (default), the orchestrator asks the developer before proceeding
  • When MCP is unavailable and mcp_policy is required, the orchestrator aborts with a clear message
  • When MCP is unavailable and mcp_policy is optional, the orchestrator continues with a one-line notice
  • When MCP is available, behavior is unchanged (no prompt, no notice)
  • When continuing without MCP, run context is generated locally: {run-dir}, {runId}, {ticketId}, {file-timestamp} are all populated
  • When continuing without MCP, all emit_event, register_artifact, and complete_run calls are skipped silently
  • When continuing without MCP, get_run_state uses its existing conversation-tracked fallback
  • The {change-summary-path} resolution falls back to scanning {run-dir} for *_coder_change-summary.md when MCP is unavailable
  • The MCP availability check is documented as a second exception to the autonomous execution constraint
  • review-cycle.md Inputs table includes {mcp-available}
  • pnpm run check passes at root

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions