From a0c795dd1fb446a274e82c0d6abfd69c0059deca Mon Sep 17 00:00:00 2001 From: Max Isbey <224885523+maxisbey@users.noreply.github.com> Date: Sun, 16 Aug 2026 12:35:51 +0000 Subject: [PATCH 1/3] docs: clarify client URL example wording in README The sentence pointed at a localhost URL and called it a "remote server", which reads oddly since nothing earlier in the README starts a server on that port. Present the URL as an example and describe what actually changes: the same client code talks to a server over HTTP. Closes #3313 No-Verification-Needed: doc-only wording change in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1850141b67..2f6774ef36 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ async def main() -> None: asyncio.run(main()) ``` -Swap `mcp` for `"http://localhost:8000/mcp"` and the exact same code talks to a remote server. +Swap `mcp` for a URL like `"http://localhost:8000/mcp"` and the exact same code talks to a server over HTTP. ## Contributing From d64e623ad94ca0c8dbd3d1599eb336d2e92a5d85 Mon Sep 17 00:00:00 2001 From: Max Isbey <224885523+maxisbey@users.noreply.github.com> Date: Sun, 16 Aug 2026 13:03:44 +0000 Subject: [PATCH 2/3] docs: lead the README client example with a URL, not the server object The "client in 10 lines" example imported the server object and connected to it in-process, then offered a URL as the variation. In-process is a testing technique, so this inverts it: serve the file you just wrote with `mcp run server.py --transport streamable-http`, connect to it by URL, and mention stdio and the in-memory test path in the closing sentence. Also fix the `mcp run --transport` help text, which still said "stdio or sse" although streamable-http is accepted and is what the README now uses. Closes #3313 --- README.md | 14 +++++++++----- src/mcp/cli/cli.py | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2f6774ef36..48610d94d2 100644 --- a/README.md +++ b/README.md @@ -86,18 +86,22 @@ Notice what you did **not** write: no JSON Schema (`a: int, b: int` _is_ the sch ## A client in 10 lines -The same package is a full MCP **client**. `Client` connects to a URL, a stdio subprocess, a custom transport, or (for tests) straight to a server object in memory with no transport at all: +The same package is a full MCP **client**. Serve `server.py` over HTTP: + +```bash +uv run mcp run server.py --transport streamable-http +``` + +then point a `Client` at it: ```python import asyncio from mcp import Client -from server import mcp - async def main() -> None: - async with Client(mcp) as client: + async with Client("http://localhost:8000/mcp") as client: result = await client.call_tool("add", {"a": 1, "b": 2}) print(result.structured_content) # {'result': 3} @@ -105,7 +109,7 @@ async def main() -> None: asyncio.run(main()) ``` -Swap `mcp` for a URL like `"http://localhost:8000/mcp"` and the exact same code talks to a server over HTTP. +A URL means Streamable HTTP, the transport you deploy. `Client` can also launch a local server as a stdio subprocess or take any custom transport, and in tests you hand it the server object itself (`Client(mcp)`): no process, no port. [Clients](https://py.sdk.modelcontextprotocol.io/client/) has the rest. ## Contributing diff --git a/src/mcp/cli/cli.py b/src/mcp/cli/cli.py index eb06bf087a..203034c6ef 100644 --- a/src/mcp/cli/cli.py +++ b/src/mcp/cli/cli.py @@ -311,7 +311,7 @@ def run( typer.Option( "--transport", "-t", - help="Transport protocol to use (stdio or sse)", + help="Transport protocol to use (stdio, sse, or streamable-http)", ), ] = None, ) -> None: # pragma: no cover From f1ca8e26de4caf7ea335090cb04da8133c87b162 Mon Sep 17 00:00:00 2001 From: Max Isbey <224885523+maxisbey@users.noreply.github.com> Date: Sun, 16 Aug 2026 13:23:21 +0000 Subject: [PATCH 3/3] docs: drop the in-memory mention from the README client section No-Verification-Needed: doc-only wording change in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48610d94d2..cc067aca25 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ async def main() -> None: asyncio.run(main()) ``` -A URL means Streamable HTTP, the transport you deploy. `Client` can also launch a local server as a stdio subprocess or take any custom transport, and in tests you hand it the server object itself (`Client(mcp)`): no process, no port. [Clients](https://py.sdk.modelcontextprotocol.io/client/) has the rest. +A URL means Streamable HTTP, the transport you deploy. `Client` can also launch a local server as a stdio subprocess or take any custom transport; [Clients](https://py.sdk.modelcontextprotocol.io/client/) has the rest. ## Contributing