24 KiB
wf_mcp Operator Manual
This is the short practical map for using the current MCP-facing platform.
Use this document when you need to answer:
- what object am I looking at?
- which tool family manages it?
- what is the normal path from "I connected a server" to "a workflow runs"?
For deeper design notes, follow the links at the end.
What This Server Is
The public MCP server exposes three kinds of things at once:
- proxied upstream MCP capabilities such as
everything.default.echo - local control-plane tools such as
wf.admin.list_sources - local workflow authoring/runtime tools such as
wf.workflow.list_capabilities
Those are different surfaces over one platform. They should not be confused with each other just because MCP transports them all.
The Nouns
| Noun | Meaning | Example |
|---|---|---|
| Connection | A configured upstream MCP account/profile with auth and transport settings. | everything.default |
| Source | A named owner of capabilities. A source may be local or backed by a connection. | wf.std, wf.docs, wf.mcp, everything.default |
| Catalog | A discovered snapshot of backend MCP capabilities. | tools/resources/prompts loaded from everything.default |
| Workflow capability | A workflow-ready NodeSpec contract that graphs can consume. |
wf.std.runtime_error, everything.default.echo |
| Artifact | An immutable saved workflow definition or saved wrapper workflow. | codex_echo_probe version 2 |
| Deployment | A runnable binding from an artifact version to concrete runtime sources. | codex_echo_probe.prod |
The most important split:
connection != source
raw MCP tool != workflow capability
artifact != deployment
The Surfaces
wf.admin
Privileged control plane.
Use it for:
- registering and editing connections
- refreshing backend catalogs
- inspecting configured sources
- reading platform status and events
- mutating config
Typical tools:
wf.admin.list_connectionswf.admin.add_connectionwf.admin.refresh_connection_catalogwf.admin.list_sourceswf.admin.inspect_sourcewf.admin.get_catalogwf.admin.get_planner_catalog
wf.admin is not meant to be a normal workflow dependency.
wf.workflow
Workflow authoring and execution surface.
Use it for:
- discovering workflow-ready capabilities
- inspecting and directly test-calling one capability
- validating, patching, and compiling workflow drafts
- creating saved artifacts from drafts or raw plans
- listing and inspecting saved artifacts
- saving deployments
- validating and running deployments
Typical tools:
wf.workflow.list_capabilitieswf.workflow.inspect_capabilitywf.workflow.call_capabilitywf.workflow.validate_draftwf.workflow.compile_draftwf.workflow.patch_draftwf.workflow.create_artifact_from_draftwf.workflow.create_artifact_from_planwf.workflow.list_artifactswf.workflow.inspect_artifactwf.workflow.save_deploymentwf.workflow.validate_deploymentwf.workflow.run_deployment
Workflow Tool Map
The workflow surface is intentionally split by job. Use the primary path first; the advanced tools exist for debugging, compatibility, or focused repair.
There are two discovery paths:
wf.workflow.list_capabilities/inspect_capabilitydiscover workflow-facing node specs and saved wrappers that can be placed in graphs.- MCP
tools/listor harness search-tools discover control tools such aswf.workflow.inspect_run,wf.workflow.read_run_trace, draft workspace mutators, and admin operations. These are not workflow capabilities and will not appear inlist_capabilities.
Discovery
Primary:
wf.workflow.list_capabilities: compact, paged workflow capability search. It returns names, source ids, outcomes, and top-level field names.wf.workflow.inspect_capability: full contract for one selected capability, including schemas, outcomes, and wrapper authoring hints.wf.workflow.call_capability: REPL-style direct test of one workflow capability or saved wrapper artifact.
Supporting:
wf.workflow.list_artifacts: compact list of saved workflow and wrapper artifacts.wf.workflow.inspect_artifact: full saved artifact payload.wf.workflow.list_deployments: compact list of saved deployment summaries.wf.workflow.inspect_deployment: full deployment payload including source bindings.
Draft Workspaces
Primary:
wf.workflow.create_draft_workspace_from_capability: preferred wrapper bootstrap. It inspects one capability, applies its hints, and creates a revisioned draft workspace.wf.workflow.get_draft_workspace: fetch current revision and optionally the full draft document.wf.workflow.validate_draft_workspace: refresh diagnostics without changing revision.wf.workflow.create_wrapper_from_workspace: save a validated draft workspace as a callable wrapper capability.wf.workflow.create_artifact_from_workspace: save a validated draft workspace as a full workflow artifact.
Focused repair helpers:
wf.workflow.set_draft_namewf.workflow.set_draft_routewf.workflow.set_step_input_bindingswf.workflow.set_step_output_bindingswf.workflow.set_step_input_mapwf.workflow.set_step_output_mapwf.workflow.set_workflow_output_bindingswf.workflow.set_workflow_output_map(compatibility-only map adapter)wf.workflow.add_step_from_capabilitywf.workflow.update_capability_step
These helpers are deliberately narrow. Prefer them over JSON Patch when the caller only needs to edit one common field.
wf.workflow.set_workflow_output_bindings replaces the complete ordered
top-level output projection. Its bindings list can mix graph paths and
literal values. Nested input.* and state.* paths may project missing
output-schema fields from declared source schemas; literal values and
context.* paths require declared output targets. An empty list restores the
implicit same-name state fallback. Use the map tool only for compatibility:
set_workflow_output_map cannot preserve canonical path/value order, literals,
or repeated-source fan-out.
The equivalent JSON-RPC operation is
workflow.draft_workspaces.set_workflow_output_bindings.
wf.workflow.add_step_from_capability accepts metadata and either the legacy
input_map or the preferred ordered input_bindings list. Canonical bindings
may interleave graph paths and literal values.
wf.workflow.update_capability_step accepts a presence-aware update object.
Omitted keys are preserved; explicit null clears desc, retry, or
timeout_seconds. Supplying input replaces the complete canonical input
list, while input: null is rejected. The operation preserves use, routes,
and outputs.
Equivalent JSON-RPC operations:
workflow.draft_workspaces.add_step_from_capabilityworkflow.draft_workspaces.update_capability_step
Advanced workspace tools:
wf.workflow.list_draft_workspaces: find mutable draft sessions.wf.workflow.patch_draft_workspace: apply RFC 6902 JSON Patch with revision checking.wf.workflow.delete_draft_workspace: cleanup abandoned sessions.wf.workflow.create_draft_workspace: store a caller-provided draft directly.wf.workflow.create_minimal_draft_workspace: bootstrap around one capability when the caller already knows schemas and bindings.
Stateless Draft Tools
Use these when the caller can resend the whole draft on every call:
wf.workflow.validate_draftwf.workflow.compile_draftwf.workflow.patch_draftwf.workflow.create_artifact_from_draft
Draft workspaces are usually safer for LLM clients because they avoid a rewrite-the-whole-document loop and preserve optimistic-concurrency revisions.
Artifact And Deployment
Primary:
wf.workflow.save_deployment: bind one saved artifact version to concrete sources.wf.workflow.inspect_deployment: inspect source bindings for one saved deployment.wf.workflow.validate_deployment: check dependency availability and drift. By default, validates against the broker's current source inventory and saved catalog snapshots. This is cheap and side-effect-light. Passlive_check=trueonly when you explicitly want to contact each required upstream source. A live check may spawn stdio MCP servers or perform network I/O. Live-check failures are returned assource_unreachablediagnostics.wf.workflow.run_deployment: execute a saved deployment with input. The default response is compact and returnstrace_count; passtrace_rangeonly when debugging a failed or surprising run.wf.workflow.inspect_run: inspect a durable stopped run without trace detail.wf.workflow.read_run_trace: retrieve only an explicit bounded debug trace slice for a durable run.wf.workflow.resume_run: resume an interrupted durable run when its pinned dependencies remain available.wf.workflow.delete_deployment: remove one mutable deployment binding.
Advanced:
wf.workflow.save_artifact: persist a complete artifact JSON document.wf.workflow.create_artifact_from_plan: raw compiled-plan escape hatch.
create_artifact_from_plan bypasses draft ergonomics. Use it only when the
caller already has a trusted compiled raw workflow plan or is deliberately
testing the lower-level artifact boundary.
delete_deployment removes the saved deployment binding only. It does not delete
workflow artifacts, wrapper artifacts, or run checkpoints.
wf.docs
Local documentation source.
It owns stable documentation resources such as:
wf://docs/operator-manualwf://docs/end-to-end-runbookwf://docs/troubleshooting
It also owns short guide prompts such as:
wf.docs.operator_guidewf.docs.workflow_authoring_guidewf.docs.troubleshooting_guide
This source exists so manuals are discoverable through the same capability model as everything else. The docs themselves are provider-neutral platform resources; MCP is only one projection of them.
Proxied Upstream Tools
These are the upstream MCP tools themselves, projected under connection/source names such as:
everything.default.echo
context7.default.query_docs
They are useful for direct interactive use and for capability discovery. They are not automatically good workflow abstractions; a workflow may want a cleaner wrapper with explicit outcomes and a smaller contract.
Human Operator Workflow
1. Register Or Update A Connection
Use the config/admin surface:
wf.admin.add_connection
wf.admin.update_connection
wf.admin.enable_connection
wf.admin.disable_connection
A connection can exist before any catalog has been fetched. In that state it should still appear as a source with zero discovered capabilities.
2. Refresh Its Catalog
wf.admin.refresh_connection_catalog
This asks the upstream MCP server for its current supported capability families.
tools/list is required for workflow-facing discovery. resources/list and
prompts/list are optional; a server that does not implement them can still be
a valid tools-only source.
3. Inspect The Platform View
Use:
wf.admin.list_sources
wf.admin.inspect_source
wf.admin.get_catalog
wf.admin.get_planner_catalog
Prefer list_sources first. It is the compact inventory. Inspect one source
only when you need its full owned-capability list. The compact response includes
counts plus small preview lists and has_more flags, so clients can usually
choose the next source to inspect without loading every schema.
Use wf.workflow.list_capabilities after that when you need workflow-ready
nodes rather than source ownership. Its rows include source_id, outcomes, and
top-level input/output field names, while full JSON schemas stay behind
wf.workflow.inspect_capability.
Do not use list_capabilities to find MCP control tools. Run/debug helpers such
as wf.workflow.inspect_run and wf.workflow.read_run_trace are ordinary MCP
tools, not graph nodes. Discover them through MCP tools/list, search-tools, or
the tool map in this manual.
wf.workflow.call_capability is the REPL-style test step. Its result is
self-describing: kind is either node_spec or wrapper_artifact,
source_id identifies the owner when applicable, and diagnostics is empty for
successful calls. Failed test calls return a structured diagnostic with
outcome="runtime_error" instead of leaking raw transport exceptions.
4. Manage Saved Workflows
Use wf.workflow.* for artifacts and deployments:
create artifact -> inspect artifact -> save deployment -> validate deployment
Artifacts are immutable saved definitions. Deployments are where those saved definitions bind to concrete runtime sources/accounts.
LLM Client Workflow
An LLM author should usually avoid starting from giant raw catalogs.
1. Discover Sources
wf.admin.list_sources
This tells the client what exists and which sources are planner-visible.
2. Discover Workflow-Ready Capabilities
wf.workflow.list_capabilities
wf.workflow.inspect_capability
Use the compact list first, then inspect only the likely candidates.
This list intentionally excludes control-plane MCP tools. If the client needs to inspect a run, patch a workspace, or call an admin operation, use MCP tool/search discovery instead of workflow capability discovery.
3. Test One Capability Directly
wf.workflow.call_capability
This is the workflow-facing REPL step. It is different from directly calling a
raw upstream MCP tool because it exercises the NodeSpec contract that the
graph would consume.
4. Build And Save
wf.workflow.validate_draft
wf.workflow.create_artifact_from_draft
wf.workflow.save_deployment
Drafts are the preferred interactive authoring format. They compile into raw
workflow plans before saving. Use create_artifact_from_plan only when a caller
already has a compiled raw plan or intentionally wants the low-level escape
hatch.
Artifacts should prefer logical source aliases in saved workflows. Deployments
bind those logical aliases to concrete sources such as context7.default.
5. Validate And Run
wf.workflow.validate_deployment
wf.workflow.run_deployment
Use run_deployment rather than expecting newly saved workflows to appear as
brand-new MCP tools. Many LLM harnesses do not reliably refresh callable tool
schemas mid-session.
The default run_deployment response is intentionally compact. It includes run
status, terminal outcome when available, failed-run error text when available,
output, diagnostics, and trace_count, where trace_count is the total number
of trace entries in the original run. If the caller needs node-level debug
detail, pass an explicit trace_range object such as
{"start": 0, "limit": 10}; otherwise trace entries stay out of the normal
response. Trace entries may include resolved node inputs, node outputs, and
state changes, so treat them as debug payloads rather than ordinary list/summary
data.
Every started deployment receives a durable run_id, including completed and
failed runs. Use inspect_run for the compact stored result and
read_run_trace only for an explicit bounded debug range. Interrupted runs can
be resumed after server/handler recreation; if a pinned source is missing or
disabled, resume_run returns resume_readiness="blocked" without advancing
the execution checkpoint.
The detailed run contract is documented in
durable_run_operations.md. The short rule is:
capture run_id, inspect summaries first, read bounded trace slices only when
debugging, and resume only runs that are actually interrupted.
Primary Workflow Lifecycle
Use this path when an LLM client needs to build, test, and run a saved workflow.
- Discover workflow-ready capabilities with
wf.workflow.list_capabilities. - Inspect the selected capability with
wf.workflow.inspect_capability. - Create a patchable draft with
wf.workflow.create_draft_workspace_from_capability. - Patch the draft with
wf.workflow.patch_draft_workspace. - Validate the draft with
wf.workflow.validate_draft_workspace. - Save an immutable workflow or wrapper artifact with
wf.workflow.create_artifact_from_workspaceorwf.workflow.create_wrapper_from_workspace. - Save a mutable deployment with
wf.workflow.save_deployment. - Validate the deployment with
wf.workflow.validate_deployment. - Optionally call
wf.workflow.validate_deploymentwithlive_check=truebefore a real run. - Run with
wf.workflow.run_deployment. - If the run returns
interrupted, resume withwf.workflow.resume_run. - Inspect stopped runs with
wf.workflow.inspect_run; read bounded trace slices withwf.workflow.read_run_trace. - Delete temporary deployments with
wf.workflow.delete_deployment.
Artifacts are immutable saved definitions. Deployments are mutable environment bindings. Runs are durable stopped execution records. Deleting a deployment does not delete artifacts or existing run records.
Which Tool Do I Use?
| I want to... | Use |
|---|---|
| See configured upstream accounts | wf.admin.list_connections |
| Add or edit an upstream account | wf.admin.add_connection, wf.admin.update_connection |
| Re-fetch what an upstream server exposes | wf.admin.refresh_connection_catalog |
| See all capability owners | wf.admin.list_sources |
| See everything one source owns | wf.admin.inspect_source |
| See raw backend MCP snapshots | wf.admin.get_catalog |
| See planner-visible workflow-ready nodes | wf.admin.get_planner_catalog or preferably wf.workflow.list_capabilities |
| Find one workflow-ready node | wf.workflow.list_capabilities |
| Read one node contract in full | wf.workflow.inspect_capability |
| Test one node directly | wf.workflow.call_capability |
| Validate an authored workflow draft | wf.workflow.validate_draft |
| Apply a targeted fix to a draft | wf.workflow.patch_draft |
| Compile a draft without saving | wf.workflow.compile_draft |
| Save a workflow definition from a draft | wf.workflow.create_artifact_from_draft |
| Save a compiled raw workflow definition | wf.workflow.create_artifact_from_plan |
| List saved workflows/wrappers | wf.workflow.list_artifacts |
| Inspect one saved workflow/wrapper | wf.workflow.inspect_artifact |
| List saved deployments | wf.workflow.list_deployments |
| Inspect one saved deployment | wf.workflow.inspect_deployment |
| Bind a saved workflow to concrete sources | wf.workflow.save_deployment |
| Check whether a deployment can run | wf.workflow.validate_deployment |
| Execute a saved workflow | wf.workflow.run_deployment |
| Inspect a stopped workflow run | wf.workflow.inspect_run |
| Delete a temporary deployment binding | wf.workflow.delete_deployment |
| Read bounded debug trace entries | wf.workflow.read_run_trace |
| Resume an interrupted workflow run | wf.workflow.resume_run |
Common Confusions
get_catalog Versus get_planner_catalog
get_catalog is the backend MCP snapshot view. It answers:
what did upstream MCP connections expose?
get_planner_catalog is the workflow-planning view. It answers:
what workflow-ready node specs can the planner use?
The second includes local workflow sources such as wf.std and wf.mcp; the
first does not.
Source Versus Connection
Every upstream connection becomes a source, but not every source is a connection.
Examples:
everything.default: both a connection and a sourcewf.docs: a local documentation source, not a connectionwf.std: a local source, not a connectionwf.admin: a privileged local source, not a connection
Raw Tool Versus Workflow Capability
A raw MCP tool is shaped for the provider. A workflow capability is shaped for graph composition.
A raw tool can be directly callable and still be an awkward workflow node if it uses provider-specific result envelopes, status strings, or transport-level errors where a graph wants explicit outcomes.
For the common MCP shape content: [{type: "text", text: "..."}], generated
workflow capabilities keep output.content raw. content may contain text,
images, resources, or mixed blocks, so wrapper hints do not invent a top-level
output.text. Add an explicit wrapper/extraction node when a workflow wants a
specific content-block field.
Artifact Versus Deployment
An artifact is the immutable saved workflow definition.
A deployment is the runnable instance that binds it to concrete source choices. Different deployments can point the same artifact version at different MCP accounts.
Read Next
wf_mcp_end_to_end_runbook.mdfor one full connection-to-deployment examplewf_mcp_troubleshooting.mdfor missing-source, missing-capability, and unrunnable-deployment caseswf_mcp_architecture.mdfor package boundaries and hot-reload behaviorwf_mcp_capability_sources.mdfor the source modelworkflow_capabilities.mdfor raw versus workflow-facing capability designworkflow_drafts.mdfor the preferred authoring formatworkflow_artifacts.mdfor immutable artifacts, deployments, and saved workflows as future nodes
Draft Workspace Authoring
Use draft workspaces when a client should iteratively edit one workflow without resending the full draft each turn.
| Need | Tool |
|---|---|
| Start a patchable authoring session | wf.workflow.create_minimal_draft_workspace |
| List existing draft sessions | wf.workflow.list_draft_workspaces |
| Fetch current draft workspace | wf.workflow.get_draft_workspace |
| Patch current draft workspace | wf.workflow.patch_draft_workspace |
| Refresh validation without changing revision | wf.workflow.validate_draft_workspace |
| Change common draft fields without JSON Patch | wf.workflow.set_draft_name, wf.workflow.set_draft_route, wf.workflow.set_step_input_bindings, wf.workflow.set_step_output_bindings, wf.workflow.set_step_input_map, wf.workflow.set_step_output_map, wf.workflow.set_workflow_output_bindings |
| Save final workspace as artifact | wf.workflow.create_artifact_from_workspace |
| Save final workspace as callable wrapper | wf.workflow.create_wrapper_from_workspace |
| Clean up a draft workspace | wf.workflow.delete_draft_workspace |
Workspace patches are optimistic-concurrency guarded. Pass the current
revision from get_draft_workspace; a stale revision returns
revision_conflict and leaves the stored draft unchanged.
Workspace mutation tools use a single request object in MCP Inspector. That
keeps the form grouped and lets the schema describe fields like
input_schema, canonical output, and error_message_source.
Use create_wrapper_from_workspace when the draft is meant to normalize a raw
capability into a reusable workflow-facing wrapper. It is the same validation
path as create_artifact_from_workspace, but the saved artifact kind is fixed
to wrapper.
Minimal example:
{
"request": {
"workspace_id": "echo_draft",
"name": "echo",
"capability_name": "demo.personal.echo_tool",
"input_schema": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
},
"required": ["text"]
},
"state_schema": {
"type": "object",
"properties": {
"echoed": {
"type": "string",
"reducer": "wf.std.replace"
}
}
},
"output_schema": {
"type": "object",
"properties": {
"echoed": {
"type": "string"
}
},
"required": ["echoed"]
},
"input": [
{
"target": "text",
"path": "input.text"
}
],
"output": [
{
"source": "echoed",
"target": "state.echoed"
}
]
}
}
Patch example:
{
"request": {
"workspace_id": "echo_draft",
"revision": 1,
"patch": [
{
"op": "replace",
"path": "/name",
"value": "echo_v2"
}
]
}
}
If you do not want to write JSON Patch by hand, use the focused helpers:
{
"request": {
"workspace_id": "echo_draft",
"revision": 1,
"name": "echo_v2"
}
}