Skip to content

fix: don't close a shared MCP transport under in-flight sibling calls - #774

Open
bhaveshpatel640 wants to merge 4 commits into
mainfrom
AGE-2253
Open

bhaveshpatel640 wants to merge 4 commits into
mainfrom
AGE-2253

Conversation

@bhaveshpatel640

@bhaveshpatel640 bhaveshpatel640 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Session-expired MCP retry no longer closes the shared transport while a sibling callTool/listTools is still using it. That sibling used to fail with a non-retried close error.

AGE-2253 / INFOSEC-15 TF-06

Changes

  • Detach the stale socket (pendingClose) and close it when inflight hits 0
  • Skip reset if the expired handle is no longer the live connection

How was this tested?

pnpm --filter @truefoundry/trueforge-core test -- tests/core/mcp/remoteMcpServer.test.ts

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, python/trueforge_sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
Changes concurrent connection teardown and session-expiry retry in core remote MCP usage; behavior is narrow and covered by new tests, but mistakes could affect parallel tool calls or leak connections.

Overview
Fixes a race where session-expired retry on one concurrent callTool/listTools would close the shared remote MCP transport while another call still held it. That sibling then failed with "Connection closed", which is not treated as session-expired, so it was never retried.

RemoteMCP now tracks in-flight operations on a captured connection handle: on expiry it detaches the stale socket into pendingClose instead of closing immediately when siblings are active, reconnects and retries once, and closes the deferred socket only when inflight reaches zero. Stale expiry on an old handle no longer resets a newer live transport, and transport onClose only clears connected state when the closed socket is still the active one.

Tests simulate a held sibling call plus session expiry on a parallel call, including late expiry on the stale connection after retry.

Reviewed by Cursor Bugbot for commit 1dfd55c. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b57abe5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge-core Patch
@truefoundry/trueforge Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit faf9c05. Configure here.

Comment thread packages/trueforge-core/src/core/mcp/RemoteMCP.ts
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.

1 participant