Skip to content

feat(mcp): resolve room-scoped servers during owned Claude SDK startup - #800

Open
bandzalkin wants to merge 3 commits into
mainfrom
feat/claude-owned-mcp-resolver
Open

bandzalkin wants to merge 3 commits into
mainfrom
feat/claude-owned-mcp-resolver

Conversation

@bandzalkin

@bandzalkin bandzalkin commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Rebased onto main d7ab3429cbdb (2026-10-15)

Rebased onto current main (after #709, #804, #789/#775, #796 and #802) as its prerequisite's commit plus one commit; head d52cb24e70018e6d3e478c380d7a70afe448ec59. Integrated into #709's ClaudeRoomSession; MCP readiness waits on the server set bound at resolution. After the first CI run, Codex close no longer fails with "process leader remained unreaped" when a forced kill's exit is reported late (seen on Windows 3.12): it waits for the reap, as callers are already bounded by the room owner's budget; regression test_forced_close_waits_for_an_exit_reported_late.

CHANGELOG.md edits are dropped: Release Please generates it.

Verified at the new head (macOS, Python 3.13): uv sync --all-packages --locked --extra dev, all pre-commit hooks, and the full pytest -q: 8810 passed, 738 skipped. Verification notes further down refer to the previous head.


Summary

Resolve room-scoped external MCP servers during owned Claude SDK startup, preserving reservation, backend, file and child-process custody through cancellation and teardown. Related: #709.

Changes

  • Resolve a fresh room snapshot under the retained startup owner, preserving Band's reserved endpoint, launch precedence and safe configuration failures.
  • Retain startup/readiness and teardown ownership across cancellation, partial startup and failed close; do not release resources still held by a child.
  • Integrate with the shared TurnTask lifecycle from feat(mcp): resolve room-scoped servers during owned Codex startup #797, preserving current activity/acknowledgement STOP behavior rather than replacing its scheduler.
  • Update user-facing configuration documentation and the Unreleased changelog; retain adapter/runtime cancellation and cleanup regressions.

Stack and merge order

Prerequisite PR: #797 (Codex MCP startup and shared lifecycle).
Exact feature-only range: e38e7ffb63dfd2daeeb415c9da3a6550d8ef9ed0..d52cb24e70018e6d3e478c380d7a70afe448ec59.
Merge #797, then #800. This main-targeted PR includes its prerequisite until that merge; review the range above for the Claude-only change. OMP and Copilot lanes are independent.
The prerequisite omits RPC wire-payload and method contents from diagnostics, preserving forwarded error freezing. Codex refuses secret-bearing stdio MCP servers on Windows before launching any process (unsupported-platform: secret-bearing stdio MCP servers require POSIX exec). Env-free Windows stdio, all HTTP servers and POSIX behavior are unchanged; a Windows owned supervisor is outside this delivery. These corrections belong to #797, not the Claude-only delta.
On POSIX, the Claude private MCP directory/file are checked as 0700/0600. On Windows, their privacy relies on the user-profile/temp-directory ACLs, not POSIX modes; chmod only toggles the read-only flag and stat bits do not prove ACL protection. Only the separate POSIX mode test is skipped on Windows, with that reason. All five cleanup-retention tests run on every OS and refuse the actual shutil.rmtree boundary before deleting the file; they retain the file, ownership and successful-retry assertions.

Shared OpenCode test-helper correction

The inherited #797 correction changes the shared OpenCode test helper wait_for to check its readiness predicate before the deadline. The coverage failure waited for FakeClient.prompt_calls before permission injection; the previous helper could time out after a delayed poll without observing work already ready. A deterministic pre-fix probe reproduced that lost observation. This is a test-observer correction, not a product TurnTask/runtime change or a claim of historical main flakiness.
The existing 1.0-second budget and 0.01-second interval are unchanged. False readiness at or beyond expiry still fails without another wait; four regressions cover true/false readiness at and beyond expiry. The exact failing CI wake delay was not measured, so the corrected-head coverage lane remains required proof.

Testing

Corrected head e083173a3dcb0bd6f7a63be2599a6ad103c85ee0 adds a test/doc-only portability correction to rebased head fb6c629d; its fourteen inherited Claude patches remain unchanged. No product code changed. The previous #800 matrix had six identical POSIX-assumption failures and a consequent fixture error in each Windows core lane, not runner flakiness; PowerShell passed in all three without relaxing its timeout.
Fresh macOS Python 3.11.16/3.12.14/3.13.14 Claude SDK + inherited Codex/OpenCode scopes passed 541 (6 existing skips) / 547 / 547 cases, with 24 warnings each. All five static hooks passed after removing an obsolete unused test import. The final six mode/retention cases passed after restoring the cleanup mutation.
Mutation proof: making McpConfigFile.release ignore the injected deletion failure made all five retention tests fail (plus two consequent fixture errors); the original product branch was restored exactly. A standalone real-file smoke observed the safe cleanup error, retained file/directory, then their removal on retry.
Feature-only source stable patch ID is 09c2c1b75556be3b87b20d4f6739a26303341bf1, excluding only changelog/fork metadata. The published-head composition proof must be refreshed after this correction is published. No security alert was dismissed or waived.
Local proof is not the corrected #800 remote all-lane matrix, full coverage-floor gate, staged-package validation or native-provider/live-room acceptance. Complete corrected-head CI remains required before the review return; no fork step is authorized by this publication.

Comment thread src/band/integrations/codex/rpc_base.py Fixed
Comment thread src/band/integrations/codex/rpc_base.py Fixed
Comment thread src/band/integrations/codex/rpc_base.py Fixed
Comment thread src/band/integrations/codex/rpc_base.py Fixed
Comment thread src/band/integrations/codex/rpc_base.py Fixed
@bandzalkin

Copy link
Copy Markdown
Contributor Author

Inherited CodeQL diagnostic findings

The rebased Claude branch inherits the actual fixing commits unchanged: bc0df019 removes wire-payload contents, 39c2d473 removes RPC method contents, and prerequisite ad176506 adds the prelaunch Windows secret-bearing stdio refusal. These are also the rebased equivalents on this branch; their hashes were not rewritten.

RPC frame/queue diagnostics retain only event-kind and length metadata: queue drops identify server requests or notifications; parse/unknown-frame diagnostics retain their transport/type labels and length. No payload or method content is logged by these diagnostics. Forwarded error freezing is unchanged.

Alerts 36–40 have fixed instances on both PR head refs, without dismissal. Alerts 41/42 were reported only on #797, are fixed there and have no #800 instance; their links below point to the corresponding #797 threads. All twelve bot threads are already resolved. This summary replaces further per-thread replies and is not an all-green CI claim.

bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 14, 2026
Source-Base: ad17650
Source-Head: e083173
Applied-Over: 8bb87d3
Conflict-Notes: None; exact feature delta, excluding CHANGELOG.md and FORK-CHANGES.md
Upstream-PR: band-ai#800
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 14, 2026
Source-Base: ad17650
Source-Head: e083173
Applied-Over: 8bb87d3
Conflict-Notes: None; exact feature delta, excluding CHANGELOG.md and FORK-CHANGES.md
Upstream-PR: band-ai#800
bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
Source-Base: ad17650
Source-Head: e083173
Applied-Over: 80fe9e6
Conflict-Notes: band-ai#709 replaced Claude command queues and local retirement maps with RetainedRoom. Port resolver, private launch files, readiness and safe diagnostics into ClaudeRoomSession acquisition/release; keep upstream native no-resolver cancellation and callback contracts. Reuse SharedBandMCPBackend close custody and retained self-disposal instead of obsolete backend/deferred-cleanup fields; an optional stop reporting budget keeps whole-adapter teardown owned. Migrate tests into current one-class files and plain helpers; retain authoritative upstream workspace/backend/startup tests. Dropped duplicated enrollment and retryable-close machinery: mutation of upstream owned-work and failed-close mechanisms fails their probes, restored mechanisms pass. MCP readiness waits on the server set bound at resolution.
Upstream-PR: band-ai#800
bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
Source-Base: ad17650
Source-Head: e083173
Applied-Over: 5a2fc6f
Conflict-Notes: band-ai#709 replaced Claude command queues and local retirement maps with RetainedRoom. Port resolver, private launch files, readiness and safe diagnostics into ClaudeRoomSession acquisition/release; keep upstream native no-resolver cancellation and callback contracts. Reuse SharedBandMCPBackend close custody and retained self-disposal instead of obsolete backend/deferred-cleanup fields; an optional stop reporting budget keeps whole-adapter teardown owned. Migrate tests into current one-class files and plain helpers; retain authoritative upstream workspace/backend/startup tests. Dropped duplicated enrollment and retryable-close machinery: mutation of upstream owned-work and failed-close mechanisms fails their probes, restored mechanisms pass. MCP readiness waits on the server set bound at resolution.
Upstream-PR: band-ai#800
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
Source-Base: ad17650
Source-Head: e083173
Applied-Over: 5a2fc6f
Conflict-Notes: band-ai#709 replaced Claude command queues and local retirement maps with RetainedRoom. Port resolver, private launch files, readiness and safe diagnostics into ClaudeRoomSession acquisition/release; keep upstream native no-resolver cancellation and callback contracts. Reuse SharedBandMCPBackend close custody and retained self-disposal instead of obsolete backend/deferred-cleanup fields; an optional stop reporting budget keeps whole-adapter teardown owned. Migrate tests into current one-class files and plain helpers; retain authoritative upstream workspace/backend/startup tests. Dropped duplicated enrollment and retryable-close machinery: mutation of upstream owned-work and failed-close mechanisms fails their probes, restored mechanisms pass. MCP readiness waits on the server set bound at resolution.
Upstream-PR: band-ai#800
@bandzalkin
bandzalkin force-pushed the feat/claude-owned-mcp-resolver branch from e083173 to 0ce45ad Compare October 15, 2026 03:43
@bandzalkin

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (d7ab3429) at 0ce45ad14e70; the description's new first section lists the conflict resolutions and the verification at this head.

@bandzalkin
bandzalkin force-pushed the feat/claude-owned-mcp-resolver branch from 0ce45ad to d52cb24 Compare October 15, 2026 05:05
@bandzalkin

Copy link
Copy Markdown
Contributor Author

Pushed d52cb24e7001: Codex close now waits for the reap after a forced kill instead of failing at 1s (Windows 3.12 CI failure); regression test added. Description updated.

bandzalkin added a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 15, 2026
Port the reviewed cancellation correction from dd8f3af..942759f4. Delegate acquisition cancellation explicitly to the matching startup owner, preserve first abandonment/cleanup diagnostics, and cover public caller/cleanup orderings after uncancel. Keep Claude-owned retention changes in the stacked Claude PR.
@bandzalkin
bandzalkin force-pushed the feat/claude-owned-mcp-resolver branch from d52cb24 to 8ab244c Compare October 15, 2026 14:01
github-actions Bot pushed a commit to bandzalkin/band-sdk-python that referenced this pull request Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants