Skip to content

fix(mcp): preserve recoverable stale transports#19

Merged
KnotFalse merged 1 commit into
trunkfrom
codex/recoverable-stale-transport
Apr 30, 2026
Merged

fix(mcp): preserve recoverable stale transports#19
KnotFalse merged 1 commit into
trunkfrom
codex/recoverable-stale-transport

Conversation

@KnotFalse
Copy link
Copy Markdown
Contributor

@KnotFalse KnotFalse commented Apr 30, 2026

Summary

  • Preserves initialized MCP transports during stale daemon ingress cleanup, even after their resource-reaped registry entry expires.
  • Keeps stale unbound sockets without recoverable initialized state eligible for timeout cleanup.
  • Bumps local release/runtime identifiers to 0.6.1 and records the local Linux package smoke evidence.

Root Cause

The previous stale cleanup recovery path kept live transports open during soft-reap, but a later daemon ingress pass could still classify an initialized transport as a stale unbound socket after its registry binding had been removed. That closed long-running agent transports that were otherwise capable of implicit rebind.

Validation

  • bun test local-mcp-bun/tests/integration/daemon_ingress_cleanup.test.ts local-mcp-bun/tests/unit/mcp_protocol_session.test.ts
  • bun run --cwd local-mcp-bun lint:spec
  • bun run --cwd local-mcp-bun lint:docs
  • bun run --cwd local-mcp-bun lint:compliance
  • bun run --cwd local-mcp-bun release:check-version -- --version v0.6.1
  • bun run --cwd local-mcp-bun package:release -- --mode=server --version v0.6.1 --clean
  • Packaged Linux binary initialize smoke returned serverInfo.version="0.6.1".

Summary by CodeRabbit

Release Notes – v0.6.1

  • Bug Fixes

    • Improved stale connection cleanup to preserve long-running MCP transports that maintain recoverable initialized state, preventing unnecessary socket closures.
  • Documentation

    • Clarified stale session cleanup behavior and daemon ingress socket lifecycle; connections with recoverable initialized state remain usable after cleanup operations.
  • Chores

    • Version bumped to 0.6.1 across package metadata, extension manifest, and server info.
    • Added integration tests validating daemon ingress cleanup behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cb71eb57-613b-4c45-b993-9018a6bf3ac2

📥 Commits

Reviewing files that changed from the base of the PR and between cdcf22d and fe8364e.

📒 Files selected for processing (10)
  • agent-logs/2026-04-30T004933-0500-recoverable-stale-transport.md
  • local-mcp-bun/README.md
  • local-mcp-bun/chrome-extension/manifest.json
  • local-mcp-bun/package.json
  • local-mcp-bun/src/bridge_transport.ts
  • local-mcp-bun/src/daemon_ingress_server.ts
  • local-mcp-bun/src/mcp_protocol_session.ts
  • local-mcp-bun/tests/integration/daemon_ingress_cleanup.test.ts
  • specs/local-multiplexed-browser-mcp-changelog.md
  • specs/local-multiplexed-browser-mcp-spec.md

Walkthrough

This PR refines daemon ingress stale-connection cleanup logic to preserve sockets with recoverable initialized MCP state, introduces a new public API method to query that state, bumps the version to 0.6.1 across package metadata and implementation files, updates specification and documentation to reflect the narrowed cleanup behavior, and adds integration tests validating the new socket preservation logic.

Changes

Cohort / File(s) Summary
Version Bump
local-mcp-bun/package.json, local-mcp-bun/chrome-extension/manifest.json, local-mcp-bun/src/bridge_transport.ts, local-mcp-bun/src/mcp_protocol_session.ts
Synchronized version number from 0.6.0 to 0.6.1 across package metadata, extension manifest, synthetic extension fixture, and server info.
Protocol Session API
local-mcp-bun/src/mcp_protocol_session.ts
Introduced public has_recoverable_initialized_state() method that returns whether the session is not closed and has an initialized auth mode, enabling socket cleanup guards to check session state.
Daemon Cleanup Logic
local-mcp-bun/src/daemon_ingress_server.ts
Modified stale-connection cleanup loop to preserve unbound idle sockets when their protocol session has recoverable initialized state, preventing premature closure of long-running transports.
Integration Tests
local-mcp-bun/tests/integration/daemon_ingress_cleanup.test.ts
Added wait_for_socket_close() utility and new test validating that stale unbound sockets without recoverable state are cleaned up; adjusted existing test to apply cleanup check at correct stale timestamp.
Specification & Documentation
specs/local-multiplexed-browser-mcp-spec.md, specs/local-multiplexed-browser-mcp-changelog.md, local-mcp-bun/README.md, agent-logs/2026-04-30T004933-0500-recoverable-stale-transport.md
Updated spec to narrow cleanup guards to cases without recoverable initialized state, documented changelog entry with verification checklist, clarified README behavior guarantees, and recorded full agent log with validation results and binary SHA256.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Browser-MCP#17: Modifies daemon ingress socket cleanup logic and mcp_protocol_session state handling to preserve live MCP transports—directly aligned with this PR's recoverable-state preservation mechanism.
  • Browser-MCP#13: Adjusts daemon ingress stale-cleanup guards and session state checks, sharing the same cleanup behavior refinement pattern with this PR's recovery guarantees.

Suggested labels

coderabbitai

Poem

