111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from wf_core import END
|
|
from wf_mcp.broker import WfMcpService
|
|
from wf_mcp.models import ConnectionConfig, RawWorkflowPlan
|
|
from wf_mcp.sdk import McpSdkAdapter
|
|
from wf_mcp.storage import FileStore
|
|
|
|
FIXTURE_SERVER = (
|
|
Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "mcp_echo_server.py"
|
|
)
|
|
|
|
|
|
async def run_example() -> dict[str, object]:
|
|
"""Discover an MCP tool, compile it into a workflow, and execute it."""
|
|
service = WfMcpService(store=FileStore(Path(".wf_mcp_store") / "example"))
|
|
service.register_connection(
|
|
ConnectionConfig(
|
|
id="fixture.personal",
|
|
server="fixture",
|
|
account="personal",
|
|
metadata={
|
|
"transport": "stdio",
|
|
"command": sys.executable,
|
|
"args": [str(FIXTURE_SERVER)],
|
|
},
|
|
)
|
|
)
|
|
service.register_adapter("fixture", McpSdkAdapter())
|
|
|
|
await service.refresh_connection_catalog("fixture.personal")
|
|
|
|
plan = RawWorkflowPlan.model_validate(
|
|
{
|
|
"name": "mcp_echo_workflow",
|
|
"input_schema": {
|
|
"type": "object",
|
|
"properties": {"text": {"type": "string"}},
|
|
"required": ["text"],
|
|
},
|
|
"state_schema": {
|
|
"type": "object",
|
|
"properties": {"echoed": {"type": "string"}},
|
|
},
|
|
"output_schema": {
|
|
"type": "object",
|
|
"properties": {"echoed": {"type": "string"}},
|
|
"required": ["echoed"],
|
|
},
|
|
"start": "echo",
|
|
"nodes": [
|
|
{
|
|
"id": "echo",
|
|
"type": "node",
|
|
"node": "fixture.personal.echo_tool",
|
|
"input": [
|
|
{
|
|
"target": {"root": "local", "parts": ["text"]},
|
|
"path": {"root": "input", "parts": ["text"]},
|
|
}
|
|
],
|
|
"output": [
|
|
{
|
|
"source": {"root": "local", "parts": ["echoed"]},
|
|
"target": {"root": "state", "parts": ["echoed"]},
|
|
}
|
|
],
|
|
},
|
|
{
|
|
"id": "raise_mcp_error",
|
|
"type": "node",
|
|
"node": "wf.std.runtime_error",
|
|
"input": [
|
|
{
|
|
"target": {"root": "local", "parts": ["message"]},
|
|
"path": {"root": "input", "parts": ["text"]},
|
|
}
|
|
],
|
|
"output": [],
|
|
},
|
|
],
|
|
"edges": [
|
|
{"from": "echo", "outcome": "ok", "to": END},
|
|
{"from": "echo", "outcome": "error", "to": "raise_mcp_error"},
|
|
{"from": "raise_mcp_error", "outcome": "ok", "to": END},
|
|
],
|
|
}
|
|
)
|
|
|
|
run = await service.run_workflow_from_plan(plan, {"text": "hello from MCP"})
|
|
return {
|
|
"status": run.status.value,
|
|
"output": run.output,
|
|
"catalog": service.get_catalog().as_payload(),
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
"""Run the MCP tool workflow example and print the result."""
|
|
import json
|
|
|
|
print(json.dumps(asyncio.run(run_example()), indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|