Skip to content

fix(mcp): clean failed servers before reconnecting - #3939

Open
jstar0 wants to merge 1 commit into
openai:mainfrom
jstar0:fix/mcp-reconnect-cleanup
Open

fix(mcp): clean failed servers before reconnecting#3939
jstar0 wants to merge 1 commit into
openai:mainfrom
jstar0:fix/mcp-reconnect-cleanup

Conversation

@jstar0

@jstar0 jstar0 commented Jul 24, 2026

Copy link
Copy Markdown

Summary

MCPServerManager.reconnect(failed_only=True) retries failed servers without
first cleaning resources that may have been opened before connect() failed.
For transports that require cleanup between attempts, the retry fails again or
runs against stale state.

This change keeps the released manager structure and existing sequential and
parallel ownership models. Failed servers are deduplicated, cleaned through the
existing cleanup path, and retried in their original order only when cleanup
succeeds. If cleanup fails or is cancelled, the server remains failed, the
cleanup error remains available in manager.errors, and no new connection is
attempted. Healthy servers are not cleaned or reconnected.

Test plan

  • Added sequential and parallel regressions for a server that opens a resource
    before its first connection failure and succeeds only after cleanup.
  • Added sequential and parallel regressions proving cleanup failure prevents a
    second connection attempt and preserves failed/error state.
  • Confirmed both regressions fail on unmodified main and pass with the fix.
  • Ran the complete MCP server manager test module.
  • Ran the focused regressions on Python 3.10.
  • Ran .agents/skills/code-change-verification/scripts/run.sh; format, lint,
    typecheck, and the complete test suite passed.

Issue number

N/A - found through code-path review; no existing issue or pull request covers
the failed-only reconnect cleanup path.

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass

Scope and risk

  • No public API, default, cancellation policy, or worker ownership changes.
  • Full reconnect and final cleanup behavior are unchanged.
  • The cleanup helper now returns the successfully cleaned subset; existing
    callers that perform rollback cleanup ignore that result and retain their
    previous behavior.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87d8d5c206

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 87d8d5c to 9ec0ad0 Compare July 24, 2026 10:13
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 9ec0ad0 to e0249ce Compare July 24, 2026 10:23

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0249ce902

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
@seratch
seratch marked this pull request as draft July 24, 2026 11:20
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from e0249ce to 37bf63c Compare July 24, 2026 12:04
@jstar0
jstar0 marked this pull request as ready for review July 24, 2026 12:07

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 37bf63cb18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch 2 times, most recently from baff106 to 47f0aae Compare July 24, 2026 17:55

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47f0aaee3e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
@seratch
seratch marked this pull request as draft July 24, 2026 21:54
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch 2 times, most recently from 90a14ed to ac7fb14 Compare July 25, 2026 23:27
@jstar0
jstar0 marked this pull request as ready for review July 25, 2026 23:28

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac7fb14702

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from ac7fb14 to a551db3 Compare July 26, 2026 00:30

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a551db374c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py
Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from a551db3 to 79e87fc Compare July 26, 2026 00:57

@seratch seratch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for iterating on this. The failed-only cleanup need is valid, and the current worker and cancellation changes address the earlier findings. One lifecycle blocker remains: connect_all(), reconnect(), and cleanup_all() can still mutate the same manager and worker state concurrently.

After two reconnects share cleanup, both can pass the connection check and enqueue a new connect for the same server. A cleanup_all() racing with reconnect() can likewise stop the replacement worker or allow reconnect to recreate one after final cleanup. The concurrent-cleanup test proves command deduplication, but not the surviving operation or final manager state.

Please serialize all three public lifecycle entry points with a manager-owned lock, use private unlocked helpers for internal composition, and add controlled regressions for concurrent reconnects and reconnect versus cleanup_all(). Assert one connect, deterministic active/failed state, and no worker surviving final cleanup. Once covered, this should be ready for another review.

@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 79e87fc to 1230746 Compare July 26, 2026 11:07
@jstar0

jstar0 commented Jul 26, 2026

Copy link
Copy Markdown
Author

Implemented in 12307469.

connect_all(), reconnect(), and cleanup_all() now share a manager-owned
lifecycle lock. Their existing bodies are private unlocked helpers so full
reconnect can compose cleanup without recursive locking. Final cleanup also
skips servers that no longer have a worker or connected marker, preserving
idempotence for queued cleanup callers.

The new sequential and parallel regressions cover concurrent failed-only
reconnects and reconnect queued before final cleanup. They assert one retry,
deterministic active/failed state, and no resource or worker surviving final
cleanup. The complete manager tests, repository verification, and the focused
Python 3.10 regressions pass on current main.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 123074697b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 1230746 to 15a98cf Compare July 26, 2026 12:17

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 15a98cfc5f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 15a98cf to a9a509f Compare July 26, 2026 13:42

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

servers_to_connect = self._servers_to_connect(self._all_servers)

P2 Badge Block connect_all after failed terminal cleanup

Fresh evidence in this revision: the new _blocked_reconnect_servers state is honored by failed-only and full reconnect, but connect_all() still rebuilds servers_to_connect from every disconnected server and clears errors without checking that block. After strict connect_all() rolls back a partial connect and terminal cleanup fails, a later connect_all() can call connect() again on the same server object even though its previous transport/session was never confirmed cleaned; route this path through the same failed-closed handling used by reconnect before retrying. .agents/references/local-mcp-server-lifecycle.mdL7-L11

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from a9a509f to 8cb2102 Compare July 26, 2026 15:50

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8cb21021d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/manager.py Outdated
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 8cb2102 to 3828517 Compare July 27, 2026 10:30

@seratch seratch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for addressing the previous lifecycle feedback. Re-reviewing the complete diff from v0.19.0, the original failed-only reconnect bug is valid, but this PR has expanded into a broader lifecycle redesign: default sequential mode now uses dedicated workers, all public lifecycle calls are serialized, and cleanup failures introduce terminal blocked state and new cancellation semantics.

Please reset this to the released manager structure and keep the fix focused: clean the deduplicated failed servers before reconnect(failed_only=True), retry only servers whose cleanup succeeds, preserve healthy servers and the existing sequential/parallel ownership model, and treat cleanup failure as terminal for that server without another connect attempt. Please retain focused regressions for successful partial-failure recovery and cleanup-failure no-retry in both modes.

Cross-caller sequential lifecycle, concurrent lifecycle operations, and cleanup-failure recovery should be handled separately if concrete need is established.

Signed-off-by: King Star <mcxin.y@gmail.com>
@jstar0
jstar0 force-pushed the fix/mcp-reconnect-cleanup branch from 3828517 to e906a57 Compare July 29, 2026 18:31
@jstar0

jstar0 commented Jul 29, 2026

Copy link
Copy Markdown
Author

Thanks for the clear scope direction. I reset the branch to the v0.19.1 manager
structure and removed the lifecycle lock, default-worker conversion, blocked
state, and cancellation changes.

The remaining fix is limited to reconnect(failed_only=True): it deduplicates
failed servers, cleans them through the existing sequential or parallel
ownership path, and retries only successful cleanups in original order. Cleanup
failure leaves the server failed with the cleanup error and makes no new connect
attempt. Healthy servers are untouched.

The new sequential and parallel regressions cover successful partial-failure
recovery and cleanup-failure no-retry behavior. The complete manager tests and
the repository format, lint, typecheck, and full test workflow pass on current
main.

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