🐰 A socket once doomed to the timeout, now saved,
When recovery blooms in the state that we've paved!
From zero-six-oh to point-one we climb,
Long transports rebind across measure of time,
And idle sockets that can't be restored? Gone, good-bye!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: preserving recoverable stale transports during daemon ingress cleanup, which is the primary objective of this pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/recoverable-stale-transport

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@KnotFalse KnotFalse self-assigned this Apr 30, 2026
@KnotFalse KnotFalse marked this pull request as ready for review April 30, 2026 19:03
Copilot AI review requested due to automatic review settings April 30, 2026 19:03
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR fixes a bug where long-running initialized MCP transport connections could be incorrectly closed by a second daemon ingress cleanup pass after their session registry entry had been removed. The fix adds a has_recoverable_initialized_state() predicate to mcp_protocol_session and uses it to guard the stale unbound socket closure path in daemon_ingress_server, ensuring that only pre-initialize (never-initialized) connections are reclaimed while initialized but unbound connections remain open for implicit rebind.

Confidence Score: 5/5

Safe to merge — targeted, well-tested fix with no regressions identified.

The change is minimal and focused: a new boolean predicate on mcp_protocol_session and a single guard in close_stale_unbound_connections. All three internal tracking maps remain atomically in sync. The existing rebind test is correctly extended to reproduce the second-pass bug, and a new test confirms pre-initialize sockets are still reclaimed. No P0 or P1 issues found.

No files require special attention.

Important Files Changed

Filename Overview
local-mcp-bun/src/mcp_protocol_session.ts Adds has_recoverable_initialized_state() predicate: returns true when !this.closed && this.initialized_auth_mode !== null. Logic is correct and aligns with the session lifecycle.
local-mcp-bun/src/daemon_ingress_server.ts Inserts a has_recoverable_initialized_state() guard in close_stale_unbound_connections; correctly placed after the bound-session skip and before the socket close call. All three tracking maps remain in sync through the existing open/close handlers.
local-mcp-bun/tests/integration/daemon_ingress_cleanup.test.ts Adds a second cleanup tick to the existing rebind test to cover the previously-missed second-pass closure bug, and adds a new test confirming uninitialised stale sockets are still closed.
local-mcp-bun/package.json Version bump from 0.6.0 to 0.6.1; consistent with other version surfaces updated in this PR.
local-mcp-bun/chrome-extension/manifest.json Version bump from 0.6.0 to 0.6.1; in sync with package.json.
specs/local-multiplexed-browser-mcp-spec.md FR-016 and FR-017 updated to precisely capture the new cleanup semantics; spec language now matches implementation.

Sequence Diagram

sequenceDiagram
    participant C as MCP Client
    participant I as daemon_ingress_server
    participant S as mcp_protocol_session
    participant R as session_registry

    C->>I: WebSocket connect
    I->>S: create session
    C->>I: initialize request
    I->>S: handle_line
    S-->>S: sets initialized_auth_mode
    S-->>I: on_agent_session_bound(session_id)
    I-->>I: bind agent_session_id to connection

    Note over I,R: 1st cleanup tick
    I->>R: run_stale_session_cleanup
    I->>I: unbind_connections_for_missing_sessions
    Note right of I: reset last_activity to now
    I->>I: close_stale_unbound_connections
    Note right of I: conn in skipped_ids, skip

    Note over I,S: 2nd cleanup tick
    I->>I: close_stale_unbound_connections
    I->>S: has_recoverable_initialized_state
    S-->>I: true, socket preserved
    C->>I: next tool call, implicit rebind
Loading

Reviews (1): Last reviewed commit: "fix(mcp): preserve recoverable stale tra..." | Re-trigger Greptile

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes daemon/proxy stale-connection cleanup so that initialized MCP transports remain usable (and can implicitly rebind) even after their session registry entry has been soft-reaped and later removed, while still reclaiming truly abandoned pre-initialize ingress sockets.

Changes:

  • Preserve unbound daemon ingress sockets during stale cleanup when the connection’s protocol session has recoverable initialized state.
  • Add/extend integration coverage for the preserved-vs-closed unbound socket behavior.
  • Bump local release/runtime version identifiers to 0.6.1 and update spec/docs/changelog accordingly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
local-mcp-bun/src/daemon_ingress_server.ts Skips stale unbound socket closure when the associated protocol session is initialized and recoverable.
local-mcp-bun/src/mcp_protocol_session.ts Adds a predicate for “recoverable initialized state” and bumps serverInfo.version to 0.6.1.
local-mcp-bun/tests/integration/daemon_ingress_cleanup.test.ts Extends coverage to ensure recoverable initialized sockets stay open, and adds a test ensuring non-initialized stale sockets still close.
specs/local-multiplexed-browser-mcp-spec.md Updates requirements language to reflect the recoverable initialized-state exception for unbound ingress cleanup.
specs/local-multiplexed-browser-mcp-changelog.md Records the behavioral change, verification commands, and version bump.
local-mcp-bun/README.md Clarifies cleanup semantics for initialized transports vs pre-initialize unbound socket leaks.
local-mcp-bun/package.json Version bump to 0.6.1.
local-mcp-bun/chrome-extension/manifest.json Extension version bump to 0.6.1.
local-mcp-bun/src/bridge_transport.ts Synthetic extension fixture version bump to 0.6.1.
agent-logs/2026-04-30T004933-0500-recoverable-stale-transport.md Adds supporting investigation/validation notes for the change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@KnotFalse KnotFalse merged commit 3396d8a into trunk Apr 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants