Skip to content

fweinberger/align shutdown with spec #1091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 9, 2025

Conversation

felixweinberger
Copy link
Contributor

@felixweinberger felixweinberger commented Jul 4, 2025

Motivation and Context

This PR implements the MCP spec-compliant stdio shutdown sequence as defined in the MCP specification.

The MCP specification recommends that stdio transport clients should:

  1. Close the input stream to the server process
  2. Wait for the server to exit
  3. Send SIGTERM if the server doesn't exit quickly
  4. Send SIGKILL if the server doesn't exit after SIGTERM

This approach gives well-behaved servers the opportunity to detect stdin closure and perform clean shutdown without forceful termination, minimizing the risk of data loss or corruption while ensuring cleanup always completes.

Resolves #765

How Has This Been Tested?

  • All existing stdio tests pass
  • Added new tests:
    • test_stdio_client_graceful_stdin_exit: Verifies processes that monitor stdin exit gracefully
    • test_stdio_client_stdin_close_ignored: Verifies escalation to SIGTERM when stdin closure is ignored
  • Tested on both POSIX and Windows platforms

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the MCP Documentation
  • My code follows the code style of this repository
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added appropriate error handling

Implementation Details

The shutdown sequence now follows a graceful escalation path:

  1. Close stdin and wait 2 seconds for voluntary exit
  2. If the process hasn't exited, call the platform-specific _terminate_process_tree which handles:
    • SIGTERM with 2-second timeout
    • SIGKILL as final resort

This unified approach works consistently across all platforms and improves compatibility with MCP servers that monitor stdin for lifecycle management.

The implementation leverages the existing platform-specific process termination utilities introduced in PRs #1044 and #1078, ensuring robust child process cleanup on both Windows (using Job Objects) and POSIX systems (using process groups).

Co-authored-by: davenpi [email protected]

@felixweinberger felixweinberger force-pushed the fweinberger/align-shutdown-with-spec branch 2 times, most recently from 3ba87ad to 9f4696d Compare July 8, 2025 16:00
The MCP specification recommends closing stdin first to allow servers
to exit gracefully before resorting to signals. This approach gives
well-behaved servers the opportunity to detect stdin closure and
perform clean shutdown without forceful termination.

The shutdown sequence now follows a graceful escalation path: first
closing stdin and waiting 2 seconds for voluntary exit, then sending
SIGTERM if needed, and finally using SIGKILL as a last resort. This
minimizes the risk of data loss or corruption while ensuring cleanup
always completes.

This unified approach works consistently across all platforms and
improves compatibility with MCP servers that monitor stdin for
lifecycle management.

resolves #765

Co-authored-by: davenpi <[email protected]>
@felixweinberger felixweinberger force-pushed the fweinberger/align-shutdown-with-spec branch from 9f4696d to 757d154 Compare July 8, 2025 16:26
@felixweinberger felixweinberger marked this pull request as ready for review July 8, 2025 16:36
@felixweinberger felixweinberger requested a review from dsp-ant July 8, 2025 16:36
@felixweinberger
Copy link
Contributor Author

@dsp-ant rework of this change we discussed offline.

felixweinberger added a commit that referenced this pull request Jul 8, 2025
This test shows that MCP server cleanup code in lifespan doesn't run
when the process is terminated, but does run when stdin is closed first
(as implemented in PR #1044).

The test includes:
- Demonstration of current broken behavior (cleanup doesn't run)
- Verification that stdin closure allows graceful shutdown
- Windows-specific ResourceWarning handling
- Detailed documentation of the issue and solution

Github-Issue:#1027
felixweinberger added a commit that referenced this pull request Jul 8, 2025
This test shows that MCP server cleanup code in lifespan doesn't run
when the process is terminated, but does run when stdin is closed first
(as implemented in PR #1044).

The test includes:
- Demonstration of current broken behavior (cleanup doesn't run)
- Verification that stdin closure allows graceful shutdown
- Windows-specific ResourceWarning handling
- Detailed documentation of the issue and solution

Github-Issue:#1027
felixweinberger added a commit that referenced this pull request Jul 8, 2025
This test shows that MCP server cleanup code in lifespan doesn't run
when the process is terminated, but does run when stdin is closed first
(as implemented in PR #1044).

The test includes:
- Demonstration of current broken behavior (cleanup doesn't run)
- Verification that stdin closure allows graceful shutdown
- Windows-specific ResourceWarning handling
- Detailed documentation of the issue and solution

Github-Issue:#1027
Copy link
Contributor

@bhosmer-ant bhosmer-ant left a comment

Choose a reason for hiding this comment

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

LGTM

@bhosmer-ant bhosmer-ant merged commit 3abefee into main Jul 9, 2025
13 checks passed
@bhosmer-ant bhosmer-ant deleted the fweinberger/align-shutdown-with-spec branch July 9, 2025 14:14
saqadri pushed a commit to saqadri/stdio-fixes that referenced this pull request Aug 6, 2025
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