Initial commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Python MCP Server Best Practices (FastMCP)
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
uv init mcp-server-name
|
||||
uv add "mcp[cli]"
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
- ✓ Use type hints (FastMCP reads them!)
|
||||
- ✓ Write detailed docstrings (becomes tool descriptions)
|
||||
- ✓ Use async functions for I/O
|
||||
- ✓ Handle exceptions gracefully
|
||||
- ✓ Log to stderr only in STDIO mode
|
||||
|
||||
## Tool Definition
|
||||
|
||||
```python
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
mcp = FastMCP("server-name")
|
||||
|
||||
@mcp.tool()
|
||||
async def search_database(query: str, limit: int = 10) -> str:
|
||||
"""
|
||||
Search the database for records matching the query.
|
||||
|
||||
Args:
|
||||
query: Search terms to match against records
|
||||
limit: Maximum number of results to return (default: 10)
|
||||
|
||||
Returns:
|
||||
JSON string of matching records
|
||||
"""
|
||||
results = await db.search(query, limit=limit)
|
||||
return json.dumps(results)
|
||||
```
|
||||
|
||||
## Resource Definition
|
||||
|
||||
```python
|
||||
@mcp.resource("db://tables/{table_name}/schema")
|
||||
async def get_table_schema(table_name: str) -> str:
|
||||
"""Get the schema for a database table."""
|
||||
schema = await db.get_schema(table_name)
|
||||
return json.dumps(schema)
|
||||
```
|
||||
|
||||
## Critical Rules
|
||||
|
||||
### STDIO Transport
|
||||
|
||||
```python
|
||||
import sys
|
||||
|
||||
# WRONG - corrupts JSON-RPC
|
||||
print("Debug info")
|
||||
|
||||
# CORRECT - safe for STDIO
|
||||
print("Debug info", file=sys.stderr)
|
||||
|
||||
# Or use logging
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stderr)
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def risky_operation(param: str) -> str:
|
||||
"""Perform an operation that might fail."""
|
||||
try:
|
||||
result = await external_api.call(param)
|
||||
return str(result)
|
||||
except Exception as e:
|
||||
logging.error(f"Operation failed: {e}")
|
||||
raise ValueError(f"Operation failed: {e}")
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
# With uv
|
||||
uv run main.py
|
||||
|
||||
# Direct
|
||||
python main.py
|
||||
```
|
||||
@@ -0,0 +1,71 @@
|
||||
# TypeScript MCP Server Best Practices
|
||||
|
||||
## Configuration
|
||||
|
||||
- ✓ Use strict mode in tsconfig.json
|
||||
- ✓ Target ES2022 or later
|
||||
- ✓ Use Node16 module resolution
|
||||
|
||||
## Implementation
|
||||
|
||||
- ✓ Leverage Zod for runtime validation
|
||||
- ✓ Export types for reusability
|
||||
- ✓ Use async/await consistently
|
||||
- ✓ Handle errors with try/catch
|
||||
- ✓ Build before testing!
|
||||
|
||||
## Critical Rules
|
||||
|
||||
### STDIO Transport
|
||||
```typescript
|
||||
// WRONG - corrupts JSON-RPC
|
||||
console.log("Debug info");
|
||||
|
||||
// CORRECT - safe for STDIO
|
||||
console.error("Debug info");
|
||||
```
|
||||
|
||||
### Tool Schemas
|
||||
|
||||
```typescript
|
||||
import { z } from "zod";
|
||||
|
||||
const ToolInputSchema = z.object({
|
||||
query: z.string().describe("Search query"),
|
||||
limit: z.number().optional().default(10).describe("Max results"),
|
||||
});
|
||||
|
||||
// Validate in handler
|
||||
const input = ToolInputSchema.parse(request.params.arguments);
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
try {
|
||||
const result = await performOperation(request.params);
|
||||
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||
} catch (error) {
|
||||
console.error("Tool error:", error);
|
||||
return {
|
||||
content: [{
|
||||
type: "text",
|
||||
text: `Error: ${error.message}`
|
||||
}],
|
||||
isError: true
|
||||
};
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Build & Run
|
||||
|
||||
```bash
|
||||
# Development
|
||||
npm run watch
|
||||
|
||||
# Production
|
||||
npm run build
|
||||
node build/index.js
|
||||
```
|
||||
Reference in New Issue
Block a user