chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:31:35 +08:00
commit c275ba2868
13613 changed files with 2980806 additions and 0 deletions
@@ -0,0 +1,123 @@
# MCP stdio Server - Python Solution
> **⚠️ Important**: This solution has been updated to use the **stdio transport** as recommended by MCP Specification 2025-06-18. The original SSE transport has been deprecated.
## Overview
This Python solution demonstrates how to build an MCP server using the current stdio transport. The stdio transport is simpler, more secure, and provides better performance than the deprecated SSE approach.
## Prerequisites
- Python 3.8 or later
- You're recommended to install `uv` for package management, see [instructions](https://docs.astral.sh/uv/#highlights)
## Setup Instructions
### Step 1: Create a virtual environment
```bash
python -m venv venv
```
### Step 2: Activate the virtual environment
**Windows:**
```bash
venv\Scripts\activate
```
**macOS/Linux:**
```bash
source venv/bin/activate
```
### Step 3: Install the dependencies
```bash
pip install mcp
```
## Running the Server
The stdio server runs differently than the old SSE server. Instead of starting a web server, it communicates through stdin/stdout:
```bash
python server.py
```
**Important**: The server will appear to hang - this is normal! It's waiting for JSON-RPC messages from stdin.
## Testing the Server
### Method 1: Using the MCP Inspector (Recommended)
```bash
npx @modelcontextprotocol/inspector python server.py
```
This will:
1. Launch your server as a subprocess
2. Open a web interface for testing
3. Allow you to test all server tools interactively
### Method 2: Direct JSON-RPC testing
You can also test by sending JSON-RPC messages directly:
1. Start the server: `python server.py`
2. Send a JSON-RPC message (example):
```json
{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}
```
3. The server will respond with available tools
### Available Tools
The server provides these tools:
- **add(a, b)**: Add two numbers together
- **multiply(a, b)**: Multiply two numbers together
- **get_greeting(name)**: Generate a personalized greeting
- **get_server_info()**: Get information about the server
### Testing with Claude Desktop
To use this server with Claude Desktop, add this configuration to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"example-stdio-server": {
"command": "python",
"args": ["path/to/server.py"]
}
}
}
```
## Key Differences from SSE
**stdio transport (Current):**
- ✅ Simpler setup - no web server needed
- ✅ Better security - no HTTP endpoints
- ✅ Subprocess-based communication
- ✅ JSON-RPC over stdin/stdout
- ✅ Better performance
**SSE transport (Deprecated):**
- ❌ Required HTTP server setup
- ❌ Needed web framework (Starlette/FastAPI)
- ❌ More complex routing and session management
- ❌ Additional security considerations
- ❌ Now deprecated in MCP 2025-06-18
## Debugging Tips
- Use `stderr` for logging (never `stdout`)
- Test with the Inspector for visual debugging
- Ensure all JSON messages are newline-delimited
- Check that the server starts without errors
This solution follows the current MCP specification and demonstrates best practices for stdio transport implementation.
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""
MCP stdio server example - Updated for MCP Specification 2025-06-18
This server demonstrates the recommended stdio transport instead of the
deprecated SSE transport. The stdio transport is simpler, more secure,
and provides better performance.
"""
import asyncio
import logging
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# Configure logging to stderr (never use stdout for logging in stdio servers)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler()]
)
logger = logging.getLogger(__name__)
# Create the server
server = Server("example-stdio-server")
# Define tools using list_tools and call_tool handlers
@server.list_tools()
async def list_tools() -> list[Tool]:
"""List available tools"""
return [
Tool(
name="add",
description="Add two numbers together",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"}
},
"required": ["a", "b"]
}
),
Tool(
name="multiply",
description="Multiply two numbers together",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"}
},
"required": ["a", "b"]
}
),
Tool(
name="get_greeting",
description="Generate a personalized greeting",
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Name to greet"}
},
"required": ["name"]
}
),
Tool(
name="get_server_info",
description="Get information about this MCP server",
inputSchema={"type": "object", "properties": {}}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
"""Handle tool calls"""
if name == "add":
result = arguments["a"] + arguments["b"]
logger.info(f"Adding {arguments['a']} + {arguments['b']} = {result}")
return [TextContent(type="text", text=str(result))]
elif name == "multiply":
result = arguments["a"] * arguments["b"]
logger.info(f"Multiplying {arguments['a']} * {arguments['b']} = {result}")
return [TextContent(type="text", text=str(result))]
elif name == "get_greeting":
greeting = f"Hello, {arguments['name']}! Welcome to the MCP stdio server."
logger.info(f"Generated greeting for {arguments['name']}")
return [TextContent(type="text", text=greeting)]
elif name == "get_server_info":
info = {
"server_name": "example-stdio-server",
"version": "1.0.0",
"transport": "stdio",
"capabilities": ["tools"],
"description": "Example MCP server using stdio transport (MCP 2025-06-18 specification)"
}
return [TextContent(type="text", text=str(info))]
else:
raise ValueError(f"Unknown tool: {name}")
async def main():
"""Main server function using stdio transport"""
logger.info("Starting MCP stdio server...")
try:
# Use stdio transport - this is the recommended approach
async with stdio_server() as (read_stream, write_stream):
logger.info("Server connected via stdio transport")
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
except Exception as e:
logger.error(f"Server error: {e}")
raise
if __name__ == "__main__":
asyncio.run(main())