From c9d9b92eee4111666463aa1c24d049897c9c7cfb Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:25:31 +0300 Subject: [PATCH 1/8] Branch for P2-T6: remove legacy broker flags From 99714a198cbdafcdfc4d7daadeb5b18a86edc8d3 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:26:16 +0300 Subject: [PATCH 2/8] Select task P2-T6: Remove legacy --broker-connect and --broker-spawn flags --- SPECS/INPROGRESS/next.md | 22 +++++++++++++--------- SPECS/Workplan.md | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index 9647f152..7b362b68 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,12 +1,16 @@ -# No Active Task +# Active Task -**Status:** Idle — P1-T7 archived. Select the next task from `SPECS/Workplan.md`. +**Status:** Selected — ready for planning/execution. -## Recently Archived +## Task Metadata -- **P1-T7** — Hide README version badge maintenance note (2026-03-01, PASS) -- **P1-T4** — Update docs to reflect broker robustness improvements (2026-03-01, PASS) -- **P2-T5** — Warn or restart daemon when --web-ui requested but running broker lacks it (2026-03-01, PASS) -- **P2-T4** — Surface broker unavailability as JSON-RPC error instead of silent timeout (2026-03-01, PASS) -- **P2-T3** — Fix double-spawn race condition when MCP client toggles rapidly (2026-03-01, PASS) -- **P2-T1** — Replace --broker-spawn/--broker-connect with single --broker flag (2026-03-01, PASS) +- **Task ID:** P2-T6 +- **Task Name:** Remove legacy --broker-connect and --broker-spawn flags +- **Priority:** P1 +- **Dependencies:** P2-T1 +- **Parallelizable:** yes +- **Source:** `SPECS/Workplan.md` + +## Summary + +Remove obsolete broker CLI aliases (`--broker-connect`, `--broker-spawn`) from parser/tests/docs and keep `--broker` as the single proxy mode entrypoint. diff --git a/SPECS/Workplan.md b/SPECS/Workplan.md index fa8b8629..4582f03d 100644 --- a/SPECS/Workplan.md +++ b/SPECS/Workplan.md @@ -184,6 +184,22 @@ Add new tasks using the canonical template in [TASK_TEMPLATE.md](TASK_TEMPLATE.m - [x] Warning text is actionable (tells user how to fix it) - [x] MCP session continues normally despite the warning +#### ⬜ P2-T6: Remove legacy --broker-connect and --broker-spawn flags +- **Status:** ⬜ Pending +- **Description:** Broker mode aliases `--broker-connect` and `--broker-spawn` were kept only for backwards compatibility. Broker mode has not shipped yet, so compatibility is unnecessary and the aliases now add confusion to docs and tests. Remove both legacy flags from wrapper CLI parsing and documentation, and keep `--broker` as the single proxy-mode entrypoint (plus `--broker-daemon` for host mode). +- **Priority:** P1 +- **Dependencies:** P2-T1 +- **Parallelizable:** yes +- **Outputs/Artifacts:** + - `src/mcpbridge_wrapper/__main__.py` — remove legacy broker alias parsing/comments + - `tests/unit/test_main.py`, `tests/unit/test_broker_proxy.py` — remove/update alias-specific tests + - `README.md` and `docs/*.md` — remove alias guidance/examples and align to `--broker` +- **Acceptance Criteria:** + - [ ] Wrapper no longer accepts `--broker-connect` and `--broker-spawn` as broker control flags + - [ ] Documentation no longer presents legacy alias usage or compatibility notes + - [ ] Broker mode guidance remains clear with `--broker` (proxy) and `--broker-daemon` (host) + - [ ] Required quality gates pass (`pytest`, `ruff check src/`, `mypy src/`, `pytest --cov` with coverage >=90%) + ### Bug Fixes #### ✅ BUG-T8: Fix broker proxy bridge exits after first write due to BaseProtocol missing _drain_helper From 9156d65988f82d296e8a651a9077aa307b3b4070 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:26:44 +0300 Subject: [PATCH 3/8] Plan task P2-T6: Remove legacy --broker-connect and --broker-spawn flags --- ...y_broker_connect_and_broker_spawn_flags.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md diff --git a/SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md b/SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md new file mode 100644 index 00000000..d67d98a1 --- /dev/null +++ b/SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md @@ -0,0 +1,60 @@ +# PRD: P2-T6 — Remove legacy --broker-connect and --broker-spawn flags + +## Overview + +`--broker` is already the single recommended proxy-mode flag. The legacy aliases +`--broker-connect` and `--broker-spawn` were retained only for backwards +compatibility, but broker mode has not been released. This task removes the +legacy aliases from CLI behavior, tests, and documentation to reduce user-facing +complexity. + +## Problem Statement + +Current state keeps three proxy entry flags (`--broker`, `--broker-connect`, +`--broker-spawn`) and carries alias-specific docs/tests. This increases support +surface and can confuse users about which mode to configure. + +## Scope + +In scope: +- Remove legacy alias parsing in CLI broker argument handling. +- Keep `--broker` (proxy auto-detect/spawn) and `--broker-daemon` (host mode). +- Remove alias-focused tests and update expectations to the two-flag model. +- Remove legacy alias guidance/examples from user docs. + +Out of scope: +- Behavioral changes to broker daemon/proxy internals unrelated to flag parsing. +- New broker features. + +## Deliverables + +| File(s) | Change | +|---|---| +| `src/mcpbridge_wrapper/__main__.py` | Remove `--broker-connect` / `--broker-spawn` broker-control parsing and related wording | +| `tests/unit/test_main.py` | Remove/update alias tests and comments for parser/main flows | +| `tests/unit/test_broker_proxy.py` | Update legacy-flag references in test descriptions to current flags | +| `README.md`, `docs/*.md` | Remove alias guidance/examples; keep `--broker` + `--broker-daemon` guidance only | + +## Acceptance Criteria + +- [ ] Wrapper no longer accepts `--broker-connect` and `--broker-spawn` as broker control flags. +- [ ] Broker-mode docs no longer present aliases as usable/recommended options. +- [ ] Broker guidance remains clear for `--broker` (proxy) and `--broker-daemon` (host). +- [ ] Quality gates pass: `pytest`, `ruff check src/`, `mypy src/`, `pytest --cov` (coverage >= 90%). + +## Validation Plan + +1. Run parser/unit tests and full test suite. +2. Run lint and type checks. +3. Run coverage and confirm >= 90%. +4. Verify no remaining legacy-flag references in active docs/code paths. + +## Dependencies + +- P2-T1 + +## Risks + +Low-medium: removing aliases is a CLI behavior change. Mitigate by fully +aligning docs/tests and preserving clear `--broker`/`--broker-daemon` +instructions. From b9b27cfd2972bc05e0c3f2bb1586b3fabdd2cc6f Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:33:47 +0300 Subject: [PATCH 4/8] Implement P2-T6: remove legacy broker alias flags from parser, docs, and templates --- README.md | 4 +- SPECS/INPROGRESS/P2-T6_Validation_Report.md | 77 +++++++++++++++++++ .../Documentation.docc/ClaudeCodeSetup.md | 7 +- .../Documentation.docc/CodexCLISetup.md | 7 +- .../Documentation.docc/CursorSetup.md | 20 +---- .../Documentation.docc/Troubleshooting.md | 16 ++-- .../Documentation.docc/WebUIDashboard.md | 6 +- .../Documentation.docc/XcodeMCPWrapper.md | 4 +- config/claude-code-broker.txt | 26 ++----- config/codex-cli-broker.txt | 26 ++----- config/cursor-mcp-broker.json | 42 +++------- docs/broker-mode.md | 18 ++--- docs/claude-setup.md | 7 +- docs/codex-setup.md | 7 +- docs/cursor-setup.md | 22 +----- docs/troubleshooting.md | 18 ++--- docs/webui-setup.md | 6 +- src/mcpbridge_wrapper/__main__.py | 19 ++--- src/mcpbridge_wrapper/broker/proxy.py | 5 +- tests/unit/test_broker_proxy.py | 39 +++++----- tests/unit/test_main.py | 71 +++++------------ 21 files changed, 193 insertions(+), 254 deletions(-) create mode 100644 SPECS/INPROGRESS/P2-T6_Validation_Report.md diff --git a/README.md b/README.md index c764b338..f6f0b0b8 100644 --- a/README.md +++ b/README.md @@ -121,8 +121,6 @@ upstream bridge session. - **Why this mode exists:** Apple documents a Coding Intelligence known issue in Xcode 26.4 where external development tools may trigger repeated "Allow Connection?" dialogs during normal usage (`170721057`). Reusing one long-lived upstream session via broker mode can reduce reconnect churn that surfaces this prompt pattern. See Apple's official [Xcode 26.4 release notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_4-release-notes). - Use `--broker` to auto-detect — connect if daemon is alive, spawn otherwise (recommended). -- Use `--broker-connect` to attach to an already-running broker (legacy alias). -- Use `--broker-spawn` to auto-start the broker if needed (legacy alias for `--broker`). - Add `--web-ui` (plus optional `--web-ui-config`) when you want the spawned or daemon host to own one shared dashboard endpoint. Quick migration examples: @@ -145,7 +143,7 @@ When you run multiple MCP client processes at the same time: - **Unified single-config pattern:** configure each client with `--broker --web-ui --web-ui-config `. - **Runtime expectation:** the first client that must spawn the broker starts the broker host and dashboard; later clients reuse the same broker and dashboard endpoint. - **Ownership rule:** only one process can bind a given Web UI `host:port` (for example `127.0.0.1:8080`). -- **Connect-only behavior:** `--broker-connect` clients never start the dashboard by themselves. +- **Connection behavior:** when a broker is already running, `--broker` reuses it and does not retrofit dashboard settings onto that existing host. - **Fallback behavior:** if dashboard bind fails (port already in use), broker MCP transport continues and only dashboard startup is skipped. See [Web UI Setup Guide](docs/webui-setup.md#multi-agent-web-ui-ownership-model) and [Troubleshooting](docs/troubleshooting.md#mcp-tools-are-green-but-dashboard-is-unreachable). diff --git a/SPECS/INPROGRESS/P2-T6_Validation_Report.md b/SPECS/INPROGRESS/P2-T6_Validation_Report.md new file mode 100644 index 00000000..47a0a068 --- /dev/null +++ b/SPECS/INPROGRESS/P2-T6_Validation_Report.md @@ -0,0 +1,77 @@ +# Validation Report: P2-T6 — Remove legacy --broker-connect and --broker-spawn flags + +**Date:** 2026-03-01 +**Verdict:** PASS + +## Summary + +Removed legacy broker aliases from runtime broker-flag parsing and aligned docs/templates to a two-flag model: +- `--broker` for proxy mode +- `--broker-daemon` for explicit host mode + +Legacy flags are no longer consumed as broker control flags; they are forwarded as ordinary passthrough args. + +## Delivered Changes + +- Updated broker argument parsing and broker-related docstrings in: + - `src/mcpbridge_wrapper/__main__.py` + - `src/mcpbridge_wrapper/broker/proxy.py` +- Updated parser/main unit tests to reflect removed alias behavior: + - `tests/unit/test_main.py` + - `tests/unit/test_broker_proxy.py` +- Removed legacy alias guidance/examples from user docs + DocC mirrors: + - `README.md` + - `docs/broker-mode.md` + - `docs/cursor-setup.md` + - `docs/claude-setup.md` + - `docs/codex-setup.md` + - `docs/webui-setup.md` + - `docs/troubleshooting.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/XcodeMCPWrapper.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/CursorSetup.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/ClaudeCodeSetup.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/CodexCLISetup.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/WebUIDashboard.md` + - `Sources/XcodeMCPWrapper/Documentation.docc/Troubleshooting.md` +- Updated broker config templates to `--broker`-only examples: + - `config/cursor-mcp-broker.json` + - `config/claude-code-broker.txt` + - `config/codex-cli-broker.txt` + +## Acceptance Criteria Check + +- [x] Wrapper no longer accepts `--broker-connect` and `--broker-spawn` as broker control flags. +- [x] Broker-mode docs no longer present aliases as usable/recommended options. +- [x] Broker guidance remains clear for `--broker` (proxy) and `--broker-daemon` (host). +- [x] Quality gates pass: `pytest`, `ruff check src/`, `mypy src/`, `pytest --cov` (coverage >= 90%). + +## Quality Gates + +1. `pytest` +- Result: PASS +- Evidence: `735 passed, 5 skipped` + +2. `ruff check src/` +- Result: PASS +- Evidence: `All checks passed!` + +3. `mypy src/` +- Result: PASS +- Evidence: `Success: no issues found in 18 source files` + +4. `pytest --cov` +- Result: PASS +- Evidence: `Required test coverage of 90.0% reached. Total coverage: 91.26%` + +## Additional Verification + +- Legacy flag reference sweep outside archival/spec artifacts reduced to intentional parser-forwarding tests only. +- Targeted parser/broker tests passed: + - `tests/unit/test_main.py::TestParseBrokerArgs` + - `tests/unit/test_main.py::TestMainBrokerMode` + - `tests/unit/test_main.py::TestMainWebUIBrokerFlagCompatibility` + - `tests/unit/test_broker_proxy.py::TestParseBrokerArgs` + +## Notes + +Given this is a pre-release compatibility cleanup, external users should configure broker mode with `--broker` only. diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/ClaudeCodeSetup.md b/Sources/XcodeMCPWrapper/Documentation.docc/ClaudeCodeSetup.md index 87565cb9..3181ebed 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/ClaudeCodeSetup.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/ClaudeCodeSetup.md @@ -30,11 +30,8 @@ claude mcp add --transport stdio xcode -- uvx --from 'mcpbridge-wrapper[webui]' claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker ``` -Advanced — connect-only (no auto-spawn): - -```bash -claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect -``` +If you run a dedicated host with `--broker-daemon`, keep clients on `--broker` +so they attach when available and auto-recover when the host is absent. ### Option 2: Using Manual Installation diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/CodexCLISetup.md b/Sources/XcodeMCPWrapper/Documentation.docc/CodexCLISetup.md index de185495..966914dc 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/CodexCLISetup.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/CodexCLISetup.md @@ -30,11 +30,8 @@ codex mcp add xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper - codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker ``` -Advanced — connect-only (no auto-spawn): - -```bash -codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect -``` +If you run a dedicated host with `--broker-daemon`, keep clients on `--broker` +so they attach when available and auto-recover when the host is absent. ### Option 2: Using Manual Installation diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/CursorSetup.md b/Sources/XcodeMCPWrapper/Documentation.docc/CursorSetup.md index a899bb7f..31a35733 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/CursorSetup.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/CursorSetup.md @@ -127,23 +127,9 @@ Replace `/path/to/XcodeMCPWrapper` with the actual path to your cloned repositor } ``` -Advanced — connect-only (no auto-spawn, manage daemon lifecycle yourself): - -```json -{ - "mcpServers": { - "xcode-tools": { - "command": "uvx", - "args": [ - "--from", - "mcpbridge-wrapper", - "mcpbridge-wrapper", - "--broker-connect" - ] - } - } -} -``` +If you manage a dedicated host with `--broker-daemon`, keep client args on +`--broker`: clients will attach when the host is alive and auto-recover by +spawning when it is not. Migration: add `--broker` to existing args. Rollback: remove broker flags and restart Cursor. diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/Troubleshooting.md b/Sources/XcodeMCPWrapper/Documentation.docc/Troubleshooting.md index a055277d..ed94b1d0 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/Troubleshooting.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/Troubleshooting.md @@ -272,7 +272,7 @@ Prefer `kill` (`SIGTERM`) first; use `kill -9` only when the process does not ex - MCP can stay healthy even if Web UI startup is skipped. - Only one process can own a given Web UI `host:port`. - Dashboard starts in a direct-mode owner (`--web-ui`) or a broker host (`--broker-daemon --web-ui`). -- `--broker-connect` never starts a dashboard by itself; `--broker --web-ui` only starts one when it must spawn a host. +- `--broker --web-ui` only starts a dashboard when it must spawn a host; when attaching to an existing host it does not retrofit dashboard settings. - If dashboard bind fails (port already in use), wrapper logs a warning and continues MCP without dashboard hosting. - A healthy MCP status does not guarantee an active dashboard listener on the expected port. @@ -298,7 +298,7 @@ If step 1 returns no listener, no process currently owns the dashboard port. 1. **Single dashboard owner (direct mode):** keep `--web-ui` on one client config only. 2. **Use separate dashboard ports:** assign unique `--web-ui-port` values per process. 3. **Unified broker single-config:** use `--broker --web-ui --web-ui-config ` in all clients so one spawned host owns the dashboard. -4. **Dedicated host pattern:** run one `--broker-daemon --web-ui` process, keep clients on `--broker-connect`, and monitor `~/.mcpbridge_wrapper/broker.log`. +4. **Dedicated host pattern:** run one `--broker-daemon --web-ui` process, keep clients on `--broker`, and monitor `~/.mcpbridge_wrapper/broker.log`. 5. **Standalone diagnostics:** run `--web-ui-only` when you need dashboard-only debugging independent from MCP startup. ## Error: "Tool charts are fresh, but Audit Log / Session Timeline look stale" @@ -386,7 +386,7 @@ The second value should be larger. **Cause:** Broker process is not running, or socket state is stale. -**Note:** When using `--broker` or `--broker-spawn`, stale socket/PID files are detected and removed automatically. Manual cleanup is only needed with `--broker-connect`. +**Note:** When using `--broker`, stale socket/PID files are detected and removed automatically. **Solution:** @@ -394,7 +394,7 @@ The second value should be larger. PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; SOCK="$HOME/.mcpbridge_wrapper/broker.sock"; if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then echo "broker running"; else echo "broker not running"; fi; ls -l "$SOCK" 2>/dev/null || echo "socket missing" ``` -If broker is not running, switch to `--broker` (auto-detects and spawns) or start it manually and use `--broker-connect`. +If broker is not running, use `--broker` (auto-detects and spawns) or start it manually, then reconnect with `--broker`. ## Warning: "broker is running without --web-ui on port N" @@ -422,7 +422,7 @@ Then restart your MCP client. The next connection will spawn a fresh daemon that **Symptom:** Explicit broker startup fails because an existing broker lock is active. -**Solution:** Reuse the running broker with `--broker-connect`, or stop the PID first: +**Solution:** Reuse the running broker with `--broker`, or stop the PID first: ```bash PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; if [ -f "$PID_FILE" ]; then kill "$(cat "$PID_FILE")"; fi @@ -430,9 +430,9 @@ PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; if [ -f "$PID_FILE" ]; then kill ## Stale broker lock/socket recovery -When using `--broker` or `--broker-spawn`, stale socket/PID files are detected automatically and removed before spawning a fresh daemon. No manual cleanup is required in normal use. +When using `--broker`, stale socket/PID files are detected automatically and removed before spawning a fresh daemon. No manual cleanup is required in normal use. -If you are using `--broker-connect` (connect-only, no auto-spawn) and a crash has left orphaned files, clean them explicitly: +If startup is repeatedly blocked by orphaned files in your environment, clean them explicitly: ```bash PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; SOCK="$HOME/.mcpbridge_wrapper/broker.sock"; if [ -f "$PID_FILE" ] && ! kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then rm -f "$PID_FILE"; fi; if [ -S "$SOCK" ]; then rm -f "$SOCK"; fi @@ -469,7 +469,7 @@ rm -f ~/.mcpbridge_wrapper/broker.pid ~/.mcpbridge_wrapper/broker.sock ## Rollback to direct mode -1. Remove `--broker`, `--broker-connect`, or `--broker-spawn` from MCP config args. +1. Remove `--broker` from MCP config args. 2. Restart the MCP client. 3. Stop and clean broker state: diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/WebUIDashboard.md b/Sources/XcodeMCPWrapper/Documentation.docc/WebUIDashboard.md index 36784738..5936e1ff 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/WebUIDashboard.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/WebUIDashboard.md @@ -49,14 +49,14 @@ The Web UI dashboard is hosted by the wrapper process that successfully binds th Recommended patterns: 1. **Single owner (recommended):** enable `--web-ui` for one designated client process only. -2. **Unified broker config (multi-agent):** use `--broker-spawn --web-ui --web-ui-config ` across Cursor/Zed/Claude/Codex so the first auto-spawn host owns one shared dashboard endpoint. +2. **Unified broker config (multi-agent):** use `--broker --web-ui --web-ui-config ` across Cursor/Zed/Claude/Codex so the first auto-spawn host owns one shared dashboard endpoint. 3. **Separate ports per process:** if you truly need multiple dashboards, give each process its own port. Broker-mode note: - `--broker-daemon --web-ui` starts the dashboard in the broker host process. -- `--broker-spawn --web-ui` can start the dashboard when it has to spawn the broker host. -- `--broker-connect` never starts the dashboard by itself. +- `--broker --web-ui` can start the dashboard when it has to spawn the broker host. +- When `--broker` attaches to an already-running host, it does not change that host's dashboard state. - If dashboard bind fails, broker MCP transport still runs and dashboard startup is skipped. ### Using Make Commands diff --git a/Sources/XcodeMCPWrapper/Documentation.docc/XcodeMCPWrapper.md b/Sources/XcodeMCPWrapper/Documentation.docc/XcodeMCPWrapper.md index 12f53a30..fda6b549 100644 --- a/Sources/XcodeMCPWrapper/Documentation.docc/XcodeMCPWrapper.md +++ b/Sources/XcodeMCPWrapper/Documentation.docc/XcodeMCPWrapper.md @@ -115,8 +115,6 @@ Broker mode lets short-lived MCP sessions share one persistent upstream bridge. - **Why this mode exists:** Apple documents a Coding Intelligence known issue in Xcode 26.4 where external development tools may trigger repeated "Allow Connection?" dialogs during normal usage (`170721057`). Reusing one long-lived upstream session via broker mode can reduce reconnect churn that surfaces this prompt pattern. See Apple's official [Xcode 26.4 release notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-26_4-release-notes). - `--broker`: auto-detect — connect if daemon is alive, spawn otherwise (recommended). -- `--broker-connect`: attach to an already-running broker (legacy alias). -- `--broker-spawn`: auto-start the broker if needed (legacy alias for `--broker`). - Add `--web-ui` (plus optional `--web-ui-config`) when you want the spawned or daemon host to own one shared dashboard endpoint. Quick migration examples: @@ -139,7 +137,7 @@ When you run multiple MCP client processes at the same time: - **Unified single-config pattern:** configure each client with `--broker --web-ui --web-ui-config `. - **Runtime expectation:** the first client that must spawn the broker starts the broker host and dashboard; later clients reuse the same broker and dashboard endpoint. - **Ownership rule:** only one process can bind a given Web UI `host:port` (for example `127.0.0.1:8080`). -- **Connect-only behavior:** `--broker-connect` clients never start the dashboard by themselves. +- **Connection behavior:** when a broker is already running, `--broker` reuses it and does not retrofit dashboard settings onto that existing host. - **Fallback behavior:** if dashboard bind fails (port already in use), broker MCP transport continues and only dashboard startup is skipped. See and . diff --git a/config/claude-code-broker.txt b/config/claude-code-broker.txt index c5fa8b4d..9798cd2b 100644 --- a/config/claude-code-broker.txt +++ b/config/claude-code-broker.txt @@ -1,26 +1,16 @@ # Claude Code broker-mode MCP setup for mcpbridge-wrapper # -# Use ONE command. Connect mode is the stable baseline. +# Use ONE command. # -# OPTION 1: uvx connect-only -# Connect to an already-running broker daemon. -claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect +# OPTION 1: uvx (recommended) +# Auto-detect running broker, spawn if missing. +claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker # -# OPTION 1B: uvx spawn (best-effort) -# Auto-spawn broker if missing, then connect. -claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-spawn +# OPTION 2: manual install +claude mcp add --transport stdio xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker # -# OPTION 2: manual install connect-only -claude mcp add --transport stdio xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker-connect -# -# OPTION 2B: manual install spawn -claude mcp add --transport stdio xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker-spawn -# -# OPTION 3: local dev (venv) connect-only -claude mcp add --transport stdio xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker-connect -# -# OPTION 3B: local dev (venv) spawn -claude mcp add --transport stdio xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker-spawn +# OPTION 3: local dev (venv) +claude mcp add --transport stdio xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker # # Verify: # claude mcp list diff --git a/config/codex-cli-broker.txt b/config/codex-cli-broker.txt index 6b4500bd..07fe80c3 100644 --- a/config/codex-cli-broker.txt +++ b/config/codex-cli-broker.txt @@ -1,26 +1,16 @@ # Codex CLI broker-mode MCP setup for mcpbridge-wrapper # -# Use ONE command. Connect mode is the stable baseline. +# Use ONE command. # -# OPTION 1: uvx connect-only -# Connect to an already-running broker daemon. -codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect +# OPTION 1: uvx (recommended) +# Auto-detect running broker, spawn if missing. +codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker # -# OPTION 1B: uvx spawn (best-effort) -# Auto-spawn broker if missing, then connect. -codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-spawn +# OPTION 2: manual install +codex mcp add xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker # -# OPTION 2: manual install connect-only -codex mcp add xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker-connect -# -# OPTION 2B: manual install spawn -codex mcp add xcode -- /Users/USERNAME/bin/xcodemcpwrapper --broker-spawn -# -# OPTION 3: local dev (venv) connect-only -codex mcp add xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker-connect -# -# OPTION 3B: local dev (venv) spawn -codex mcp add xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker-spawn +# OPTION 3: local dev (venv) +codex mcp add xcode -- /path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper --broker # # Verify: # codex mcp list diff --git a/config/cursor-mcp-broker.json b/config/cursor-mcp-broker.json index 2abc2ff5..4cf2a9b8 100644 --- a/config/cursor-mcp-broker.json +++ b/config/cursor-mcp-broker.json @@ -3,52 +3,28 @@ "_note": "Copy ONE option block into your real xcode-tools server entry.", "mcpServers": { "xcode-tools": { - "_option1_uvx_connect_only": { - "_comment": "Connect to an already-running broker daemon.", + "_option1_uvx": { + "_comment": "Recommended: auto-detect broker, spawn if needed.", "command": "uvx", "args": [ "--from", "mcpbridge-wrapper", "mcpbridge-wrapper", - "--broker-connect" + "--broker" ] }, - "_option1b_uvx_spawn": { - "_comment": "Best-effort auto-spawn broker if missing, then connect.", - "command": "uvx", - "args": [ - "--from", - "mcpbridge-wrapper", - "mcpbridge-wrapper", - "--broker-spawn" - ] - }, - "_option2_manual_connect_only": { - "_comment": "Manual install path example; connect-only mode.", + "_option2_manual": { + "_comment": "Manual install path example.", "command": "/Users/USERNAME/bin/xcodemcpwrapper", "args": [ - "--broker-connect" - ] - }, - "_option2b_manual_spawn": { - "_comment": "Manual install path example; auto-spawn mode.", - "command": "/Users/USERNAME/bin/xcodemcpwrapper", - "args": [ - "--broker-spawn" - ] - }, - "_option3_local_dev_connect_only": { - "_comment": "Local venv entry point; connect-only mode.", - "command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper", - "args": [ - "--broker-connect" + "--broker" ] }, - "_option3b_local_dev_spawn": { - "_comment": "Local venv entry point; auto-spawn mode.", + "_option3_local_dev": { + "_comment": "Local venv entry point.", "command": "/path/to/XcodeMCPWrapper/.venv/bin/mcpbridge-wrapper", "args": [ - "--broker-spawn" + "--broker" ] } } diff --git a/docs/broker-mode.md b/docs/broker-mode.md index c58c7937..9505edc9 100644 --- a/docs/broker-mode.md +++ b/docs/broker-mode.md @@ -10,8 +10,6 @@ Broker mode lets short-lived MCP client processes share a single long-lived upst | *(none — default)* | `direct`: each wrapper process launches its own upstream bridge. | | `--broker-daemon` | **Daemon host**: long-lived process that owns the upstream bridge and accepts client connections on a Unix socket. Start this once, then point clients at it. | | `--broker` | **Proxy + auto-detect** *(recommended)*: connects to a running broker if one is alive, spawns a new daemon otherwise. Automatically recovers stale socket/PID files left by a crashed daemon. | -| `--broker-connect` | **Proxy**: connects to an already-running broker socket and forwards stdio. Legacy alias — use `--broker` for new configs. | -| `--broker-spawn` | **Proxy + auto-start**: legacy alias for `--broker`. | Use broker mode when you want lower process churn across repeated MCP client restarts. @@ -22,13 +20,13 @@ Recommended topology for multiple agents/clients: 1. **Unified single-config (recommended):** use the same client args everywhere: `--broker --web-ui --web-ui-config `. 2. **Dedicated host alternative:** run one explicit broker host with - `--broker-daemon --web-ui` and configure clients with `--broker-connect`. + `--broker-daemon --web-ui` and configure clients with `--broker`. Web UI behavior in broker modes: - `--broker-daemon --web-ui` starts broker + dashboard in one host process. - `--broker --web-ui` forwards Web UI flags to the spawned daemon when auto-start is needed; if a broker is already running without `--web-ui`, a warning is printed to stderr. -- `--broker-connect` never starts a dashboard by itself. +- When `--broker` reuses an already-running daemon, it does not change that daemon's dashboard state. - Only one process can own a given Web UI `host:port`. - If dashboard bind fails (for example port already in use), broker transport continues and only dashboard startup is skipped. @@ -61,7 +59,7 @@ nohup uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper \ > "$HOME/.mcpbridge_wrapper/broker.log" 2>&1 & ``` -Then configure MCP clients with `--broker-connect` (see client examples below). +Then configure MCP clients with `--broker` (see client examples below). `--broker` is the recommended alternative that auto-detects: connects if a broker is alive, spawns otherwise (including dashboard args): @@ -172,16 +170,16 @@ codex mcp add xcode -- \ --broker --web-ui --web-ui-config "$HOME/.config/xcodemcpwrapper/webui.json" ``` -### Dedicated host + connect-only alternative +### Dedicated host alternative -If you prefer explicit host lifecycle management, start one `--broker-daemon --web-ui` process manually and configure clients with `--broker-connect` only. +If you prefer explicit host lifecycle management, start one `--broker-daemon --web-ui` process manually and configure clients with `--broker`. ## Migration from direct mode to broker mode 1. Back up your current MCP client configuration. 2. Choose one rollout pattern: - Unified config: set clients to `--broker --web-ui --web-ui-config `. - - Dedicated host: start `--broker-daemon --web-ui` once and set clients to `--broker-connect`. + - Dedicated host: start `--broker-daemon --web-ui` once and set clients to `--broker`. 3. Restart each MCP client. 4. Run a first MCP request and verify broker files exist: - `~/.mcpbridge_wrapper/broker.pid` @@ -190,7 +188,7 @@ If you prefer explicit host lifecycle management, start one `--broker-daemon --w ## Rollback to direct mode -1. Remove `--broker`, `--broker-connect`, or `--broker-spawn` from MCP config args. +1. Remove `--broker` from MCP config args. 2. Restart the MCP client. 3. Stop any running broker process and remove stale files: @@ -206,7 +204,7 @@ rm -f "$PID_FILE" "$SOCK" ## Limitations - Broker mode currently uses local Unix socket paths and is intended for single-user local workflows. -- `--broker` and `--broker-spawn` automatically detect and remove stale socket/PID files left by a crashed daemon before spawning a new one. Manual cleanup is only needed when using `--broker-connect` (connect-only mode), which does not perform the liveness check. +- `--broker` automatically detects and removes stale socket/PID files left by a crashed daemon before spawning a new one. ## Security boundary diff --git a/docs/claude-setup.md b/docs/claude-setup.md index ab621920..96f9170e 100644 --- a/docs/claude-setup.md +++ b/docs/claude-setup.md @@ -29,11 +29,8 @@ claude mcp add --transport stdio xcode -- uvx --from 'mcpbridge-wrapper[webui]' claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker ``` -Advanced — connect to an already-running broker only (no auto-spawn): - -```bash -claude mcp add --transport stdio xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect -``` +If you run a dedicated host with `--broker-daemon`, keep clients on `--broker` +so they attach when available and auto-recover when the host is absent. ## Alternative: Using Manual Installation diff --git a/docs/codex-setup.md b/docs/codex-setup.md index 43d83a72..e86cbf17 100644 --- a/docs/codex-setup.md +++ b/docs/codex-setup.md @@ -29,11 +29,8 @@ codex mcp add xcode -- uvx --from 'mcpbridge-wrapper[webui]' mcpbridge-wrapper - codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker ``` -Advanced — connect to an already-running broker only (no auto-spawn): - -```bash -codex mcp add xcode -- uvx --from mcpbridge-wrapper mcpbridge-wrapper --broker-connect -``` +If you run a dedicated host with `--broker-daemon`, keep clients on `--broker` +so they attach when available and auto-recover when the host is absent. ## Alternative: Using Manual Installation diff --git a/docs/cursor-setup.md b/docs/cursor-setup.md index acd03031..04202b9f 100644 --- a/docs/cursor-setup.md +++ b/docs/cursor-setup.md @@ -74,25 +74,9 @@ Edit `~/.cursor/mcp.json` directly: } ``` -### Using uvx in Broker Mode (Connect-only, advanced) - -Use `--broker-connect` only when you manage the broker daemon lifecycle yourself: - -```json -{ - "mcpServers": { - "xcode-tools": { - "command": "uvx", - "args": [ - "--from", - "mcpbridge-wrapper", - "mcpbridge-wrapper", - "--broker-connect" - ] - } - } -} -``` +If you manage a dedicated host with `--broker-daemon`, keep client args on +`--broker`: clients will attach when the host is alive and auto-recover by +spawning when it is not. ### Using Manual Installation diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index e2876f1e..231a26e8 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -306,7 +306,7 @@ Prefer `kill` (`SIGTERM`) first; use `kill -9` only when the process does not ex - MCP can stay healthy even if Web UI startup is skipped. - Only one process can own a given Web UI `host:port`. - Dashboard starts in a direct-mode owner (`--web-ui`) or a broker host (`--broker-daemon --web-ui`). -- `--broker-connect` never starts a dashboard by itself; `--broker --web-ui` only starts one when it must spawn a host. +- `--broker --web-ui` only starts a dashboard when it must spawn a host; when attaching to an existing host it does not retrofit dashboard settings. - If dashboard bind fails (port already in use), wrapper logs a warning and continues MCP without dashboard hosting. - A healthy MCP status does not guarantee an active dashboard listener on the expected port. @@ -332,7 +332,7 @@ If step 1 returns no listener, no process currently owns the dashboard port. 1. **Single dashboard owner (direct mode):** keep `--web-ui` on one client config only. 2. **Use separate dashboard ports:** assign unique `--web-ui-port` values per process. 3. **Unified broker single-config:** use `--broker --web-ui --web-ui-config ` in all clients so one spawned host owns the dashboard. -4. **Dedicated host pattern:** run one `--broker-daemon --web-ui` process, keep clients on `--broker-connect`, and monitor `~/.mcpbridge_wrapper/broker.log`. +4. **Dedicated host pattern:** run one `--broker-daemon --web-ui` process, keep clients on `--broker`, and monitor `~/.mcpbridge_wrapper/broker.log`. 5. **Standalone diagnostics:** run `--web-ui-only` when you need dashboard-only debugging independent from MCP startup. See also: @@ -427,7 +427,7 @@ Or exits with the error text in logs. **Cause:** The broker socket is missing or not ready. -**Note:** When using `--broker` or `--broker-spawn`, stale socket/PID files from a crashed daemon are detected and removed automatically. Manual cleanup is only needed if you are using `--broker-connect` (connect-only mode). +**Note:** When using `--broker`, stale socket/PID files from a crashed daemon are detected and removed automatically. **Solution:** @@ -435,7 +435,7 @@ Or exits with the error text in logs. PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; SOCK="$HOME/.mcpbridge_wrapper/broker.sock"; if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then echo "broker running"; else echo "broker not running"; fi; ls -l "$SOCK" 2>/dev/null || echo "socket missing" ``` -If broker is not running, switch to `--broker` (auto-detects and spawns) or start it manually and use `--broker-connect`. +If broker is not running, use `--broker` (auto-detects and spawns) or start it manually, then reconnect with `--broker`. ### "Warning: broker is running without --web-ui on port N" @@ -446,7 +446,7 @@ Warning: broker is running without --web-ui on port 8080. Restart the broker to Hint: stop the running broker (rm ~/.mcpbridge_wrapper/broker.sock ~/.mcpbridge_wrapper/broker.pid) then reconnect with --broker --web-ui. ``` -**Cause:** You passed `--broker --web-ui` (or `--broker-spawn --web-ui`) but the broker daemon that is already running was started *without* `--web-ui`. The wrapper detects that port `8080` (or your configured port) is not accepting connections and prints this actionable warning. The MCP session continues normally. +**Cause:** You passed `--broker --web-ui` but the broker daemon that is already running was started *without* `--web-ui`. The wrapper detects that port `8080` (or your configured port) is not accepting connections and prints this actionable warning. The MCP session continues normally. **Solution:** @@ -475,7 +475,7 @@ RuntimeError: Broker already running (PID ...) **Cause:** A live broker process already owns the lock. **Solution:** -1. Reuse the existing broker with `--broker-connect`, or +1. Reuse the existing broker with `--broker`, or 2. Stop the existing PID first: ```bash @@ -484,9 +484,9 @@ PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; if [ -f "$PID_FILE" ]; then kill ### Stale broker lock/socket recovery -When using `--broker` or `--broker-spawn`, stale socket/PID files are detected automatically: the proxy checks whether the socket is actually accepting connections and, if not, removes the stale files and spawns a fresh daemon. No manual cleanup is required in normal use. +When using `--broker`, stale socket/PID files are detected automatically: the proxy checks whether the socket is actually accepting connections and, if not, removes the stale files and spawns a fresh daemon. No manual cleanup is required in normal use. -If you are using `--broker-connect` (connect-only, no auto-spawn) and a crash has left orphaned files, clean them explicitly: +If startup is repeatedly blocked by orphaned files in your environment, clean them explicitly: ```bash PID_FILE="$HOME/.mcpbridge_wrapper/broker.pid"; SOCK="$HOME/.mcpbridge_wrapper/broker.sock"; if [ -f "$PID_FILE" ] && ! kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then rm -f "$PID_FILE"; fi; if [ -S "$SOCK" ]; then rm -f "$SOCK"; fi @@ -523,7 +523,7 @@ rm -f ~/.mcpbridge_wrapper/broker.pid ~/.mcpbridge_wrapper/broker.sock ### Rollback to direct mode (verified flow) -1. Remove `--broker`, `--broker-connect`, or `--broker-spawn` from your MCP config command args. +1. Remove `--broker` from your MCP config command args. 2. Restart the MCP client. 3. Stop and clean broker state: diff --git a/docs/webui-setup.md b/docs/webui-setup.md index 87cb5984..e1d27d67 100644 --- a/docs/webui-setup.md +++ b/docs/webui-setup.md @@ -98,14 +98,14 @@ The Web UI dashboard is hosted by the wrapper process that successfully binds th Recommended patterns: 1. **Single owner (recommended):** enable `--web-ui` for one designated client process only. -2. **Unified broker config (multi-agent):** use `--broker-spawn --web-ui --web-ui-config ` across Cursor/Zed/Claude/Codex so the first auto-spawn host owns one shared dashboard endpoint. +2. **Unified broker config (multi-agent):** use `--broker --web-ui --web-ui-config ` across Cursor/Zed/Claude/Codex so the first auto-spawn host owns one shared dashboard endpoint. 3. **Separate ports per process:** if you truly need multiple dashboards, give each process its own port. Broker-mode note: - `--broker-daemon --web-ui` starts the dashboard in the broker host process. -- `--broker-spawn --web-ui` can start the dashboard when it has to spawn the broker host. -- `--broker-connect` never starts the dashboard by itself. +- `--broker --web-ui` can start the dashboard when it has to spawn the broker host. +- When `--broker` attaches to an already-running host, it does not change that host's dashboard state. - If dashboard bind fails, broker MCP transport still runs and dashboard startup is skipped. For full single-config examples by client (Cursor, Zed, Claude Code, Codex CLI), see [Broker Mode Guide](broker-mode.md#client-configuration-examples). diff --git a/src/mcpbridge_wrapper/__main__.py b/src/mcpbridge_wrapper/__main__.py index 703ce363..685f8e8e 100644 --- a/src/mcpbridge_wrapper/__main__.py +++ b/src/mcpbridge_wrapper/__main__.py @@ -283,15 +283,13 @@ def _parse_broker_args( ) -> Tuple[bool, bool, bool, list]: """Parse broker arguments from command-line args. - Extracts ``--broker-daemon``, ``--broker-connect``, ``--broker-spawn``, - and ``--broker`` flags and returns them along with the remaining args to - forward to the bridge. Broker-only flags are *never* forwarded to + Extracts ``--broker-daemon`` and ``--broker`` flags and returns them + along with the remaining args to forward to the bridge. Broker-only flags + are *never* forwarded to ``xcrun mcpbridge``. ``--broker`` is the recommended flag: it auto-detects whether a daemon is - already running and spawns one if needed (equivalent to ``--broker-spawn``). - ``--broker-spawn`` and ``--broker-connect`` are kept as hidden aliases for - backwards compatibility. + already running and spawns one if needed. Args: args: Command-line arguments list. @@ -307,13 +305,6 @@ def _parse_broker_args( for arg in args: if arg == "--broker-daemon": broker_daemon = True - elif arg == "--broker-connect": - # Legacy alias: connect-only (no auto-spawn). - broker_connect = True - elif arg == "--broker-spawn": - # Legacy alias: auto-spawn then connect. - broker_spawn = True - broker_connect = True elif arg == "--broker": # Recommended flag: auto-detect (spawn if needed, then connect). broker_spawn = True @@ -477,7 +468,7 @@ def main() -> int: Supports optional --web-ui flag to start a monitoring dashboard. Supports optional --broker-daemon flag to start a persistent broker host. - Supports optional --broker-connect / --broker-spawn flags for proxy mode. + Supports optional --broker flag for proxy mode. Returns: Exit code from the bridge process (0 for success) diff --git a/src/mcpbridge_wrapper/broker/proxy.py b/src/mcpbridge_wrapper/broker/proxy.py index 3218a778..887f0753 100644 --- a/src/mcpbridge_wrapper/broker/proxy.py +++ b/src/mcpbridge_wrapper/broker/proxy.py @@ -6,7 +6,7 @@ This allows existing MCP clients configured for stdio to transparently use the persistent broker without any client-side changes beyond their -command configuration (adding ``--broker-connect`` flag). +command configuration (adding ``--broker`` flag). See SPECS/ARCHIVE/P13-T1_*/broker_architecture_spec.md §3.7 for the sequence diagram of the proxy connect/disconnect lifecycle. @@ -37,8 +37,7 @@ class BrokerProxy: Shared broker configuration (socket path, PID file, upstream cmd). auto_spawn: When ``True``, attempt to spawn the broker daemon if the socket is - absent before connecting. Corresponds to the ``--broker-spawn`` CLI - flag. + absent before connecting. Corresponds to the ``--broker`` CLI flag. connect_timeout: Maximum seconds to wait for the broker socket to become available. web_ui_port: diff --git a/tests/unit/test_broker_proxy.py b/tests/unit/test_broker_proxy.py index 3137c168..805f9177 100644 --- a/tests/unit/test_broker_proxy.py +++ b/tests/unit/test_broker_proxy.py @@ -7,8 +7,8 @@ - EOF on socket causes clean exit - auto_spawn: spawns broker subprocess when socket absent - auto_spawn: no-op when broker already running (PID file present) -- _parse_broker_args: --broker-connect flag -- _parse_broker_args: --broker-spawn implies --broker-connect +- _parse_broker_args: --broker enables spawn+connect +- _parse_broker_args: legacy broker flags pass through unchanged - _parse_broker_args: unknown flags pass through """ @@ -775,37 +775,36 @@ def test_no_flags_leaves_all_args(self) -> None: assert spawn is False assert remaining == ["--some-flag", "value"] - def test_broker_connect_flag(self) -> None: - daemon, connect, spawn, remaining = _parse_broker_args(["--broker-connect"]) + def test_broker_flag_sets_spawn_and_connect(self) -> None: + daemon, connect, spawn, remaining = _parse_broker_args(["--broker"]) assert daemon is False assert connect is True - assert spawn is False + assert spawn is True assert remaining == [] - def test_broker_spawn_implies_connect(self) -> None: + def test_legacy_broker_connect_flag_is_forwarded(self) -> None: + daemon, connect, spawn, remaining = _parse_broker_args(["--broker-connect"]) + assert daemon is False + assert connect is False + assert spawn is False + assert remaining == ["--broker-connect"] + + def test_legacy_broker_spawn_flag_is_forwarded(self) -> None: daemon, connect, spawn, remaining = _parse_broker_args(["--broker-spawn"]) assert daemon is False - assert connect is True - assert spawn is True - assert remaining == [] + assert connect is False + assert spawn is False + assert remaining == ["--broker-spawn"] def test_unknown_flags_pass_through(self) -> None: daemon, connect, spawn, remaining = _parse_broker_args( - ["--broker-connect", "--other-flag", "val"] + ["--other-flag", "val"] ) assert daemon is False - assert connect is True + assert connect is False + assert spawn is False assert remaining == ["--other-flag", "val"] - def test_both_flags_together(self) -> None: - daemon, connect, spawn, remaining = _parse_broker_args( - ["--broker-connect", "--broker-spawn"] - ) - assert daemon is False - assert connect is True - assert spawn is True - assert remaining == [] - def test_empty_args(self) -> None: daemon, connect, spawn, remaining = _parse_broker_args([]) assert daemon is False diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 2339a515..872581ee 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -905,23 +905,23 @@ def test_no_flags_returns_all_as_remaining(self): assert spawn is False assert remaining == ["--some-flag"] - def test_broker_connect_flag(self): + def test_legacy_broker_connect_flag_is_forwarded(self): from mcpbridge_wrapper.__main__ import _parse_broker_args daemon, connect, spawn, remaining = _parse_broker_args(["--broker-connect"]) assert daemon is False - assert connect is True + assert connect is False assert spawn is False - assert remaining == [] + assert remaining == ["--broker-connect"] - def test_broker_spawn_implies_connect(self): + def test_legacy_broker_spawn_flag_is_forwarded(self): from mcpbridge_wrapper.__main__ import _parse_broker_args daemon, connect, spawn, remaining = _parse_broker_args(["--broker-spawn"]) assert daemon is False - assert connect is True - assert spawn is True - assert remaining == [] + assert connect is False + assert spawn is False + assert remaining == ["--broker-spawn"] def test_broker_daemon_flag(self): from mcpbridge_wrapper.__main__ import _parse_broker_args @@ -962,26 +962,9 @@ def test_broker_flag_not_forwarded_to_bridge(self): class TestMainBrokerMode: """Tests for main() broker proxy mode branch.""" - def test_main_broker_connect_success(self): - """main() with --broker-connect runs proxy and returns 0.""" - argv = ["mcpbridge-wrapper", "--broker-connect"] - with patch("mcpbridge_wrapper.__main__.sys.argv", argv), patch( - "mcpbridge_wrapper.broker.proxy.BrokerProxy" - ) as mock_proxy_cls, patch( - "mcpbridge_wrapper.broker.types.BrokerConfig" - ) as mock_cfg_cls, patch("asyncio.run") as mock_run: - mock_cfg_cls.default.return_value = MagicMock() - mock_proxy_cls.return_value = MagicMock() - mock_run.return_value = None - - result = main() - - assert result == 0 - mock_run.assert_called_once() - - def test_main_broker_connect_timeout_returns_1(self): - """main() with --broker-connect returns 1 on TimeoutError.""" - argv = ["mcpbridge-wrapper", "--broker-connect"] + def test_main_broker_flag_timeout_returns_1(self): + """main() with --broker returns 1 on TimeoutError.""" + argv = ["mcpbridge-wrapper", "--broker"] with patch("mcpbridge_wrapper.__main__.sys.argv", argv), patch( "mcpbridge_wrapper.broker.proxy.BrokerProxy" ) as mock_proxy_cls, patch( @@ -1029,27 +1012,9 @@ def test_main_broker_flag_success(self): assert result == 0 mock_run.assert_called_once() - def test_main_broker_spawn_sets_auto_spawn(self): - """main() with --broker-spawn constructs BrokerProxy(auto_spawn=True).""" - argv = ["mcpbridge-wrapper", "--broker-spawn"] - with patch("mcpbridge_wrapper.__main__.sys.argv", argv), patch( - "mcpbridge_wrapper.broker.proxy.BrokerProxy" - ) as mock_proxy_cls, patch( - "mcpbridge_wrapper.broker.types.BrokerConfig" - ) as mock_cfg_cls, patch("asyncio.run") as mock_run: - mock_cfg_cls.default.return_value = MagicMock() - mock_proxy_cls.return_value = MagicMock() - mock_run.return_value = None - - result = main() - - assert result == 0 - _, kwargs = mock_proxy_cls.call_args - assert kwargs.get("auto_spawn") is True - - def test_main_broker_connect_keyboard_interrupt_returns_0(self): - """main() with --broker-connect returns 0 on KeyboardInterrupt.""" - argv = ["mcpbridge-wrapper", "--broker-connect"] + def test_main_broker_flag_keyboard_interrupt_returns_0(self): + """main() with --broker returns 0 on KeyboardInterrupt.""" + argv = ["mcpbridge-wrapper", "--broker"] with patch("mcpbridge_wrapper.__main__.sys.argv", argv), patch( "mcpbridge_wrapper.broker.proxy.BrokerProxy" ) as mock_proxy_cls, patch( @@ -1062,11 +1027,11 @@ def test_main_broker_connect_keyboard_interrupt_returns_0(self): assert result == 0 - def test_main_broker_spawn_with_webui_propagates_spawn_args(self): - """main() with --broker-spawn --web-ui passes web-ui args to proxy spawn.""" + def test_main_broker_with_webui_propagates_spawn_args(self): + """main() with --broker --web-ui passes web-ui args to proxy spawn.""" argv = [ "mcpbridge-wrapper", - "--broker-spawn", + "--broker", "--web-ui", "--web-ui-restart", "--web-ui-port", @@ -1265,8 +1230,8 @@ def test_main_rejects_webui_only_with_broker_daemon(self): assert result == 2 mock_create.assert_not_called() - def test_main_rejects_webui_only_with_broker_connect(self): - argv = ["mcpbridge-wrapper", "--web-ui-only", "--broker-connect"] + def test_main_rejects_webui_only_with_broker_flag(self): + argv = ["mcpbridge-wrapper", "--web-ui-only", "--broker"] with patch("mcpbridge_wrapper.__main__.sys.argv", argv), patch( "mcpbridge_wrapper.__main__.create_bridge" ) as mock_create: From dfb16429bba8e08c07821049057fec191de1a9b7 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:35:11 +0300 Subject: [PATCH 5/8] Archive task P2-T6: Remove legacy --broker-connect and --broker-spawn flags (PASS) --- SPECS/ARCHIVE/INDEX.md | 4 +++- ...y_broker_connect_and_broker_spawn_flags.md | 4 ++++ .../P2-T6_Validation_Report.md | 0 SPECS/INPROGRESS/next.md | 22 ++++++++----------- SPECS/Workplan.md | 12 +++++----- 5 files changed, 22 insertions(+), 20 deletions(-) rename SPECS/{INPROGRESS => ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags}/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md (97%) rename SPECS/{INPROGRESS => ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags}/P2-T6_Validation_Report.md (100%) diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index b80132e3..7fcfac1e 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -1,11 +1,12 @@ # mcpbridge-wrapper Tasks Archive -**Last Updated:** 2026-03-01 (P1-T7 archived) +**Last Updated:** 2026-03-01 (P2-T6 archived) ## Archived Tasks | Task ID | Folder | Archived | Verdict | |---------|--------|----------|---------| +| P2-T6 | [P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/](P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/) | 2026-03-01 | PASS | | P1-T7 | [P1-T7_Hide_README_version_badge_maintenance_note/](P1-T7_Hide_README_version_badge_maintenance_note/) | 2026-03-01 | PASS | | P1-T4 | [P1-T4_Update_docs_broker_robustness/](P1-T4_Update_docs_broker_robustness/) | 2026-03-01 | PASS | | P2-T5 | [P2-T5_Warn_when_broker_lacks_web_ui/](P2-T5_Warn_when_broker_lacks_web_ui/) | 2026-03-01 | PASS | @@ -303,6 +304,7 @@ | Date | Task ID | Action | |------|---------|--------| +| 2026-03-01 | P2-T6 | Archived Remove legacy --broker-connect and --broker-spawn flags (PASS) | | 2026-03-01 | P1-T7 | Archived REVIEW_P1-T7_readme_badge_note report | | 2026-03-01 | P1-T7 | Archived FOLLOWUP_P1-T7_readme_badge_note report | | 2026-03-01 | P1-T7 | Archived Hide README version badge maintenance note (PASS) | diff --git a/SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md b/SPECS/ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md similarity index 97% rename from SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md rename to SPECS/ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md index d67d98a1..647c1dd3 100644 --- a/SPECS/INPROGRESS/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md +++ b/SPECS/ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags.md @@ -58,3 +58,7 @@ Out of scope: Low-medium: removing aliases is a CLI behavior change. Mitigate by fully aligning docs/tests and preserving clear `--broker`/`--broker-daemon` instructions. + +--- +**Archived:** 2026-03-01 +**Verdict:** PASS diff --git a/SPECS/INPROGRESS/P2-T6_Validation_Report.md b/SPECS/ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/P2-T6_Validation_Report.md similarity index 100% rename from SPECS/INPROGRESS/P2-T6_Validation_Report.md rename to SPECS/ARCHIVE/P2-T6_Remove_legacy_broker_connect_and_broker_spawn_flags/P2-T6_Validation_Report.md diff --git a/SPECS/INPROGRESS/next.md b/SPECS/INPROGRESS/next.md index 7b362b68..a8c42db6 100644 --- a/SPECS/INPROGRESS/next.md +++ b/SPECS/INPROGRESS/next.md @@ -1,16 +1,12 @@ -# Active Task +# No Active Task -**Status:** Selected — ready for planning/execution. +**Status:** Idle — P2-T6 archived. Select the next task from `SPECS/Workplan.md`. -## Task Metadata +## Recently Archived -- **Task ID:** P2-T6 -- **Task Name:** Remove legacy --broker-connect and --broker-spawn flags -- **Priority:** P1 -- **Dependencies:** P2-T1 -- **Parallelizable:** yes -- **Source:** `SPECS/Workplan.md` - -## Summary - -Remove obsolete broker CLI aliases (`--broker-connect`, `--broker-spawn`) from parser/tests/docs and keep `--broker` as the single proxy mode entrypoint. +- **P2-T6** — Remove legacy --broker-connect and --broker-spawn flags (2026-03-01, PASS) +- **P1-T7** — Hide README version badge maintenance note (2026-03-01, PASS) +- **P1-T4** — Update docs to reflect broker robustness improvements (2026-03-01, PASS) +- **P2-T5** — Warn or restart daemon when --web-ui requested but running broker lacks it (2026-03-01, PASS) +- **P2-T4** — Surface broker unavailability as JSON-RPC error instead of silent timeout (2026-03-01, PASS) +- **P2-T3** — Fix double-spawn race condition when MCP client toggles rapidly (2026-03-01, PASS) diff --git a/SPECS/Workplan.md b/SPECS/Workplan.md index 4582f03d..ed639b7c 100644 --- a/SPECS/Workplan.md +++ b/SPECS/Workplan.md @@ -184,8 +184,8 @@ Add new tasks using the canonical template in [TASK_TEMPLATE.md](TASK_TEMPLATE.m - [x] Warning text is actionable (tells user how to fix it) - [x] MCP session continues normally despite the warning -#### ⬜ P2-T6: Remove legacy --broker-connect and --broker-spawn flags -- **Status:** ⬜ Pending +#### ✅ P2-T6: Remove legacy --broker-connect and --broker-spawn flags +- **Status:** ✅ Completed (2026-03-01) - **Description:** Broker mode aliases `--broker-connect` and `--broker-spawn` were kept only for backwards compatibility. Broker mode has not shipped yet, so compatibility is unnecessary and the aliases now add confusion to docs and tests. Remove both legacy flags from wrapper CLI parsing and documentation, and keep `--broker` as the single proxy-mode entrypoint (plus `--broker-daemon` for host mode). - **Priority:** P1 - **Dependencies:** P2-T1 @@ -195,10 +195,10 @@ Add new tasks using the canonical template in [TASK_TEMPLATE.md](TASK_TEMPLATE.m - `tests/unit/test_main.py`, `tests/unit/test_broker_proxy.py` — remove/update alias-specific tests - `README.md` and `docs/*.md` — remove alias guidance/examples and align to `--broker` - **Acceptance Criteria:** - - [ ] Wrapper no longer accepts `--broker-connect` and `--broker-spawn` as broker control flags - - [ ] Documentation no longer presents legacy alias usage or compatibility notes - - [ ] Broker mode guidance remains clear with `--broker` (proxy) and `--broker-daemon` (host) - - [ ] Required quality gates pass (`pytest`, `ruff check src/`, `mypy src/`, `pytest --cov` with coverage >=90%) + - [x] Wrapper no longer accepts `--broker-connect` and `--broker-spawn` as broker control flags + - [x] Documentation no longer presents legacy alias usage or compatibility notes + - [x] Broker mode guidance remains clear with `--broker` (proxy) and `--broker-daemon` (host) + - [x] Required quality gates pass (`pytest`, `ruff check src/`, `mypy src/`, `pytest --cov` with coverage >=90%) ### Bug Fixes From 7f13bca5da72717c57d9092fa371b2b4a5799dc2 Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:35:41 +0300 Subject: [PATCH 6/8] Review P2-T6: legacy broker flags removal --- ...REVIEW_p2_t6_remove_legacy_broker_flags.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md diff --git a/SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md b/SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md new file mode 100644 index 00000000..19079336 --- /dev/null +++ b/SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md @@ -0,0 +1,33 @@ +## REVIEW REPORT — P2-T6 Legacy Broker Flag Removal + +**Scope:** `origin/main..HEAD` +**Files:** 25 + +### Summary Verdict +- [x] Approve +- [ ] Approve with comments +- [ ] Request changes +- [ ] Block + +### Critical Issues +- None. + +### Secondary Issues +- None. + +### Architectural Notes +- The CLI surface is now simpler and internally consistent: `--broker` (proxy) and `--broker-daemon` (host). +- Parser behavior is explicit: removed flags are no longer broker controls and are treated as passthrough args. +- Docs, DocC mirrors, and configuration templates are aligned to the same model. + +### Tests +- Quality gates were run and passed: + - `pytest` → `735 passed, 5 skipped` + - `ruff check src/` → pass + - `mypy src/` → pass + - `pytest --cov` → `91.26%` (>= 90%) +- Targeted parser/main broker tests passed after behavior change. + +### Next Steps +- No actionable follow-up items from this review. +- FOLLOW-UP step is skipped per FLOW rules. From 712d9a3ecf2144baa50b292d154e7e13d31cf92d Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:36:10 +0300 Subject: [PATCH 7/8] Archive REVIEW_p2_t6_remove_legacy_broker_flags report --- SPECS/ARCHIVE/INDEX.md | 2 ++ .../_Historical}/REVIEW_p2_t6_remove_legacy_broker_flags.md | 0 2 files changed, 2 insertions(+) rename SPECS/{INPROGRESS => ARCHIVE/_Historical}/REVIEW_p2_t6_remove_legacy_broker_flags.md (100%) diff --git a/SPECS/ARCHIVE/INDEX.md b/SPECS/ARCHIVE/INDEX.md index 7fcfac1e..6ffb40da 100644 --- a/SPECS/ARCHIVE/INDEX.md +++ b/SPECS/ARCHIVE/INDEX.md @@ -296,6 +296,7 @@ | [REVIEW_bug_t13_capture_params_hint.md](_Historical/REVIEW_bug_t13_capture_params_hint.md) | Review report for BUG-T13 | | [REVIEW_bug_t9_orphaned_webui_process.md](BUG-T9_Orphaned_Web_UI_server_process_blocks_port_after_MCP_client_disconnect_or_config_change/REVIEW_bug_t9_orphaned_webui_process.md) | Review report for BUG-T9 | | [REVIEW_bug_t11_request_timeline.md](_Historical/REVIEW_bug_t11_request_timeline.md) | Review report for BUG-T11 | +| [REVIEW_p2_t6_remove_legacy_broker_flags.md](_Historical/REVIEW_p2_t6_remove_legacy_broker_flags.md) | Review report for P2-T6 | | [REVIEW_bug_t10.md](_Historical/REVIEW_bug_t10.md) | Review report for BUG-T10 | | [REVIEW_BUG-T12_audit_log_live_updates.md](BUG-T12_Audit_Log_does_not_show_new_calls/REVIEW_BUG-T12_audit_log_live_updates.md) | Review report for BUG-T12 | @@ -304,6 +305,7 @@ | Date | Task ID | Action | |------|---------|--------| +| 2026-03-01 | P2-T6 | Archived REVIEW_p2_t6_remove_legacy_broker_flags report | | 2026-03-01 | P2-T6 | Archived Remove legacy --broker-connect and --broker-spawn flags (PASS) | | 2026-03-01 | P1-T7 | Archived REVIEW_P1-T7_readme_badge_note report | | 2026-03-01 | P1-T7 | Archived FOLLOWUP_P1-T7_readme_badge_note report | diff --git a/SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md b/SPECS/ARCHIVE/_Historical/REVIEW_p2_t6_remove_legacy_broker_flags.md similarity index 100% rename from SPECS/INPROGRESS/REVIEW_p2_t6_remove_legacy_broker_flags.md rename to SPECS/ARCHIVE/_Historical/REVIEW_p2_t6_remove_legacy_broker_flags.md From 2fa4f84d013285f7c77ad75220ec486fe5a8891d Mon Sep 17 00:00:00 2001 From: Egor Merkushev Date: Sun, 1 Mar 2026 16:38:04 +0300 Subject: [PATCH 8/8] Format P2-T6: run ruff format on broker proxy tests --- tests/unit/test_broker_proxy.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit/test_broker_proxy.py b/tests/unit/test_broker_proxy.py index 805f9177..32215a7e 100644 --- a/tests/unit/test_broker_proxy.py +++ b/tests/unit/test_broker_proxy.py @@ -797,9 +797,7 @@ def test_legacy_broker_spawn_flag_is_forwarded(self) -> None: assert remaining == ["--broker-spawn"] def test_unknown_flags_pass_through(self) -> None: - daemon, connect, spawn, remaining = _parse_broker_args( - ["--other-flag", "val"] - ) + daemon, connect, spawn, remaining = _parse_broker_args(["--other-flag", "val"]) assert daemon is False assert connect is False assert spawn is False