-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Bump mcp and other dependencies for Dependabot alerts
#4047
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
Changes from 9 commits
7833b96
782a995
e8d0496
634d5eb
4e00834
99fa07d
94bc306
840099e
0194063
023a518
8922929
b53d48c
e706269
0885571
e832160
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -127,6 +127,7 @@ async def sampling_callback( | |
| annotations=None, | ||
| meta=None, | ||
| ), | ||
| meta=None, | ||
| ) | ||
| ] | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,13 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import base64 | ||
| import functools | ||
| import os | ||
| import re | ||
| import warnings | ||
| from abc import ABC, abstractmethod | ||
| from asyncio import Lock | ||
| from collections.abc import AsyncIterator, Awaitable, Callable, Sequence | ||
| from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager | ||
| from contextlib import AsyncExitStack, asynccontextmanager | ||
| from dataclasses import dataclass, field, replace | ||
| from datetime import timedelta | ||
| from pathlib import Path | ||
|
|
@@ -32,7 +31,7 @@ | |
| from mcp.client.session import ClientSession, ElicitationFnT, LoggingFnT | ||
| from mcp.client.sse import sse_client | ||
| from mcp.client.stdio import StdioServerParameters, stdio_client | ||
| from mcp.client.streamable_http import GetSessionIdCallback, streamablehttp_client | ||
| from mcp.client.streamable_http import streamable_http_client | ||
| from mcp.shared import exceptions as mcp_exceptions | ||
| from mcp.shared.context import RequestContext | ||
| from mcp.shared.message import SessionMessage | ||
|
|
@@ -1113,67 +1112,6 @@ def __init__( | |
| client_info=client_info, | ||
| ) | ||
|
|
||
| @property | ||
| @abstractmethod | ||
| def _transport_client( | ||
| self, | ||
| ) -> Callable[ | ||
| ..., | ||
| AbstractAsyncContextManager[ | ||
| tuple[ | ||
| MemoryObjectReceiveStream[SessionMessage | Exception], | ||
| MemoryObjectSendStream[SessionMessage], | ||
| GetSessionIdCallback, | ||
| ], | ||
| ] | ||
| | AbstractAsyncContextManager[ | ||
| tuple[ | ||
| MemoryObjectReceiveStream[SessionMessage | Exception], | ||
| MemoryObjectSendStream[SessionMessage], | ||
| ] | ||
| ], | ||
| ]: ... | ||
|
|
||
| @asynccontextmanager | ||
| async def client_streams( | ||
| self, | ||
| ) -> AsyncIterator[ | ||
| tuple[ | ||
| MemoryObjectReceiveStream[SessionMessage | Exception], | ||
| MemoryObjectSendStream[SessionMessage], | ||
| ] | ||
| ]: | ||
| if self.http_client and self.headers: | ||
| raise ValueError('`http_client` is mutually exclusive with `headers`.') # pragma: no cover | ||
|
|
||
| transport_client_partial = functools.partial( | ||
| self._transport_client, | ||
| url=self.url, | ||
| timeout=self.timeout, | ||
| sse_read_timeout=self.read_timeout, | ||
| ) | ||
|
|
||
| if self.http_client is not None: | ||
| # TODO: Clean up once https://github.com/modelcontextprotocol/python-sdk/pull/1177 lands. | ||
| @asynccontextmanager | ||
| async def httpx_client_factory( | ||
| headers: dict[str, str] | None = None, | ||
| timeout: httpx.Timeout | None = None, | ||
| auth: httpx.Auth | None = None, | ||
| ) -> AsyncIterator[httpx.AsyncClient]: | ||
| assert self.http_client is not None | ||
| yield self.http_client | ||
|
|
||
| async with transport_client_partial(httpx_client_factory=httpx_client_factory) as ( | ||
| read_stream, | ||
| write_stream, | ||
| *_, | ||
| ): | ||
| yield read_stream, write_stream | ||
| else: | ||
| async with transport_client_partial(headers=self.headers) as (read_stream, write_stream, *_): | ||
| yield read_stream, write_stream | ||
|
|
||
| def __repr__(self) -> str: # pragma: no cover | ||
| repr_args = [ | ||
| f'url={self.url!r}', | ||
|
|
@@ -1217,9 +1155,45 @@ def __get_pydantic_core_schema__(cls, _: Any, __: Any) -> CoreSchema: | |
| ), | ||
| ) | ||
|
|
||
| @property | ||
| def _transport_client(self): | ||
| return sse_client # pragma: no cover | ||
| # sse_client has a hang bug (https://github.com/modelcontextprotocol/python-sdk/issues/1811). | ||
| # Remove pragma once https://github.com/modelcontextprotocol/python-sdk/pull/1838 is released. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not obvious why a hang bug results in a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. precisely
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove pragma "and add a test", right? Also worth marking as "TODO:" |
||
| @asynccontextmanager | ||
| async def client_streams( # pragma: no cover | ||
| self, | ||
| ) -> AsyncIterator[ | ||
| tuple[ | ||
| MemoryObjectReceiveStream[SessionMessage | Exception], | ||
| MemoryObjectSendStream[SessionMessage], | ||
| ] | ||
| ]: | ||
| if self.http_client and self.headers: | ||
| raise ValueError('`http_client` is mutually exclusive with `headers`.') | ||
|
|
||
| if self.http_client is not None: | ||
|
|
||
| def httpx_client_factory( | ||
| headers: dict[str, str] | None = None, | ||
| timeout: httpx.Timeout | None = None, | ||
| auth: httpx.Auth | None = None, | ||
| ) -> httpx.AsyncClient: | ||
| assert self.http_client is not None | ||
| return self.http_client | ||
|
|
||
| async with sse_client( | ||
| url=self.url, | ||
| timeout=self.timeout, | ||
| sse_read_timeout=self.read_timeout, | ||
| httpx_client_factory=httpx_client_factory, | ||
| ) as (read_stream, write_stream, *_): | ||
| yield read_stream, write_stream | ||
| else: | ||
| async with sse_client( | ||
| url=self.url, | ||
| timeout=self.timeout, | ||
| sse_read_timeout=self.read_timeout, | ||
| headers=self.headers, | ||
| ) as (read_stream, write_stream, *_): | ||
| yield read_stream, write_stream | ||
|
|
||
| def __eq__(self, value: object, /) -> bool: | ||
| return super().__eq__(value) and isinstance(value, MCPServerSSE) and self.url == value.url | ||
|
|
@@ -1281,9 +1255,27 @@ def __get_pydantic_core_schema__(cls, _: Any, __: Any) -> CoreSchema: | |
| ), | ||
| ) | ||
|
|
||
| @property | ||
| def _transport_client(self): | ||
| return streamablehttp_client | ||
| @asynccontextmanager | ||
| async def client_streams( | ||
| self, | ||
| ) -> AsyncIterator[ | ||
| tuple[ | ||
| MemoryObjectReceiveStream[SessionMessage | Exception], | ||
| MemoryObjectSendStream[SessionMessage], | ||
| ] | ||
| ]: | ||
| aexit_stack = AsyncExitStack() | ||
| http_client = self.http_client or await aexit_stack.enter_async_context( | ||
| httpx.AsyncClient(timeout=httpx.Timeout(self.timeout, read=self.read_timeout), headers=self.headers) | ||
|
dsfaccini marked this conversation as resolved.
|
||
| ) | ||
| read_stream, write_stream, *_ = await aexit_stack.enter_async_context( | ||
| streamable_http_client(self.url, http_client=http_client) | ||
| ) | ||
| try: | ||
| yield read_stream, write_stream | ||
| finally: | ||
| # unwrap the aexit | ||
|
dsfaccini marked this conversation as resolved.
Outdated
|
||
| await aexit_stack.aclose() | ||
|
|
||
| def __eq__(self, value: object, /) -> bool: | ||
| return super().__eq__(value) and isinstance(value, MCPServerStreamableHTTP) and self.url == value.url | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the new types we could support here and below? Add a comment at lease please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the painful stuff is that
content: SamplingMessageContentBlock | list[SamplingMessageContentBlock]but I've moved the
NotImplementedErrorinto an explicit branch checking all rest-types and added anassert_neverat the endThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AudioContenteasily in theImageContentbranch above?map_from_sampling_content) but relatively easily could be, vs anything that is fundamentally unsupported. Just so people know what their options are when they hit this error (e.g. contribute a fix)