feat: expand InitializationState with explicit lifecycle state machine#1
Open
feat: expand InitializationState with explicit lifecycle state machine#1
Conversation
…protocol#1663) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
* Auto-enable DNS rebinding protection for localhost servers When a FastMCP server is created with host="127.0.0.1" or "localhost" and no explicit transport_security is provided, automatically enable DNS rebinding protection. Both 127.0.0.1 and localhost are allowed as valid hosts/origins since clients may use either to connect. * Add tests for auto DNS rebinding protection on localhost Tests verify that: - Protection auto-enables for host=127.0.0.1 - Protection auto-enables for host=localhost - Both 127.0.0.1 and localhost are in allowed hosts/origins - Protection does NOT auto-enable for other hosts (e.g., 0.0.0.0) - Explicit transport_security settings are not overridden * Add IPv6 localhost (::1) support for DNS rebinding protection Extend auto-enable DNS rebinding protection to also cover IPv6 localhost. When host="::1", protection is now auto-enabled with appropriate allowed hosts ([::1]:*) and origins (http://[::1]:*). * Fix import ordering in test file
…modelcontextprotocol#1669) Co-authored-by: TheMailmans <tyler@example.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
…elcontextprotocol#1384) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com> Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
…delcontextprotocol#1755) Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: ARJUN-TS1 <arjun.ts1@ibm.com> Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
…d of `httpx_client_factory` (modelcontextprotocol#1177) Co-authored-by: Felix Weinberger <fweinberger@anthropic.com>
…otocol#1782) Signed-off-by: Ondrej Mosnáček <omosnacek@gmail.com>
…#1481) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
…col#1503) Co-authored-by: Paul Carleton <paulcarletonjr@gmail.com>
…textprotocol#1808) Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
…otocol#1651) Co-authored-by: Claude <noreply@anthropic.com>
…across 1 directory (modelcontextprotocol#2031) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
…ross 1 directory (modelcontextprotocol#2036) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
…delcontextprotocol#2038) Co-authored-by: Lee Hubbard <hubbard.zlee@unknowncyber.com> Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
Expand the InitializationState enum with new states (Stateless, Closing, Closed, Error) and add centralized transition validation via a _VALID_TRANSITIONS table and _transition_state() method. Key changes: - Add Stateless state for sessions that skip the initialization handshake - Add Closing/Closed states for orderly shutdown tracking - Add Error state for unrecoverable failures with recovery paths - Add _transition_state() method that validates transitions against a table - Add initialization_state property (read-only) and is_initialized property - Override __aexit__ to transition through Closing -> Closed on exit - Update _received_request and _received_notification to use new APIs - Add comprehensive test suite (20 tests) covering all state transitions Github-Issue: modelcontextprotocol#1691
d443932 to
cf1bbd2
Compare
…ition_state Github-Issue: modelcontextprotocol#1691
Add tests for __aexit__ when session is already in Closing or Closed state, covering the 'if' False branch and the second except RuntimeError. Mark the first except RuntimeError as pragma: no cover since it is unreachable under the current transition table (all non-terminal states can transition to Closing).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses #1691 — Phase 1: expand the
InitializationStateenum with an explicit lifecycle state machine and add centralized transition validation.Problem
The current
ServerSessionlifecycle management uses a simple three-state enum (NotInitialized,Initializing,Initialized) with direct state assignment. This makes it difficult to reason about session lifecycle, provides no protection against invalid transitions, and lacks visibility into shutdown states. Stateless sessions were handled by jumping directly toInitialized, conflating two conceptually different modes.Solution
Expanded
InitializationStateenumStateless— sessions that skip the initialization handshake (previously mapped toInitialized)Closing— session is shutting down, entered during__aexit__Closed— terminal state after shutdown completesError— unrecoverable failure, with recovery paths toClosing/ClosedCentralized transition validation
_VALID_TRANSITIONSdict — maps each state to its valid target states, documenting the state machine in one place_transition_state()method — validates transitions and raisesRuntimeErroron invalid ones, with debug loggingInitialized → Initializing) is explicitly allowed for backward compatibilityNew properties
initialization_state— read-only access to current stateis_initialized— returnsTruefor bothInitializedandStateless(replaces direct comparisons)__aexit__overrideClosing → Closedon session exitUpdated handlers
_received_requestand_received_notificationnow use_transition_state()instead of direct assignment_received_notificationguards against redundantInitializedNotificationin stateless modeTests
20 new tests in
tests/server/test_session_lifecycle.pycovering:Closedis terminal,Errorallows recovery)_transition_state()is_initializedproperty for all states__aexit__lifecycle transitionsAll 474 existing server tests pass with no regressions.