MCP tools reference
Loom MCP exposes 6 tools. Validation, compile, and run operations call shared Loom libraries in-process; the read tools operate on workspace artifacts. All tools return typed JSON.
All tools accept an optional workspace_root compatibility field. When present, it must exactly match the server's canonical startup directory. Requests cannot add roots or use relative or symlink aliases. Every content path is repo-relative and resolved beneath that root before open; rejected paths use WF_TRUSTED_PATH at the offending field. See MCP overview for startup and process-isolation guidance.
Quick reference
| Tool | Purpose | Key inputs |
|---|---|---|
loom_version | Print CLI version | — |
loom_validate | Validate workflow schema | — |
loom_compile | Compile workflow to Graph IR | workflow_path |
loom_run_local | Execute workflow locally | workflow_path, mount_mode, parallel |
loom_read_receipt | Read a run/validation receipt | receipt_path |
loom_read_logs | Read runtime logs by selector | run_id, selector |
loom_version
Print the Loom CLI version string. Use to verify the toolchain is available.
Equivalent Loom action: loom version
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
Output
| Field | Type | Description |
|---|---|---|
version | string | CLI version, e.g. loom v0.0.0-alpha.1 |
Example
// Request
{ "tool": "loom_version" }
// Response
{ "version": "loom v0.0.0-alpha.1" }
loom_validate
Validate the default workflow schema without executing it. Returns a receipt with validation results.
Equivalent Loom action: loom check
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
Output
| Field | Type | Description |
|---|---|---|
status | string | "success" or "failed" |
exit_code | number | Process exit code |
receipt_path | string | Repo-relative path to the validation receipt |
receipt_json | object | Parsed receipt contents |
Example
// Request
{ "tool": "loom_validate" }
// Response
{
"status": "success",
"exit_code": 0,
"receipt_path": ".loom/.runtime/receipts/loom-check-1772050684042246000.json",
"receipt_json": { "..." }
}
See Receipts contract for the receipt schema.
loom_compile
Compile the workflow into Graph IR JSON without executing it. Use to inspect the resolved dependency graph or feed downstream tooling.
Equivalent Loom action: loom compile
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
workflow_path | string | no | Repo-relative workflow YAML path. Defaults to .loom/workflow.yml. |
Output
| Field | Type | Description |
|---|---|---|
graph_ir_json | object | The compiled Graph IR |
warnings | object[] | Compiler warnings (each: code, path, message) |
exit_code | number | Process exit code |
Example
// Request
{ "tool": "loom_compile" }
// Response
{
"graph_ir_json": { "..." },
"warnings": [],
"exit_code": 0
}
loom_run_local
Execute the workflow locally and produce runtime artifacts (logs, receipt). This is the primary "run the pipeline" tool.
Equivalent Loom action: loom run --local
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
workflow_path | string | no | Repo-relative workflow YAML path. Default: .loom/workflow.yml. |
mount_mode | string | no | Docker mount mode: bind_mount or ephemeral_volume. Default: ephemeral_volume. |
parallel | integer | no | Maximum number of concurrently running jobs. Must be positive. Default: 1. |
The mount_mode parameter controls how the workspace is mounted into Docker containers. ephemeral_volume (default) creates a Docker volume, seeds it with workspace contents, and removes the volume after execution (no full workspace sync-back). bind_mount directly mounts the host directory. See Docker provider for details.
The parallel parameter bounds runnable job execution. Dependencies and stage barriers still determine when each job can start. Explicit zero, negative, and non-integer values are rejected before the workflow starts.
Output
| Field | Type | Description |
|---|---|---|
status | string | Public run status: "success", "skipped", or "failed" |
exit_code | number | Public run exit code; a rule skip is 0 and a rule evaluation failure is 1 |
message | string | Value-safe workflow-rule outcome message when an explicit rule contract was evaluated |
workflow_rule | object | Public rule outcome, stable reason, rule index, optional diagnostic code, and message |
receipt_path | string | Repo-relative path to the run receipt |
receipt_json | object | Filtered parsed receipt copy; rule expressions and raw rule errors are omitted |
run_id | string | Run identifier, e.g. loom-run-local-1772050684042246000 |
logs_dir | string | Repo-relative path to the runtime logs directory |
pipeline_summary_path | string | Repo-relative path to pipeline/summary.json when the run emitted pipeline artifacts |
pipeline_manifest_path | string | Repo-relative path to pipeline/manifest.json when the run emitted pipeline artifacts |
phase_report_path | string | Repo-relative path to phase-report.json when the run emitted a phase report |
failing_job_id | string | Job ID of the first failing job (only present on failure) |
failing_job_manifest_path | string | Repo-relative path to the failing job manifest when available |
artifact_pointers | object[] | Array of artifact pointer objects for jobs that produced artifacts. Each pointer can include artifacts_archive_path when an archive was produced. |
Example (success)
// Request
{ "tool": "loom_run_local", "parallel": 4 }
// Response
{
"status": "success",
"exit_code": 0,
"run_id": "loom-run-local-1772050684042246000",
"receipt_path": ".loom/.runtime/receipts/loom-run-local-1772050684042246000.json",
"receipt_json": { "..." },
"logs_dir": ".loom/.runtime/logs/loom-run-local-1772050684042246000"
}
Example (workflow-rule skip)
// Response
{
"status": "skipped",
"exit_code": 0,
"message": "workflow rules skipped execution: no rule matched",
"workflow_rule": {
"outcome": "skip",
"reason": "no_matching_rule",
"rule_index": -1,
"message": "workflow rules skipped execution: no rule matched"
},
"receipt_path": ".loom/.runtime/receipts/loom-run-local-1772050684042246000.json",
"receipt_json": { "..." }
}
The public skipped/0 fields are the MCP control-flow contract. The returned receipt_json is a filtered
copy that omits rule expressions and replaces raw rule errors with the value-safe public message. The
durable receipt at receipt_path remains unchanged and can retain its internal failure/1 envelope; see
workflow rules.
Example (failure)
// Response
{
"status": "failed",
"exit_code": 1,
"run_id": "loom-run-local-1772050684042246000",
"receipt_path": ".loom/.runtime/receipts/loom-run-local-1772050684042246000.json",
"receipt_json": { "..." },
"logs_dir": ".loom/.runtime/logs/loom-run-local-1772050684042246000",
"failing_job_id": "check-pnpm"
}
On failure, use run_id and failing_job_id with loom_read_logs to triage. See the failure triage flow below.
loom_read_receipt
Read and parse a Loom receipt JSON file. Use to inspect structured metadata from a previous run or validation.
Equivalent Loom action: file read + JSON parse
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
receipt_path | string | yes | Repo-relative receipt JSON path beneath the startup root. |
Output
| Field | Type | Description |
|---|---|---|
receipt_json | object | Parsed receipt contents |
run_id | string | Run identifier derived from receipt metadata when present |
logs_dir | string | Repo-relative path to the runtime logs directory when present |
pipeline_summary_path | string | Repo-relative path to pipeline/summary.json when present |
pipeline_manifest_path | string | Repo-relative path to pipeline/manifest.json when present |
phase_report_path | string | Repo-relative path to phase-report.json when present |
failing_job_id | string | Failing job ID inferred from the pipeline manifest when available |
failing_job_manifest_path | string | Repo-relative path to the failing job manifest when available |
artifact_pointers | object[] | Artifact pointer metadata from the pipeline manifest when available |
Example
// Request
{
"tool": "loom_read_receipt",
"receipt_path": ".loom/.runtime/receipts/loom-run-local-1772050684042246000.json"
}
// Response
{
"receipt_json": { "..." }
}
See Receipts contract for what fields to expect.
loom_read_logs
Read Loom runtime logs by run ID and selector. This is the primary tool for failure triage — it navigates the structured log directory so you don't have to.
Equivalent Loom action: structured file reads over .loom/.runtime/logs/<run_id>/
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
workspace_root | string | no | Optional exact canonical startup directory; other values are rejected. |
run_id | string | yes | Run identifier from loom_run_local output. |
selector | string | yes | What to read: pipeline_summary, pipeline_manifest, phase_report, job_summary, job_manifest, or events_jsonl. |
job_id | string | conditional | Required for job_summary and job_manifest. For events_jsonl, omit to auto-infer from failure metadata. |
events_path | string | no | For events_jsonl only: repo-relative path beneath the selected run. Omit to infer it. |
max_lines | number | no | Max lines to return. Default: 200, cap: 2000. Use 30 for focused triage. |
tail | boolean | no | Return the last max_lines events. Recommended for failure triage. |
levels | string[] | no | Filter by log level, e.g. ["error", "warn"]. |
streams | string[] | no | Filter by stream, e.g. ["stderr"] for diagnostics. |
contains | string[] | no | Substring match over message/raw fields. |
Selector reference
| Selector | Reads | Use when |
|---|---|---|
pipeline_summary | Pipeline-level status + exit code | First step: confirm overall pass/fail |
pipeline_manifest | Pipeline pointer doc (job IDs, paths, artifact archive pointers) | Identify which jobs ran, which failed, and where artifacts live |
phase_report | Phase-level summary for the run | Inspect higher-level phase outcomes before drilling into a job |
job_summary | Job-level status + exit code | Drill into a specific job |
job_manifest | Job pointer doc (step paths) | Find the failing step within a job |
events_jsonl | Step-level event stream | Read actual output, errors, diagnostics |
Output
| Field | Type | Description |
|---|---|---|
run_id | string | Echo of the requested run ID |
selector | string | Echo of the requested selector |
job_id | string | Resolved job ID when applicable |
resolved_path | string | Repo-relative path that was read after selector or events-path resolution |
data | object | Parsed JSON for summary, manifest, and phase-report selectors |
events | object[] | Array of event objects for events_jsonl |
line_count | number | Number of lines or events returned |
total_scanned | number | Total lines scanned before filtering |
failing_job_id | string | Failing job ID surfaced for pipeline_manifest when present |
failing_job_manifest_path | string | Repo-relative failing job manifest path surfaced for pipeline_manifest when present |
artifact_pointers | object[] | Artifact pointer metadata surfaced for pipeline_manifest when present |
artifacts | object | Artifacts metadata surfaced for job_manifest when present |
Example: pipeline summary
{
"tool": "loom_read_logs",
"run_id": "loom-run-local-1772050684042246000",
"selector": "pipeline_summary"
}
Example: focused failure triage
{
"tool": "loom_read_logs",
"run_id": "loom-run-local-1772050684042246000",
"selector": "events_jsonl",
"tail": true,
"max_lines": 30,
"streams": ["stderr"]
}
This reads the failing step's events.jsonl, returns the last 30 stderr events, and auto-infers job_id and events_path from the run's failure metadata.
See Runtime logs contract for the full log directory structure and event schema.
Failure triage flow
When loom_run_local returns status: "failed", follow this sequence to identify the root cause with minimal reads.
Step 1 — Confirm overall status
{ "tool": "loom_read_logs", "run_id": "<run_id>", "selector": "pipeline_summary" }
Step 2 — Read the failing step's stderr
The server auto-infers the job and step from failure metadata:
{
"tool": "loom_read_logs",
"run_id": "<run_id>",
"selector": "events_jsonl",
"tail": true,
"max_lines": 30,
"streams": ["stderr"]
}
Step 3 — Widen if needed
If 30 lines of stderr aren't enough, increase the window or drop the stream filter:
{
"tool": "loom_read_logs",
"run_id": "<run_id>",
"selector": "events_jsonl",
"tail": true,
"max_lines": 200
}
Step 4 — Read the receipt for structured metadata
{ "tool": "loom_read_receipt", "receipt_path": "<receipt_path>" }
This follows the same methodology as the Diagnostics ladder but uses MCP tools instead of reading files directly.
What to read next
- MCP overview — setup and workspace root contract.
- Runtime logs contract — log directory structure and event schema.
- Receipts contract — receipt format and fields.
- Diagnostics ladder — the pointer-first triage methodology.