Build MCP servers using the recommended stdio transport — simple, secure subprocess-based communication over standard input and output.
The stdio transport is the recommended transport mechanism for local MCP servers as of the MCP Specification 2025-06-18. It communicates through standard input and output streams, requires no HTTP server, and is simpler to implement, debug, and secure than any web-based transport.
The standalone SSE (Server-Sent Events) transport was deprecated in MCP Specification 2025-06-18. Use stdio for local servers and Streamable HTTP for remote servers.
import asyncioimport loggingfrom mcp.server import Serverfrom mcp.server.stdio import stdio_serverlogging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)server = Server("example-stdio-server")@server.tool()def calculate_sum(a: int, b: int) -> int: """Calculate the sum of two numbers""" return a + b@server.tool()def get_greeting(name: str) -> str: """Generate a personalized greeting""" return f"Hello, {name}! Welcome to MCP stdio server."@server.tool()def get_server_info() -> dict: """Get information about this MCP server""" return { "server_name": "example-stdio-server", "version": "1.0.0", "transport": "stdio", "capabilities": ["tools"] }async def main(): async with stdio_server(server) as (read_stream, write_stream): await server.run( read_stream, write_stream, server.create_initialization_options() )if __name__ == "__main__": asyncio.run(main())
#!/usr/bin/env nodeimport { Server } from "@modelcontextprotocol/sdk/server/index.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";const server = new Server( { name: "example-stdio-server", version: "1.0.0" }, { capabilities: { tools: {} } });server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "get_greeting", description: "Get a personalized greeting", inputSchema: { type: "object", properties: { name: { type: "string", description: "Name to greet" } }, required: ["name"], }, }, ],}));server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "get_greeting") { return { content: [{ type: "text", text: `Hello, ${request.params.arguments?.name}! Welcome to MCP stdio server.`, }], }; } throw new Error(`Unknown tool: ${request.params.name}`);});async function runServer() { const transport = new StdioServerTransport(); await server.connect(transport);}runServer().catch(console.error);
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using ModelContextProtocol.Server;using System.ComponentModel;var builder = Host.CreateApplicationBuilder(args);builder.Services .AddMcpServer() .WithStdioServerTransport() .WithTools<Tools>();var app = builder.Build();await app.RunAsync();[McpServerToolType]public class Tools{ [McpServerTool, Description("Get a personalized greeting")] public string GetGreeting(string name) => $"Hello, {name}! Welcome to MCP stdio server."; [McpServerTool, Description("Calculate the sum of two numbers")] public int CalculateSum(int a, int b) => a + b;}
The Inspector opens a browser window. You will see your server’s capabilities listed, and you can test tools interactively while monitoring the raw JSON-RPC messages.