goodbye modes 1

This commit is contained in:
lda
2026-05-16 18:30:22 +07:00 Verified
parent 8987aceb9d
commit 5369fa1bae
11 changed files with 47 additions and 124 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
# MCP Protocol Proxy Inventory
This document records observed behavior of `wf-mcp` unified mode against real
This document records observed behavior of the `wf-mcp` server against real
upstream MCP servers. It is not a design spec. It is a fact log for deciding
which proxy features need explicit implementation.
@@ -23,7 +23,7 @@ everything.default
Proxy mode:
```text
wf-mcp serve --mode unified
wf-mcp serve
```
### Working
@@ -49,7 +49,7 @@ Remove the public `serve --mode broker` and `serve --mode proxy` choices.
After this pass:
- `wf-mcp serve` runs the unified surface
- `wf-mcp serve` runs the server surface
- users no longer choose among three product modes
- docs should describe one server behavior, not a mode matrix
@@ -76,7 +76,7 @@ These packages still represent useful implementation boundaries:
- `wf_mcp.server`
`transparent_proxy` is already partly a legacy package name, but the code inside
it still owns real proxy-mounting mechanics used by unified mode. Rename or
it still owns real proxy-mounting mechanics used by the server. Rename or
re-home that code only as a later cleanup if the package name becomes a real
source of confusion.
+5 -4
View File
@@ -101,11 +101,12 @@ The current practical proxy roadmap, including which FastMCP gaps are worth
working around locally and which should stay upstream-dependent for now, lives
in [`wf_mcp_proxy_reality_and_roadmap.md`](wf_mcp_proxy_reality_and_roadmap.md).
The public MCP mode split is now being retired. The current execution plan is
The public MCP mode split has been retired. The execution plan is
[`superpowers/plans/2026-05-16-retire-legacy-mcp-modes.md`](superpowers/plans/2026-05-16-retire-legacy-mcp-modes.md):
`broker` and `proxy` are legacy public launch surfaces, while unified behavior
is the intended product surface. Internal concern packages remain useful even
after the public mode choices disappear.
`broker` and `proxy` were legacy public launch surfaces, while the ordinary
server now exposes both local capabilities and proxied upstream capabilities.
Internal concern packages remain useful even though the public mode choices are
gone.
## Future Extraction
+6 -6
View File
@@ -2,8 +2,8 @@
`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. Broker mode, transparent proxy mode, workflow planning, and future UI
surfaces are projections of those sources.
a source. The MCP server, workflow planning, and future UI surfaces are
projections of those sources.
This avoids the current trap where broker admin tools, transparent proxy admin
tools, workflow node specs, and upstream MCP tools all look like unrelated
@@ -237,15 +237,15 @@ names.
## Migration Path
1. Add explicit admin MCP exposure controls for broker mode.
2. Project broker admin tools from `wf.admin` only when admin MCP exposure is
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 broker mode and transparent proxy mode
define separate copies of the same admin/control capabilities.
The implementation should avoid having separate backend layers define copies of
the same admin/control capabilities.
## Current Inventory Surfaces
+6 -7
View File
@@ -51,16 +51,15 @@ new workflow artifacts are saved. A stable `run_deployment` tool lets an LLM
test saved workflows immediately without requiring dynamic tool registration or
tool-list notifications to work perfectly.
This control surface should not fork between broker mode and transparent proxy
mode. The project currently has two MCP exposure styles:
This control surface should not fork between backend service layers. The public
server now has one exposure style, but internally it still combines:
- compatibility broker tools such as list/call wrappers
- transparent proxy projection through MCP `tools/list` and `tools/call`
- service-backed local workflow/admin tools
- upstream proxy projection through MCP `tools/list` and `tools/call`
Workflow artifact operations should be defined once and projected through the
chosen MCP server surface. If broker and transparent modes remain as launch
options, they should share the same platform service instead of owning separate
workflow registries or separate run semantics.
server surface instead of owning separate workflow registries or separate run
semantics.
Dynamic projection of saved workflows as individual MCP tools can exist later,
but it should be optional. The stable run tool is the reliable base layer.
-4
View File
@@ -1,7 +1,5 @@
from .broker import (
load_broker_config,
run_broker_server,
run_transparent_proxy_server,
WfMcpService,
)
from .capabilities import (
@@ -39,7 +37,5 @@ __all__ = [
"create_transparent_proxy_client",
"create_transparent_proxy_server",
"load_broker_config",
"run_broker_server",
"run_transparent_proxy_server",
"validate_transparent_proxy_config",
]
+1 -7
View File
@@ -5,11 +5,7 @@ from .discovery import (
specs_from_discovered_tools,
)
from .events import McpEvent, make_event
from .server import (
create_broker_server,
run_broker_server,
run_transparent_proxy_server,
)
from .server import create_broker_server
from .config import build_service_from_config, load_broker_config
from .transport import normalize_transport
from .service import WfMcpService
@@ -24,8 +20,6 @@ __all__ = [
"discover_connection_capabilities",
"load_broker_config",
"make_event",
"run_broker_server",
"run_transparent_proxy_server",
"snapshot_from_specs",
"specs_from_discovered_tools",
"normalize_transport",
-41
View File
@@ -1,18 +1,12 @@
from __future__ import annotations
import os
from pathlib import Path
from mcp.server.fastmcp import FastMCP
from ..transparent_proxy import create_transparent_proxy_server
from .artifact_tools import register_artifact_tools
from .config import build_service_from_config, load_broker_config
from .prompts import register_broker_prompts
from .resources import register_broker_resources
from .service import WfMcpService
from .tools import register_broker_tools
from .transport import normalize_transport
def create_broker_server(service: WfMcpService) -> FastMCP:
@@ -31,38 +25,3 @@ def create_broker_server(service: WfMcpService) -> FastMCP:
register_broker_prompts(server, service)
return server
def main() -> None:
config_path = os.environ.get("WF_MCP_CONFIG", "wf_mcp.config.json")
transport_env = os.environ.get("WF_MCP_TRANSPORT", "stdio")
run_broker_server(config_path, transport_env)
def run_broker_server(config_path: str | Path, transport: str = "stdio") -> None:
config = load_broker_config(config_path)
service = build_service_from_config(config)
server = create_broker_server(service)
server.run(transport=normalize_transport(transport))
def run_transparent_proxy_server(
config_path: str | Path,
transport: str = "stdio",
*,
resources_as_tools: bool = False,
prompts_as_tools: bool = False,
search_tools: bool = False,
) -> None:
config = load_broker_config(config_path)
server = create_transparent_proxy_server(
config,
config_path=config_path,
resources_as_tools=resources_as_tools,
prompts_as_tools=prompts_as_tools,
search_tools=search_tools,
)
server.run(transport=normalize_transport(transport), show_banner=False)
if __name__ == "__main__":
main()
+13 -32
View File
@@ -9,8 +9,6 @@ from typing import Any
from .broker import (
build_service_from_config,
load_broker_config,
run_broker_server,
run_transparent_proxy_server,
)
from .server import run_unified_proxy_server
@@ -25,18 +23,12 @@ def build_parser() -> argparse.ArgumentParser:
subparsers = parser.add_subparsers(dest="command", required=True)
serve = subparsers.add_parser("serve", help="Run the broker MCP server.")
serve = subparsers.add_parser("serve", help="Run the MCP server.")
serve.add_argument(
"--transport",
default="stdio",
choices=["stdio", "sse", "streamable-http", "streamable_http"],
help="Transport to run the broker server with.",
)
serve.add_argument(
"--mode",
default="proxy",
choices=["broker", "proxy", "unified"],
help="Run broker mode, transparent proxy mode, or unified mode.",
help="Transport to run the MCP server with.",
)
serve.add_argument(
"--resources-as-tools",
@@ -57,7 +49,7 @@ def build_parser() -> argparse.ArgumentParser:
"--no-admin-tools",
dest="admin_tools",
action="store_false",
help="Hide wf.admin.* tools in unified mode.",
help="Hide wf.admin.* tools.",
)
serve.set_defaults(admin_tools=True)
@@ -122,27 +114,16 @@ def main(argv: list[str] | None = None) -> int:
args = parser.parse_args(argv)
if args.command == "serve":
if args.mode == "proxy":
run_transparent_proxy_server(
args.config,
args.transport,
resources_as_tools=args.resources_as_tools,
prompts_as_tools=args.prompts_as_tools,
search_tools=args.search_tools,
)
elif args.mode == "broker":
run_broker_server(args.config, args.transport)
else:
config = load_broker_config(args.config)
run_unified_proxy_server(
config,
args.transport,
config_path=args.config,
resources_as_tools=args.resources_as_tools,
prompts_as_tools=args.prompts_as_tools,
search_tools=args.search_tools,
admin_tools=args.admin_tools,
)
config = load_broker_config(args.config)
run_unified_proxy_server(
config,
args.transport,
config_path=args.config,
resources_as_tools=args.resources_as_tools,
prompts_as_tools=args.prompts_as_tools,
search_tools=args.search_tools,
admin_tools=args.admin_tools,
)
return 0
service = _service_from_config(args.config)
+1 -1
View File
@@ -43,7 +43,7 @@ class ProxyRuntime:
"""Mount configured upstream MCP connections into one FastMCP server.
The `transparent_proxy` package name is compatibility history. This runtime
is now the shared proxy mounting engine used by unified mode too.
is now the shared proxy mounting engine used by the public server surface.
"""
def __init__(
+11 -18
View File
@@ -38,7 +38,6 @@ def test_build_parser_accepts_serve_transport() -> None:
assert args.command == "serve"
assert args.transport == "streamable_http"
assert args.mode == "proxy"
assert args.resources_as_tools is False
assert args.prompts_as_tools is False
assert args.search_tools is False
@@ -58,27 +57,24 @@ def test_build_parser_accepts_proxy_compatibility_flags() -> None:
)
assert args.command == "serve"
assert args.mode == "proxy"
assert args.resources_as_tools is True
assert args.prompts_as_tools is True
assert args.search_tools is True
def test_build_parser_accepts_unified_mode() -> None:
def test_build_parser_rejects_legacy_mode_flag() -> None:
parser = build_parser()
args = parser.parse_args(
[
"--config",
"wf_mcp.config.json",
"serve",
"--mode",
"unified",
]
)
assert args.command == "serve"
assert args.mode == "unified"
assert args.admin_tools is True
with pytest.raises(SystemExit):
parser.parse_args(
[
"--config",
"wf_mcp.config.json",
"serve",
"--mode",
"unified",
]
)
def test_build_parser_accepts_no_admin_tools_flag() -> None:
@@ -88,14 +84,11 @@ def test_build_parser_accepts_no_admin_tools_flag() -> None:
"--config",
"wf_mcp.config.json",
"serve",
"--mode",
"unified",
"--no-admin-tools",
]
)
assert args.command == "serve"
assert args.mode == "unified"
assert args.admin_tools is False