From 4f36581a5cae4a46aaba3514cddc29de8867c473 Mon Sep 17 00:00:00 2001 From: TerminalMan <84923604+SecretiveShell@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:41:30 +0000 Subject: [PATCH 1/8] add text encoding params to STDIO client --- src/mcp/client/stdio.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/mcp/client/stdio.py b/src/mcp/client/stdio.py index e79a816..e894ae9 100644 --- a/src/mcp/client/stdio.py +++ b/src/mcp/client/stdio.py @@ -1,6 +1,7 @@ import os import sys from contextlib import asynccontextmanager +from typing import Literal import anyio import anyio.lowlevel @@ -65,6 +66,20 @@ class StdioServerParameters(BaseModel): If not specified, the result of get_default_environment() will be used. """ + encoding: str = "utf-8" + """ + The text encoding used when sending/receiving messages to the server + + defaults to utf-8 + """ + + encoding_error_handler: Literal["strict", "ignore", "replace"] = "strict" + """ + The text encoding error handler. + + See https://docs.python.org/3/library/codecs.html#codec-base-classes for explanations of possible values + """ + @asynccontextmanager async def stdio_client(server: StdioServerParameters): @@ -93,7 +108,7 @@ async def stdio_client(server: StdioServerParameters): try: async with read_stream_writer: buffer = "" - async for chunk in TextReceiveStream(process.stdout): + async for chunk in TextReceiveStream(process.stdout, encoding=server.encoding, errors=server.encoding_error_handler): lines = (buffer + chunk).split("\n") buffer = lines.pop() @@ -115,7 +130,7 @@ async def stdio_client(server: StdioServerParameters): async with write_stream_reader: async for message in write_stream_reader: json = message.model_dump_json(by_alias=True, exclude_none=True) - await process.stdin.send((json + "\n").encode()) + await process.stdin.send((json + "\n").encode(encoding=server.encoding, errors=server.encoding_error_handler)) except anyio.ClosedResourceError: await anyio.lowlevel.checkpoint() From 99727a97ae476a26fbac8fcf202a68e525100519 Mon Sep 17 00:00:00 2001 From: TerminalMan <84923604+SecretiveShell@users.noreply.github.com> Date: Sun, 29 Dec 2024 17:08:09 +0000 Subject: [PATCH 2/8] ruff format --- src/mcp/client/stdio.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mcp/client/stdio.py b/src/mcp/client/stdio.py index e894ae9..2eaa347 100644 --- a/src/mcp/client/stdio.py +++ b/src/mcp/client/stdio.py @@ -77,7 +77,8 @@ class StdioServerParameters(BaseModel): """ The text encoding error handler. - See https://docs.python.org/3/library/codecs.html#codec-base-classes for explanations of possible values + See https://docs.python.org/3/library/codecs.html#codec-base-classes for + explanations of possible values """ @@ -108,7 +109,11 @@ async def stdio_client(server: StdioServerParameters): try: async with read_stream_writer: buffer = "" - async for chunk in TextReceiveStream(process.stdout, encoding=server.encoding, errors=server.encoding_error_handler): + async for chunk in TextReceiveStream( + process.stdout, + encoding=server.encoding, + errors=server.encoding_error_handler, + ): lines = (buffer + chunk).split("\n") buffer = lines.pop() @@ -130,7 +135,12 @@ async def stdio_client(server: StdioServerParameters): async with write_stream_reader: async for message in write_stream_reader: json = message.model_dump_json(by_alias=True, exclude_none=True) - await process.stdin.send((json + "\n").encode(encoding=server.encoding, errors=server.encoding_error_handler)) + await process.stdin.send( + (json + "\n").encode( + encoding=server.encoding, + errors=server.encoding_error_handler, + ) + ) except anyio.ClosedResourceError: await anyio.lowlevel.checkpoint() From 937c640f04d9bc74bc3b75419c7a93e22ee0719b Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Thu, 5 Dec 2024 10:30:01 +0530 Subject: [PATCH 3/8] feat: add version string parameter to 'create_initialization_options' --- README.md | 9 +-------- src/mcp/server/__init__.py | 3 ++- src/mcp/server/sse.py | 3 ++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4ef08cf..20fd03e 100644 --- a/README.md +++ b/README.md @@ -135,14 +135,7 @@ async def run(): await server.run( read_stream, write_stream, - InitializationOptions( - server_name="example", - server_version="0.1.0", - capabilities=server.get_capabilities( - notification_options=NotificationOptions(), - experimental_capabilities={}, - ) - ) + server.create_initialization_options("0.1.0") ) if __name__ == "__main__": diff --git a/src/mcp/server/__init__.py b/src/mcp/server/__init__.py index a0dd033..212f011 100644 --- a/src/mcp/server/__init__.py +++ b/src/mcp/server/__init__.py @@ -114,6 +114,7 @@ class Server: def create_initialization_options( self, + version: str | None = None, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, ) -> InitializationOptions: @@ -133,7 +134,7 @@ class Server: return InitializationOptions( server_name=self.name, - server_version=pkg_version("mcp"), + server_version=version if version else pkg_version("mcp"), capabilities=self.get_capabilities( notification_options or NotificationOptions(), experimental_capabilities or {}, diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py index 3062b32..765c0eb 100644 --- a/src/mcp/server/sse.py +++ b/src/mcp/server/sse.py @@ -19,8 +19,9 @@ Example usage: async with sse.connect_sse( request.scope, request.receive, request._send ) as streams: + # Pass user visible version string, egs. 0.1.0 await app.run( - streams[0], streams[1], app.create_initialization_options() + streams[0], streams[1], app.create_initialization_options("0.1.0") ) async def handle_messages(request): From 6f108f7f7c0bc151a1c8a0c1d2830834f8231ac2 Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:27:58 +0530 Subject: [PATCH 4/8] doc: added comment to README example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20fd03e..87eb245 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ async def run(): await server.run( read_stream, write_stream, - server.create_initialization_options("0.1.0") + server.create_initialization_options("0.1.0") # user visible version number ) if __name__ == "__main__": From 34a257147bb7375846ea2ecb02afd355605e7ec4 Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:51:36 +0530 Subject: [PATCH 5/8] chore: revert doc changes --- README.md | 9 ++++++++- src/mcp/server/sse.py | 3 +-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 87eb245..4ef08cf 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,14 @@ async def run(): await server.run( read_stream, write_stream, - server.create_initialization_options("0.1.0") # user visible version number + InitializationOptions( + server_name="example", + server_version="0.1.0", + capabilities=server.get_capabilities( + notification_options=NotificationOptions(), + experimental_capabilities={}, + ) + ) ) if __name__ == "__main__": diff --git a/src/mcp/server/sse.py b/src/mcp/server/sse.py index 765c0eb..3062b32 100644 --- a/src/mcp/server/sse.py +++ b/src/mcp/server/sse.py @@ -19,9 +19,8 @@ Example usage: async with sse.connect_sse( request.scope, request.receive, request._send ) as streams: - # Pass user visible version string, egs. 0.1.0 await app.run( - streams[0], streams[1], app.create_initialization_options("0.1.0") + streams[0], streams[1], app.create_initialization_options() ) async def handle_messages(request): From 3de4dc1f13fc4800a8bd4f3e6a52f0d4219f30d0 Mon Sep 17 00:00:00 2001 From: restlessronin <88921269+restlessronin@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:54:52 +0530 Subject: [PATCH 6/8] feat: add version string parameter to Server constructor --- src/mcp/server/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mcp/server/__init__.py b/src/mcp/server/__init__.py index 212f011..4c5dc04 100644 --- a/src/mcp/server/__init__.py +++ b/src/mcp/server/__init__.py @@ -101,8 +101,9 @@ class NotificationOptions: class Server: - def __init__(self, name: str): + def __init__(self, name: str, version: str | None = None): self.name = name + self.version = version self.request_handlers: dict[ type, Callable[..., Awaitable[types.ServerResult]] ] = { @@ -114,7 +115,6 @@ class Server: def create_initialization_options( self, - version: str | None = None, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, ) -> InitializationOptions: @@ -134,7 +134,7 @@ class Server: return InitializationOptions( server_name=self.name, - server_version=version if version else pkg_version("mcp"), + server_version=self.version if self.version else pkg_version("mcp"), capabilities=self.get_capabilities( notification_options or NotificationOptions(), experimental_capabilities or {}, From b89cabc7df5dfa48f893775a07872729532201b5 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 2 Jan 2025 09:30:18 +0000 Subject: [PATCH 7/8] fix: Add constructor for McpError to allow setting field Backport of #116 by @allenporter to v1.1.x branch. Fixes an issue where exception handling code fails with AttributeError when accessing the error field of McpError. --- src/mcp/shared/exceptions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mcp/shared/exceptions.py b/src/mcp/shared/exceptions.py index d8855b8..97a1c09 100644 --- a/src/mcp/shared/exceptions.py +++ b/src/mcp/shared/exceptions.py @@ -7,3 +7,8 @@ class McpError(Exception): """ error: ErrorData + + def __init__(self, error: ErrorData): + """Initialize McpError.""" + super().__init__(error.message) + self.error = error From d06b393cdbfc8c18109dceb0eec358b44f415900 Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Fri, 3 Jan 2025 15:45:57 +0000 Subject: [PATCH 8/8] build: bump version to v1.1.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1e46ae0..45c691e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "mcp" -version = "1.1.2" +version = "1.1.3" description = "Model Context Protocol SDK" readme = "README.md" requires-python = ">=3.10"