5.3 KiB
Server CLI And Transport Boundary
Date: 2026-06-10
Status: first move slice implemented
Related:
- Long-lived workflow API boundary
- Runtime source lifecycle
- Workflow config targets and sources
- Project map
Purpose
wf-rpc-server used to live in wf_transport_rpc_http.cli, but that module did
more than transport work. It parsed server startup config, selected local static
vs MCP-backed composition, handled legacy --mcp-config, and started the
JSON-RPC HTTP transport.
That made sense while JSON-RPC was the only long-lived server path. It is now
the wrong long-term ownership. Server composition belongs in wf_server; HTTP
JSON-RPC should stay a transport adapter around an already-built
WorkflowServer.
Ownership Rule
wf_server
owns process startup policy
owns WorkflowServer composition from wf_config / legacy inputs
decides which transports to host
wf_transport_rpc_http
owns JSON-RPC HTTP app/client/envelope code
owns create_rpc_app(server)
may provide a small serve helper for an already-built WorkflowServer
The script name can remain wf-rpc-server for compatibility, but its entrypoint
should eventually point at wf_server.cli:main.
Previous Shape
Previous script registration:
wf-rpc-server = "wf_transport_rpc_http.cli:main"
Previous responsibilities inside wf_transport_rpc_http.cli:
- parse
--config - parse
--store-root - parse legacy
--mcp-config - load neutral
wf_config - detect MCP sources
- select local/static or MCP-backed
WorkflowServer - select RPC bind host/port/path
- call
create_rpc_app(server) - call
uvicorn.run(...)
Only the last two bullets are transport-specific.
Desired Shape
Recommended first refactor:
src/wf_server/cli.py
Typer app for durable server startup
parses config and startup overrides
builds WorkflowServer through wf_server.config
starts configured transports
src/wf_transport_rpc_http/cli.py
compatibility shim:
from wf_server.cli import app, main
src/wf_transport_rpc_http/app.py
unchanged create_rpc_app(server, rpc_path="/rpc")
Updated script registration:
wf-rpc-server = "wf_server.cli:main"
Keep wf_transport_rpc_http.cli temporarily so tests and imports do not break
immediately.
Implementation Status
First move slice complete:
wf-rpc-serverscript entrypoint points atwf_server.cli:main.wf_server.cliowns startup config parsing and server composition.wf_transport_rpc_http.cliremains as a compatibility shim.wf_transport_rpc_http.create_rpc_app(server)remains the JSON-RPC HTTP transport adapter.
Why Not Move create_rpc_app
create_rpc_app(server) is transport code:
- JSON-RPC route and method registration
- JSON-RPC error mapping
- HTTP health endpoint
- FastAPI/fastapi-jsonrpc object construction
It should stay in wf_transport_rpc_http. Future transports should have their
own equivalent adapter over WorkflowServer.
Why Move The Typer Entrypoint
The Typer entrypoint answers process-level questions:
- Which config file is used?
- Is this local/static or MCP-backed?
- Are source providers loaded from neutral config?
- Is legacy config accepted?
- Which transports are hosted?
- Which store roles are used?
Those questions are server composition policy. They should not live in an HTTP transport package because the same process may later host JSON-RPC HTTP, MCP HTTP, WebSocket, or other transports together.
Compatibility Policy
- Keep the command name
wf-rpc-serverduring the move. - Keep
wf_transport_rpc_http.cli.appand.mainas re-export shims for one compatibility window. - Update tests to target
wf_server.clifor behavior. - Keep one compatibility test proving the old import path is identity-equal.
- Do not change runtime behavior in the move slice.
First Implementation Slice
The first slice should be a pure move/refactor:
-
Create
src/wf_server/cli.pyby moving the current implementation fromsrc/wf_transport_rpc_http/cli.py. -
Replace
src/wf_transport_rpc_http/cli.pywith:from wf_server.cli import app, main __all__ = ["app", "main"] -
Update
pyproject.toml:wf-rpc-server = "wf_server.cli:main" -
Move CLI behavior tests from
tests/wf_transport_rpc_http/test_cli.pyto a server-focused test module, for exampletests/wf_server/test_cli.py. -
Update monkeypatch targets from
wf_transport_rpc_http.cli...towf_server.cli.... -
Add a compatibility import test for
wf_transport_rpc_http.cli. -
Update docs and project map.
Non-Goals
- Do not add WebSocket, MCP HTTP, or multi-transport hosting in the move slice.
- Do not change
create_rpc_app. - Do not remove the
wf_transport_rpc_http.clishim immediately. - Do not redesign
wf_config. - Do not change
wfclient targeting behavior.
Future Follow-Up
After the move, wf_server.cli can grow toward multi-transport hosting:
wf-server --config wf.config.json
hosts server.transports[] from config
wf-rpc-server can remain as an alias or convenience command for the RPC-only
case. The important boundary is that server startup composes transports; a
transport package does not compose the server.