Conversation
There was a problem hiding this comment.
2 issues found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="docs/client/session-groups.md">
<violation number="1" location="docs/client/session-groups.md:83">
P2: Copying this example raises `NameError` for `client_metadata`, `token_storage`, `redirect_handler`, and `callback_handler`; define these values or link a complete runnable OAuth example.</violation>
<violation number="2" location="docs/client/session-groups.md:98">
P2: When the same auth object is assigned to two parameter instances, `ClientSessionGroup` shares its mutable OAuth context and tokens. Tell users to construct a distinct auth instance per server before claiming these lifecycles are independent.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
|
||
| server_auth = OAuthClientProvider( | ||
| server_url="https://api.example.com", | ||
| client_metadata=client_metadata, |
There was a problem hiding this comment.
P2: Copying this example raises NameError for client_metadata, token_storage, redirect_handler, and callback_handler; define these values or link a complete runnable OAuth example.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/client/session-groups.md, line 83:
<comment>Copying this example raises `NameError` for `client_metadata`, `token_storage`, `redirect_handler`, and `callback_handler`; define these values or link a complete runnable OAuth example.</comment>
<file context>
@@ -70,6 +70,33 @@ If you already hold a connected `ClientSession` (`Client.session` is one), hand
+
+server_auth = OAuthClientProvider(
+ server_url="https://api.example.com",
+ client_metadata=client_metadata,
+ storage=token_storage,
+ redirect_handler=redirect_handler,
</file context>
| await group.connect_to_server(server_params) | ||
| ``` | ||
|
|
||
| Because `auth` is configured per `ServerParameters` instance, each server in the session group maintains independent authentication context, scopes, and token-refresh lifecycle. Custom headers can still be supplied alongside `auth` via `headers=`. |
There was a problem hiding this comment.
P2: When the same auth object is assigned to two parameter instances, ClientSessionGroup shares its mutable OAuth context and tokens. Tell users to construct a distinct auth instance per server before claiming these lifecycles are independent.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/client/session-groups.md, line 98:
<comment>When the same auth object is assigned to two parameter instances, `ClientSessionGroup` shares its mutable OAuth context and tokens. Tell users to construct a distinct auth instance per server before claiming these lifecycles are independent.</comment>
<file context>
@@ -70,6 +70,33 @@ If you already hold a connected `ClientSession` (`Client.session` is one), hand
+ await group.connect_to_server(server_params)
+```
+
+Because `auth` is configured per `ServerParameters` instance, each server in the session group maintains independent authentication context, scopes, and token-refresh lifecycle. Custom headers can still be supplied alongside `auth` via `headers=`.
+
## Recap
</file context>
| Because `auth` is configured per `ServerParameters` instance, each server in the session group maintains independent authentication context, scopes, and token-refresh lifecycle. Custom headers can still be supplied alongside `auth` via `headers=`. | |
| Because `auth` is configured per `ServerParameters` instance, give each server a distinct auth instance to maintain independent authentication context, scopes, and token-refresh lifecycle. Custom headers can still be supplied alongside `auth` via `headers=`. |
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="docs/client/session-groups.md">
<violation number="1" location="docs/client/session-groups.md:82">
P2: The new `main()` is never invoked, so copying this authentication example only defines the function and never connects to the server. Add an async runner such as `asyncio.run(main())` and its import.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| from mcp.client.session_group import ClientSessionGroup, StreamableHttpParameters | ||
|
|
||
|
|
||
| async def main() -> None: |
There was a problem hiding this comment.
P2: The new main() is never invoked, so copying this authentication example only defines the function and never connects to the server. Add an async runner such as asyncio.run(main()) and its import.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/client/session-groups.md, line 82:
<comment>The new `main()` is never invoked, so copying this authentication example only defines the function and never connects to the server. Add an async runner such as `asyncio.run(main())` and its import.</comment>
<file context>
@@ -78,21 +78,23 @@ When connecting to HTTP servers using `StreamableHttpParameters` or `SseServerPa
-async with ClientSessionGroup() as group:
- await group.connect_to_server(server_params)
+
+async def main() -> None:
+ server_auth = OAuthClientProvider(
+ server_url="https://api.example.com",
</file context>
Closes #1723
Summary
ClientSessionGroupserver parameters (SseServerParametersandStreamableHttpParameters) lacked anauthfield, requiring users to manually manage bearer tokens via theheadersparameter and preventing automated OAuth flows (likeOAuthClientProvider) with dynamic client registration and token refresh.This change adds an optional
auth: httpx2.Auth | None = Noneparameter to both HTTP server parameter models and propagates it intosse_client()andcreate_mcp_http_client().Changes
auth: httpx2.Auth | None = Field(default=None, description="Optional HTTPX authentication handler.", exclude=True)toSseServerParametersandStreamableHttpParameters.ConfigDict(arbitrary_types_allowed=True)to both parameter models.authtosse_client()andcreate_mcp_http_client()withinClientSessionGroup._establish_session().tests/client/test_session_group.pyverifying:authis passed tosse_client()in SSE transport.authis passed tocreate_mcp_http_client()in Streamable HTTP transport.model_dump,model_dump_json) safely excludesauth.docs/client/session-groups.mdwith an authentication usage guide and example.Backward Compatibility
100% backward compatible:
authdefaults toNone.headersconfigurations remain fully supported.StdioServerParametersis unaffected.Test Plan
uv run --frozen pytest tests/client/test_session_group.py(17 passed, 100% coverage onsession_group.py).uv run --frozen pytest tests/client/(778 passed, 0 regressions).uv run --frozen pyright src/mcp/client/session_group.py tests/client/test_session_group.py(0 errors).uv run --frozen ruff check .anduv run --frozen ruff format --check .(passed).