Commit Graph

1028 Commits

Author SHA1 Message Date
Claude 66a928547c docs: align the SSE notification-POST sentence with its streamable sibling
The SSE paragraph said "a notification"; the write loop also carries
response POSTs, exactly as the streamable sentence already states.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 06:57:18 +00:00
Claude d25e6f8bcb fix(client): export status_error_data in _transport's __all__
The module keeps an exhaustive export list; the helper is imported by
sse.py and streamable_http.py.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 06:46:30 +00:00
Claude af77621978 docs: scope the connect-failure escape note to request POSTs
The sentence claimed connect-level failures on any streamable HTTP
message POST still escape the transport context; that is only true for
a request's POST (spawned on the transport task group). A notification
or response POST runs inside post_writer's guarded loop: the failure is
logged, does not escape, and kills the write loop - pre-existing
behavior, now stated instead of implied away.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 06:38:26 +00:00
Claude 6472241329 fix(client): contain arbitrary POST failures and dedupe the status-error mapping
Address the third review round:

- Broaden the SSE message POST's failure catch to a terminal containment
  boundary (except Exception): user-supplied auth flows and hooks raise
  arbitrary types from inside client.post(), so an enumerated catch cannot
  keep the caller from hanging.
- Extract the status -> JSON-RPC error mapping into
  mcp.client._transport.status_error_data and use it from the message POST
  handler, the resumption GET, and the SSE POST; the message POST keeps its
  pre-session 404 -> METHOD_NOT_FOUND case locally. Wire-identical.
- Contain the SSE error-resolution send against a concurrently closed read
  stream (BrokenResourceError/ClosedResourceError -> debug log), mirroring
  _resolve_abandoned_request, so the teardown race cannot kill the write
  loop.

Tests: the auth-failure test is parametrized over OAuthTokenError and
RuntimeError, and a raw-stream teardown-race test pins that a failing
POST whose error is undeliverable leaves the write loop serving later
messages. Both fail against the previous revision.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 06:26:42 +00:00
Claude 51d99af614 fix(client): cover OAuth failures and 404 session expiry on the SSE POST; document the new error contract
Address the second review round:

- Widen the SSE message POST's failure catch to (httpx.HTTPError,
  OAuthFlowError): an OAuthClientProvider re-auth failing inside
  client.post() previously took the same swallowed path and hung the
  waiting caller forever.
- Map a 404 on the SSE message POST to INVALID_REQUEST / "Session
  terminated" when the endpoint URL carries a session id (the SSE
  analogue of the streamable transport's session check); keep the
  generic error when it does not.
- Document the changed error behavior in docs/migration.md: resumption
  GET and SSE message POST outcome tables, and scope the "connect-level
  failures still escape" sentence to the streamable message POST, the
  one place it still holds.

Three new regression tests; the OAuth and 404-session ones fail against
the previous revision.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 06:08:39 +00:00
Claude b4edbd4bb7 fix(client): harden the resumption GET and SSE POST error paths per review
Address the review findings on the previous revision:

- Dispatch resumption on message type as well as metadata: a notification
  stamped with a resumption token is POSTed as usual instead of tripping
  the resumption path's request-only assertion and killing the write loop.
- Treat any non-2xx as a failure (response.is_success), restoring the
  raise_for_status() semantics the checks replaced: an unfollowed redirect
  resolves the caller instead of being logged as success.
- Map a 404 on the resumption GET while a session id is held to
  INVALID_REQUEST / "Session terminated", the POST path's session-expiry
  signal, so reconnect logic keyed on it works across both.
- Contain the resumption read loop like _handle_sse_response: a stream
  dying mid-read or ending cleanly without a response resolves the waiter
  (CONNECTION_CLOSED) instead of tearing down the transport or hanging.
- Resolve the resumption GET's status errors via _resolve_abandoned_request
  for its closed-stream containment instead of hand-building the error.
- Surface network-level errors (httpx.HTTPError) on the SSE message POST
  through the same correlated path: on this transport nothing escapes
  loudly, so the caller previously hung forever.
- Deduplicate the SSE test app wiring behind make_app(wrap_post=...).

