Files
lda-wf/docs/wf_mcp_capability_sources.md
T

331 lines
12 KiB
Markdown

# wf_mcp Capability Sources
`wf_mcp` should model capabilities before it models MCP server tool lists.
Tools, workflow node specs, prompts, resources, and admin controls all belong to
a source. The MCP server, workflow planning, and future UI surfaces are
projections of those sources.
If you need the practical "which thing do I call?" view before the domain model,
start with [`wf_mcp_operator_manual.md`](wf_mcp_operator_manual.md).
This avoids the current trap where broker admin tools, proxy admin
tools, workflow node specs, and upstream MCP tools all look like unrelated
systems.
## Core Model
A capability source is a named provider of one or more capability kinds.
The domain model lives in `wf_platform.sources`; `wf_mcp` projects MCP-backed
connections into that model rather than owning the model itself.
```text
CapabilitySource
id: "wf.std" | "wf.docs" | "wf.admin" | "<server>.<account>"
kind: "system" | "connection"
enabled: bool
visibility:
planner: bool
mcp_client: bool
admin_dashboard: bool
permissions:
safe_for_workflow: bool
calls_upstream: bool
mutates_config: bool
mutates_auth: bool
capabilities:
tools
node_specs
reducers
prompts
resources
```
Important rule: a source is not "an MCP tool source." A source owns
capabilities. Each surface decides which capability kinds it projects.
For the distinction between raw capabilities, workflow-facing `NodeSpec`s, and
future saved wrapper artifacts, see
[`workflow_capabilities.md`](workflow_capabilities.md).
## Canonical Sources
### `wf.docs`
Local platform documentation.
- Planner-visible: no.
- MCP-client-visible: yes.
- Admin-dashboard-visible: yes.
- MCP tools: none.
- Workflow safety: not applicable; it owns docs, not workflow nodes.
Current capabilities:
- `prompts`: `wf.docs.operator_guide`, `wf.docs.workflow_authoring_guide`,
`wf.docs.troubleshooting_guide`.
- `resources`: `wf://docs/operator-manual`,
`wf://docs/end-to-end-runbook`, `wf://docs/troubleshooting`.
The documentation resource model lives in `wf_platform`, not in the MCP
projection layer. That lets the same manuals feed MCP resources now and other
surfaces such as a future CLI or UI later.
### `wf.std`
Workflow standard library.
- Planner-visible: yes, for reusable workflow node specs.
- MCP-client-visible: yes, for prompts/resources/manuals.
- Admin-dashboard-visible: yes, for inspection and source toggling.
- MCP tools: normally none.
- Workflow safety: yes.
Expected capabilities:
- `node_specs`: `wf.std.runtime_error`, `wf.std.coalesce`,
`wf.std.default_if_none`, `wf.std.constant`, `wf.std.pick_key`,
`wf.std.truthy`, `wf.std.first_item`, `wf.std.first_item_maybe`,
`wf.std.first_item_or_none`, `wf.std.last_item`, `wf.std.last_item_or_none`,
`wf.std.length`, `wf.std.is_empty`.
- `reducers`: `wf.std.replace`, `wf.std.append`, `wf.std.max`,
`wf.std.merge_object`, `wf.std.set_union`.
- `prompts`: workflow authoring guide, error-handling guide, mapping guide.
- `resources`: reference docs for stdlib node behavior.
### `wf.mcp`
Reserved for future workflow-safe MCP helpers.
`wf.mcp` currently owns no public NodeSpecs. The previous raw
`wf.mcp.call_tool` helper was deleted because it duplicated the proxy tool
surface and used the wrong abstraction for stateful servers. Workflow authors
should use generated connection NodeSpecs, saved wrappers, or
`wf.workflow.call_capability` when they need to test a workflow-facing
capability.
### `wf.admin`
Human/control-plane administration source.
- Planner-visible: no by default.
- MCP-client-visible: no by default.
- Admin-dashboard-visible: yes.
- MCP tools: only when explicitly launched with admin exposure enabled.
- Workflow safety: no.
Expected capabilities:
- `tools`: list sources, enable source, disable source, refresh catalog, list
connections, add/update/remove connections, view config, reload config, inspect
events, and inspect proxy tools.
- `prompts/resources`: admin documentation may be useful later.
This source is privileged. A normal client LLM should not automatically see
tools that can mutate config, auth, or its own available capability set.
### Connection Sources
Each upstream MCP connection is a source, for example `everything.default` or
`fixture.personal`.
- Planner-visible: yes when enabled and allowed.
- MCP-client-visible: yes when enabled and allowed.
- Admin-dashboard-visible: yes.
- MCP tools/resources/prompts: discovered from upstream.
- Workflow node specs: generated wrappers around upstream tools.
Connection sources are the only sources that represent upstream MCP server
snapshots. System sources are local broker capabilities.
A configured connection should still appear as a connection source even when no
catalog snapshot has been loaded yet. In that state the source can have zero
owned capabilities and a description such as `No catalog loaded for ...`; the
absence of discovered capabilities must not make the configured connection
disappear from source inventory.
Connection discovery treats `tools/list` as the required workflow-facing family.
Optional MCP families such as `resources/list` and `prompts/list` may be absent;
servers that return MCP `Method not found` for those methods still refresh as
tool-only sources instead of failing the whole catalog refresh.
## Projections
### Planner Catalog
The planner catalog shows `node_specs` where:
```text
source.enabled
and source.visibility.planner
and capability is safe or explicitly allowed for workflow
```
Examples:
- include `wf.std.runtime_error`
- include `everything.default.echo`
- exclude `wf.admin.disable_source`
### MCP Client Tools
The MCP `tools/list` projection shows `tools` where:
```text
source.enabled
and source.visibility.mcp_client
and capability kind == tool
```
Normal mode should not expose `wf.admin` tools. Admin mode may expose them with
clear names such as `wf.admin.list_sources`.
### MCP Client Prompts And Resources
The MCP `prompts/list` and `resources/list` projections may show documentation
from system sources.
Examples:
- `wf.std.workflow_manual`
- `wf.std.error_handling_guide`
- MCP workflow guides under `wf.docs`
These are MCP-visible without implying the source exposes MCP tools.
### Admin Dashboard
The admin dashboard projection shows sources, visibility, health, auth status,
and privileged operations.
This is the preferred place for source toggling:
- disable an entire source
- enable an entire source
- refresh a source catalog
- update connection config
- log out / replace auth
Dashboard operations should use `wf.admin` capability definitions or Python
control APIs, not ad hoc tool functions copied across broker and proxy modes.
## Implemented Shape
The code now has the first capability-source layer in place.
- `wf_platform.CapabilitySource` owns source metadata, visibility, permissions, and
capability buckets.
- `CapabilitySource` is the mutable runtime registry object; typed
`SourceStatus` and `SourceInventory` snapshots are the serializable domain
projections used at boundaries such as `list_sources()`.
- Executable `NodeSpec` objects stay inside runtime buckets because they hold
Python callables. Inventory exposes `NodeSpecInventory` contracts instead:
names, descriptions, outcomes, schemas, and execution flags, but never the
wrapped function object itself.
- Reducer inventory follows the same rule: executable reducer definitions stay
private, while `ReducerInventory` exposes only reducer names, descriptions,
and config schemas.
- `WfMcpService.capability_sources` is the canonical in-memory registry.
- Planner node lookup reads `CapabilitySource.capabilities.node_specs`
directly; the old `SpecSource` compatibility layer has been removed.
- `wf.std` owns current `wf_authoring.ops` workflow node specs under
`wf.std.*`.
- `wf.mcp` is reserved for future workflow-safe MCP helpers and currently owns
no public NodeSpecs.
- `wf.admin` owns privileged admin capability metadata and is not planner-visible
by default.
- Transparent proxy admin tools now use dotted `wf.admin.*` names through
`LdaNamespace`.
- `wf.admin` and `wf.mcp` are reserved connection ids.
- Planner catalog, `list_available_specs()`, and workflow spec resolution respect
source `enabled` and `visibility.planner`.
Legacy broker MCP tools still expose compatibility names such as
`list_connections` and `get_planner_catalog` on the compatibility-only broker
server constructor. They now reuse the same service-admin registrar as the
public server, with only the visible names changed. The public server projects
service-backed admin tools such as `wf.admin.list_sources` alongside
proxy-backed admin tools under the same `wf.admin.*` namespace.
## Current Code Mapping
Current code has several useful pieces but the boundaries are blurred.
| Current location | Current role | Target source |
| --- | --- | --- |
| `wf_authoring.ops` | reusable workflow node specs | `wf.std.node_specs` |
| `wf_core` built-in reducers | reusable workflow state reducers | `wf.std.reducers` |
| `wf_mcp.broker.service.builtins` | local workflow specs | `wf.std` |
| `wf_mcp.broker.tools` | compatibility wrapper over shared service-admin registration | `wf.admin.tools` |
| `wf_mcp.admin_surface.tools` | shared service-backed admin tool registration | `wf.admin.tools` |
| `wf_mcp.proxy.admin` | proxy-backed public admin tools | `wf.admin.tools` |
| discovered MCP tools | upstream tools and workflow wrappers | connection source |
| broker resources/prompts | catalog/status/planning context | likely `wf.admin` or docs sources |
New source behavior should be added to `CapabilitySource`.
## Naming Rules
Use source ids consistently:
- `wf.std.*` for workflow standard library capabilities.
- `wf.mcp.*` for workflow MCP runtime helpers.
- `wf.admin.*` for privileged control/admin capabilities.
- `<connection_id>.*` for upstream connection capabilities.
Avoid using `wf.mcp_*` for admin tools. `wf.mcp` is reserved for workflow MCP
runtime helpers. Transparent proxy admin tools now use dotted `wf.admin.*`
names.
## Migration Path
1. Keep explicit admin MCP exposure controls on the server surface.
2. Project admin tools from `wf.admin` only when admin MCP exposure is
enabled.
3. Add source-level enable/disable operations backed by `wf.admin`.
4. Add persisted source policy so source visibility survives process restart.
5. Add system prompts/resources for `wf.std` and `wf.mcp` manuals.
The implementation should avoid having separate backend layers define copies of
the same admin/control capabilities.
## Current Inventory Surface
`list_sources()` is the compact source-discovery surface:
- returns paged source summaries with visibility, permissions, and counts
- includes small sorted preview name lists per capability kind
- includes `has_more` flags when a preview omits additional owned names
- is intentionally compact enough for progressive discovery
- pairs with `inspect_source(source_id)` for the full owned-capability inventory
Humans and LLM authoring clients should list sources first, then inspect only the
sources they need. Planner projection remains a different **use** of source
metadata, not a second source model.
The summary payload intentionally does not include schemas or executable
contracts:
```json
{
"id": "wf.std",
"node_spec_count": 12,
"reducer_count": 6,
"preview": {
"node_specs": [
"wf.std.coalesce",
"wf.std.constant",
"wf.std.default_if_none"
],
"reducers": ["wf.std.add", "wf.std.append", "wf.std.max"]
},
"has_more": {
"node_specs": true,
"reducers": true
}
}
```
Call `inspect_source("wf.std")` only when those previews indicate the source is
relevant. That keeps large source inventories usable for MCP clients with tight
context windows.