stdio transport

MCP supports two transports. HTTP is for remote servers. stdio is for servers that run as a local subprocess under the client. Claude Desktop and Cursor both spawn your server as a subprocess and talk to it through standard input and output. That makes stdio the right default for local tooling.

mcp_server.py
python
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server

server: Server = Server("mcp-pr-review-server")


async def main() -> None:
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            server.create_initialization_options(),
        )


if __name__ == "__main__":
    asyncio.run(main())

stdio_server is an async context manager. It hands you a read stream for requests from stdin and a write stream for responses to stdout. Anything you print to stdout must go through write_stream, otherwise you corrupt the protocol frame.

mcp_server.py
python
import json
from typing import Any
from mcp.types import TextContent

from service import fetch_pr_diff


def _ok(payload: Any) -> list[TextContent]:
    return [TextContent(type="text", text=json.dumps(payload, indent=2, default=str))]


@server.call_tool()
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
    if name == "fetch_pr_diff":
        pr = await fetch_pr_diff(
            arguments["owner"], arguments["repo"], int(arguments["pr_number"])
        )
        return _ok(pr.model_dump())
    return [TextContent(type="text", text=f"Unknown tool: {name}")]

The call_tool handler dispatches by name and always returns a list of content blocks. TextContent wraps a JSON payload so the client receives structured data it can parse.

HTTP makes sense when the server runs somewhere else, like a shared team server or a cloud deployment. stdio is the right pick whenever the server should run with the same file system access, environment variables, and credentials as the client. PR review is a local job, so stdio wins.

Quiz: Quiz

Loading practice…