Seven new regression tests pin the above; each fails against the previous
revision (hang into fail_after, transport teardown, or wrong error).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 05:56:37 +00:00
Claude e5fe739c59 test: use one parenthesized async-with to dodge py3.14 coverage phantom arc
Separately nested async-with statements trip a phantom branch arc under
coverage on Python 3.14 (the artifact already noted in mcp.client.sse),
failing the 3.14 CI matrix legs at 99.99%. Collapse the two context
managers into a single parenthesized async-with, the form the sibling
streamable-http tests already use, instead of adding a pragma.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 05:35:35 +00:00
Claude 15b394c438 fix(client): surface HTTP errors on resumption GET and SSE message POST
Two client-side paths still swallowed non-2xx HTTP responses, leaving the
caller hanging with no way to tell an auth failure from a slow server
(#2110):

- streamable HTTP: a non-2xx on the resumption GET (Last-Event-ID) hit a
  bare raise_for_status() inside the request's background task; the
  escaping HTTPStatusError tore down the transport's task group and every
  stream with it.
- SSE transport: a non-2xx on the message POST raised into post_writer's
  catch-all, which logged and dropped it; the waiting caller hung forever
  and the write loop died.

Both paths now resolve the waiting request with a JSON-RPC error
correlated to its id, mirroring _handle_post_request's existing non-2xx
handling: the caller gets a prompt INTERNAL_ERROR and the
transport/session stays usable. A non-2xx on a notification POST has no
waiter to resolve, so it is logged and contained.

Regression tests drive both transports in-process (httpx MockTransport /
ASGI) at 401/403/500 and pin that the error is correlated, prompt, and
non-fatal to the session; all fail (hang into fail_after) without the
fix.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuJi8kEB3bhikW2pzbmhUL
2026-08-11 05:27:29 +00:00
Max a4f4ccd091 Link the released 2026-07-28 spec and point migrators at /v1/ (#3214) 2026-07-29 15:01:27 +01:00
Max fe47969fb9 Ask which release line a bug report is on (#3213) 2026-07-29 14:55:15 +01:00
Max d82ed88eb5 Describe the maintenance line without hardcoding 1.28 (#3212) 2026-07-29 14:54:45 +01:00
Max b31ddf37ed Retire wording tied to pre-2.0 milestones (#3211) 2026-07-29 14:54:23 +01:00
Max 6f69a3758e Present v2 as the stable release across the README, docs, and policies (#3178)
Conformance Tests / server-conformance (push) Has been cancelled
Conformance Tests / client-conformance (push) Has been cancelled
Deploy Docs / deploy-docs (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
CI / checks (push) Failing after 1s
CI / all-green (push) Has been cancelled
v2.0.0
2026-07-28 14:31:36 +01:00
Max 78e6fbb7e4 Serve v2 docs at the site root, with permanent per-major paths (#3176) 2026-07-28 13:57:21 +01:00
Max af06330a31 Remove unused StreamableHTTPTransport.get_session_id() (#3205) 2026-07-28 13:55:02 +01:00
Max 68ca87e20b Document the two-line release process for stable v2 (#3179) 2026-07-28 13:51:31 +01:00
Max c9c431b71a Expose the middleware chain on MCPServer and stop sending unrequested change notifications (#3201) 2026-07-28 12:24:23 +01:00
Max 528e366558 Fail fast on server-to-client requests in JSON-response mode instead of hanging (#3195) 2026-07-28 11:04:51 +01:00
Max 27f5cc7a46 Remove unused mcpserver.exceptions.ValidationError (#3199) 2026-07-28 10:25:51 +01:00
Max 89c5e700f2 Gate log notifications on the per-request log-level opt-in at 2026-07-28 (#3198) 2026-07-28 02:20:33 +01:00
Max b61ce388dd docs: fix off-by-one hl_lines in apps.md (#3196) 2026-07-28 00:04:57 +01:00
Max b7c9a916d6 Add mcp.types as a permanent alias for mcp_types (#3190) 2026-07-27 23:47:04 +01:00
Max 923341c98a Stop answering cancelled requests (#3188) 2026-07-27 23:26:00 +01:00
Max e8ef138153 docs: fill migration-guide gaps found by automated v1-to-v2 migration runs (#3187) 2026-07-27 23:17:17 +01:00
Max d3ffe87960 Split the registration request model from the registered-client record (#3181) 2026-07-27 23:11:01 +01:00
Max b9422f1c9b Make the per-version wire packages private (mcp_types._v*) (#3191) 2026-07-27 22:16:48 +01:00
Max 45f2a88a9a Point pre-release install pins at 2.0.0rc1 (#3186)
CI / checks (push) Failing after 1s
CI / all-green (push) Has been cancelled
v2.0.0rc1
2026-07-27 14:23:57 +01:00
Max 333aca7ac8 Repin conformance harness to the published 0.2.0-alpha.10 (#3184) 2026-07-27 14:03:06 +01:00
Max dcd9c1ee9f Lengthen the demo signing keys in the identity-assertion examples (#3180)
Conformance Tests / server-conformance (push) Has been cancelled
Conformance Tests / client-conformance (push) Has been cancelled
Deploy Docs / deploy-docs (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
CI / all-green (push) Has been cancelled
CI / checks (push) Failing after 0s
2026-07-26 11:45:26 +01:00
Jeremiah Lowin f599cdfcf9 Cache compiled output-schema validators on ClientSession (#3134)
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-07-26 11:29:10 +01:00
Max 11934c90ae Replace FileResource.is_binary with an encoding field (#3171) 2026-07-26 00:58:06 +01:00
Max 814072c94d Narrow message_handler's parameter to notifications and exceptions (#3168) 2026-07-26 00:24:48 +01:00
Max 47bfa85e83 Remove the unused timeout parameter from OAuthClientProvider (#3165) 2026-07-26 00:22:15 +01:00
Max 3212591946 Stop advertising MCP_* env vars for MCPServer settings; drop pydantic-settings (#3170) 2026-07-25 23:22:27 +01:00
Max 7163d8263f Remove the deprecated RFC7523OAuthClientProvider (#3169) 2026-07-25 22:50:57 +01:00
Max 1963af52cc Correct stable v2 target date to 2026-07-28 (#3105)
CI / checks (push) Failing after 0s
Deploy Docs / deploy-docs (push) Has been cancelled
Conformance Tests / server-conformance (push) Has been cancelled
Conformance Tests / client-conformance (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
CI / all-green (push) Has been cancelled
2026-07-25 20:36:08 +01:00
Max e90a66b554 Rename scopes= to scope= on the client-credentials OAuth providers (#3166) 2026-07-25 20:23:36 +01:00
Max 5dd062d077 Remove Context.client_id (#3167) 2026-07-25 19:11:51 +01:00
Max 0cb920f126 Make CacheConfig() the Client cache default and None the off switch (#3164) 2026-07-25 17:50:53 +01:00
Max 629ca297d2 Isolate the stdio server's stdin and stdout from handler subprocesses (#3117) 2026-07-25 13:05:51 +01:00
Max 00a70148bc Serve the 2026-07-28 protocol over stdio: decide the era from the opening request (#3152)
CI / checks (push) Failing after 1s
Deploy Docs / deploy-docs (push) Has been cancelled
Conformance Tests / server-conformance (push) Has been cancelled
Conformance Tests / client-conformance (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
CI / all-green (push) Has been cancelled
2026-07-24 13:46:37 +01:00
Max 837ef904f8 Align with spec #3002: optional clientInfo, serverInfo in result _meta (#3143)
Deploy Docs / deploy-docs (push) Has been cancelled
CI / checks (push) Failing after 24m23s
CI / all-green (push) Has been cancelled
Conformance Tests / server-conformance (push) Has been cancelled
Conformance Tests / client-conformance (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
2026-07-23 12:00:36 +01:00
Max 3a6f2996cd docs: load media examples from disk instead of inline base64 (#3108) 2026-07-16 20:41:05 +01:00
Max ebcc4dc3fb Pin pymdown-extensions back to 11.0 (#3106) 2026-07-16 20:25:33 +01:00
Max 497f7afa61 docs: make API reference rendering independent of page order (#3107) 2026-07-16 18:29:44 +01:00
Andre.Kalberer e464f72c12 docs: document Windows stdio subprocess stdin handling (#3079) 2026-07-16 11:25:47 +01:00
Marcelo Trylesinski 03aaebd3aa Add Streamable HTTP request body limits (#3095) 2026-07-16 08:33:32 +02:00
Marcelo Trylesinski 2713b53b12 Replace httpx and httpx-sse with httpx2 (#2972)
CI / checks (push) Failing after 1s
CI / all-green (push) Has been cancelled
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
v2.0.0b2
2026-07-14 17:05:08 +01:00
Otis Cui 1216c53693 fix: reject trailing newline in tool-name and URI-template varname validation (#3076)
Python's $ with re.match also matches just before a single trailing newline, so tool-name validation accepted "name\n" and UriTemplate.parse accepted varnames like "foo\n". Switch both checks to re.fullmatch.

Closes #3084
2026-07-10 12:56:54 +00:00
Marcelo Trylesinski 4fc8882c02 docs: replace MkDocs with Zensical (#3073)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
2026-07-10 12:48:46 +01:00