Files
lda-wf/docs/wf_mcp_operator_manual.md
T

677 lines
24 KiB
Markdown

# 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:
1. proxied upstream MCP capabilities such as `everything.default.echo`
2. local control-plane tools such as `wf.admin.list_sources`
3. 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:
```text
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_connections`
- `wf.admin.add_connection`
- `wf.admin.refresh_connection_catalog`
- `wf.admin.list_sources`
- `wf.admin.inspect_source`
- `wf.admin.get_catalog`
- `wf.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_capabilities`
- `wf.workflow.inspect_capability`
- `wf.workflow.call_capability`
- `wf.workflow.validate_draft`
- `wf.workflow.compile_draft`
- `wf.workflow.patch_draft`
- `wf.workflow.create_artifact_from_draft`
- `wf.workflow.create_artifact_from_plan`
- `wf.workflow.list_artifacts`
- `wf.workflow.inspect_artifact`
- `wf.workflow.save_deployment`
- `wf.workflow.validate_deployment`
- `wf.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_capability` discover
workflow-facing node specs and saved wrappers that can be placed in graphs.
- MCP `tools/list` or harness search-tools discover control tools such as
`wf.workflow.inspect_run`, `wf.workflow.read_run_trace`, draft workspace
mutators, and admin operations. These are not workflow capabilities and will
not appear in `list_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_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`
- `wf.workflow.set_workflow_output_map` (compatibility-only map adapter)
- `wf.workflow.add_step_from_capability`
- `wf.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_capability`
- `workflow.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_draft`
- `wf.workflow.compile_draft`
- `wf.workflow.patch_draft`
- `wf.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. Pass `live_check=true`
only 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 as `source_unreachable` diagnostics.
- `wf.workflow.run_deployment`: execute a saved deployment with input. The
default response is compact and returns `trace_count`; pass `trace_range`
only 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-manual`
- `wf://docs/end-to-end-runbook`
- `wf://docs/troubleshooting`
It also owns short guide prompts such as:
- `wf.docs.operator_guide`
- `wf.docs.workflow_authoring_guide`
- `wf.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:
```text
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:
```text
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
```text
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:
```text
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:
```text
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
```text
wf.admin.list_sources
```
This tells the client what exists and which sources are planner-visible.
### 2. Discover Workflow-Ready Capabilities
```text
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
```text
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
```text
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
```text
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`](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.
1. Discover workflow-ready capabilities with `wf.workflow.list_capabilities`.
2. Inspect the selected capability with `wf.workflow.inspect_capability`.
3. Create a patchable draft with
`wf.workflow.create_draft_workspace_from_capability`.
4. Patch the draft with `wf.workflow.patch_draft_workspace`.
5. Validate the draft with `wf.workflow.validate_draft_workspace`.
6. Save an immutable workflow or wrapper artifact with
`wf.workflow.create_artifact_from_workspace` or
`wf.workflow.create_wrapper_from_workspace`.
7. Save a mutable deployment with `wf.workflow.save_deployment`.
8. Validate the deployment with `wf.workflow.validate_deployment`.
9. Optionally call `wf.workflow.validate_deployment` with `live_check=true`
before a real run.
10. Run with `wf.workflow.run_deployment`.
11. If the run returns `interrupted`, resume with `wf.workflow.resume_run`.
12. Inspect stopped runs with `wf.workflow.inspect_run`; read bounded trace
slices with `wf.workflow.read_run_trace`.
13. 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:
```text
what did upstream MCP connections expose?
```
`get_planner_catalog` is the workflow-planning view. It answers:
```text
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 source
- `wf.docs`: a local documentation source, not a connection
- `wf.std`: a local source, not a connection
- `wf.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.md`](wf_mcp_end_to_end_runbook.md) for one full
connection-to-deployment example
- [`wf_mcp_troubleshooting.md`](wf_mcp_troubleshooting.md) for missing-source,
missing-capability, and unrunnable-deployment cases
- [`wf_mcp_architecture.md`](wf_mcp_architecture.md) for package boundaries and
hot-reload behavior
- [`wf_mcp_capability_sources.md`](wf_mcp_capability_sources.md) for the source
model
- [`workflow_capabilities.md`](workflow_capabilities.md) for raw versus
workflow-facing capability design
- [`workflow_drafts.md`](workflow_drafts.md) for the preferred authoring format
- [`workflow_artifacts.md`](workflow_artifacts.md) for 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:
```json
{
"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:
```json
{
"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:
```json
{
"request": {
"workspace_id": "echo_draft",
"revision": 1,
"name": "echo_v2"
}
}
```