mcp-server-template

mcp-server-template

A production-ready FastMCP server template supporting local development with stdio and secure web deployment with HTTPS and OAuth.

Category
访问服务器

README

MCP Server Template

A production-ready FastMCP server template with dual-mode support: secure web deployment with HTTPS and OAuth for Claude Code, or local development with stdio transport for Claude Desktop. This template provides a foundation for building MCP servers that work in both local and production environments.

Features

  • 🔄 Dual Mode Support: Local development (stdio) + Production deployment (HTTPS/OAuth)
  • 🖥️ Claude Desktop Compatible: Local mode with stdio transport for desktop development
  • 🌐 Claude Code Ready: Web mode with SSE transport for production use
  • 🔒 OAuth 2.1 + PKCE: Google OAuth 2.1 with PKCE for enhanced security (web mode)
  • 🔄 Dynamic Client Registration: RFC 7591 compliant for Claude Code compatibility
  • 🌐 HTTPS Support: SSL/TLS encryption with Let's Encrypt integration
  • 🐳 Docker Deployment: Production-ready containerized deployment
  • ⚡ FastMCP Integration: Built on the modern FastMCP framework
  • 🛡️ Security First: JWT tokens, PKCE validation, and comprehensive OAuth endpoints

Example Tools & Resources

  • Addition tool: Demonstrates basic tool functionality
  • Secret word tool: Shows authenticated tool access
  • Dynamic greeting resource: Example of parametrized resources

Quick Start

Prerequisites

For Local Development (Claude Desktop):

  • Python 3.10+
  • Claude Desktop

For Web Deployment (Claude Code):

  • Python 3.10+
  • Docker
  • A domain name (for HTTPS deployment)
  • Browser access (required for OAuth authentication)

1. Clone and Setup

git clone https://github.com/your-username/mcp-server-template.git
cd mcp-server-template

# Install dependencies
pip install uv
uv sync

2. Configure Google OAuth

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API
  4. Create OAuth 2.0 credentials:
    • Application type: Web application
    • Authorized redirect URIs: https://your-domain.com:8443/callback

3. Configure Environment

Create a .env file:

# Server Configuration
SERVER_NAME=mcp-template       # Name for the MCP server, Docker image, and container

# OAuth Configuration
GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-google-client-secret
OAUTH_REDIRECT_URI=https://your-domain.com:8443/callback
JWT_SECRET_KEY=your-secure-random-string-here

# SSL/HTTPS (for production)
SSL_ENABLED=true
DOMAIN_NAME=your-domain.com
SSL_CERT_PATH=/etc/letsencrypt/live/your-domain.com/fullchain.pem
SSL_KEY_PATH=/etc/letsencrypt/live/your-domain.com/privkey.pem

# MCP Configuration
MCP_TRANSPORT=sse
MCP_HOST=0.0.0.0
MCP_PORT=8443

4. Deploy

Local Development

# Run locally without SSL
MCP_TRANSPORT=sse SSL_ENABLED=false uv run python server.py

Production Deployment

# Build Docker image
./scripts/build.sh

# Deploy with HTTPS and Let's Encrypt
export DOMAIN_NAME=your-domain.com
export SSL_EMAIL=admin@your-domain.com
export GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
export GOOGLE_CLIENT_SECRET=your-google-client-secret
export OAUTH_REDIRECT_URI=https://your-domain.com:8443/callback
export JWT_SECRET_KEY=$(openssl rand -base64 32)
sudo -E ./scripts/run-with-letsencrypt.sh

Your server will be available at: https://your-domain.com:8443/sse

Using This Template

For Template Users

  1. Fork this repository

  2. Update server.py:

    • Replace example tools with your own tools
    • Update the server name in FastMCP("YourServerName")
    • Add your custom resources
  3. Update pyproject.toml:

    • Change name to your project name
    • Update description
    • Add any additional dependencies
  4. Configure deployment:

    • Set up Google OAuth credentials
    • Configure your domain name and OAuth redirect URI
    • Generate a secure JWT secret key

Example Tool Implementation

@mcp.tool()
def my_custom_tool(param1: str, param2: int) -> str:
    """Your custom tool description"""
    # Your tool logic here
    return f"Result: {param1} with {param2}"

@mcp.resource("my-resource://{id}")
def get_my_resource(id: str) -> str:
    """Your custom resource description"""
    # Your resource logic here
    return f"Resource data for {id}"

Client Setup

Claude Desktop (Local Mode)

For local development with Claude Desktop (no OAuth required):

Quick Setup (Recommended)

  1. Install dependencies:
# Using uv (recommended)
uv sync

# Or using pip (Windows users)
pip install --upgrade pip
pip install "mcp>=1.12.0" "anyio>=4.4.0" python-dotenv
  1. Configure Claude Desktop (claude_desktop_config.json):

Windows (Recommended):

{
  "mcpServers": {
    "my-local-server": {
      "command": "cmd",
      "args": ["/c", "C:/path/to/your/project/run_local_simple.bat"],
      "cwd": "C:/path/to/your/project"
    }
  }
}

Linux/Mac:

{
  "mcpServers": {
    "my-local-server": {
      "command": "uv",
      "args": ["run", "python", "/path/to/your/project/server.py"],
      "env": {
        "LOCAL_MODE": "true"
      }
    }
  }
}

✅ Benefits: No OAuth setup required, immediate local development, stdio transport

Claude Code (Web Mode)

For production deployment, Claude Code natively supports SSE transport over HTTPS with OAuth 2.1 + PKCE:

# Add the server (OAuth flow will start automatically)
claude mcp add --transport sse my-server https://your-domain.com:8443/sse

When you connect, Claude Code will:

  1. Discover OAuth server capabilities
  2. Register itself as a dynamic client (RFC 7591)
  3. Open your browser for Google authentication
  4. Complete PKCE flow and store token securely

⚠️ Note: Browser access is required for authentication. This server does not support headless authentication.

Other MCP Clients

Configure your MCP client with:

  • Transport: sse (Server-Sent Events)
  • URL: https://your-domain.com:8443/sse
  • Authentication: OAuth 2.0 with JWT tokens

Testing Your Server

# Test connectivity
curl https://your-domain.com:8443/sse

# Test OAuth metadata endpoint
curl https://your-domain.com:8443/.well-known/oauth-authorization-server

# After OAuth authentication, test with JWT token
curl -H "Authorization: Bearer your-jwt-token" https://your-domain.com:8443/sse

# Test specific tools (requires MCP client)
# Your MCP client will be able to call tools like:
# - add(5, 3) -> 8
# - secret_word() -> "OVPostWebExperts"
# - greeting://John -> "Hello, John!"

Architecture

Files Structure

├── server.py              # Main MCP server implementation (dual-mode support)
├── oauth.py               # OAuth 2.0 authentication implementation (web mode)
├── run_local.py           # Python script for LOCAL_MODE with version checking
├── run_local.bat          # Windows batch script with auto-install
├── run_local_simple.bat   # Simple Windows batch script (recommended)
├── requirements.txt       # Python dependencies for pip users
├── pyproject.toml         # Python dependencies and project config
├── .env                   # Environment configuration
├── .env.example           # Environment configuration template
├── Dockerfile             # Production container setup
└── scripts/
    ├── build.sh           # Docker build script
    ├── run-local.sh       # Local development script
    └── run-with-letsencrypt.sh  # Production deployment with SSL

Security Features

  • OAuth 2.1 + PKCE: Enhanced security with Proof Key for Code Exchange
  • Dynamic Client Registration: RFC 7591 compliant client registration
  • HTTPS Enforcement: SSL/TLS encryption for all communications
  • JWT Token Validation: Short-lived tokens (1 hour) for secure access
  • Comprehensive OAuth Endpoints: Authorization server and protected resource metadata
  • Input Validation: Type checking and parameter validation
  • Error Handling: Secure error responses without information leakage
  • Let's Encrypt Integration: Automatic SSL certificate management

Configuration Reference

Environment Variables

Variable Description Default Required
SERVER_NAME Name for the MCP server, Docker image, and container mcp-template No
LOCAL_MODE Enable local mode: stdio transport, no OAuth, no HTTPS false No
GOOGLE_CLIENT_ID Google OAuth Client ID - For web mode
GOOGLE_CLIENT_SECRET Google OAuth Client Secret - For web mode
OAUTH_REDIRECT_URI OAuth callback URL - For web mode
JWT_SECRET_KEY Secret for JWT signing - For web mode
SSL_ENABLED Enable HTTPS false No
DOMAIN_NAME Your domain name - For HTTPS
SSL_CERT_PATH SSL certificate path - If SSL enabled
SSL_KEY_PATH SSL private key path - If SSL enabled
MCP_TRANSPORT Transport protocol sse No
MCP_HOST Host to bind to 0.0.0.0 No
MCP_PORT Port to listen on 8443 (HTTPS) / 8899 (HTTP) No

OAuth 2.1 + PKCE Configuration

Authentication uses OAuth 2.1 with PKCE for enhanced security. The server provides:

  • Dynamic Client Registration (RFC 7591): Automatic client registration
  • OAuth Authorization Server Metadata (RFC 8414): Endpoint discovery
  • OAuth Protected Resource Metadata (RFC 8707): Resource server information
  • PKCE Support (RFC 7636): Protection against code interception attacks

JWT tokens include:

  • User's Google ID (sub)
  • Email address
  • Display name
  • Profile picture URL
  • Token expiration (1 hour)

Development

Local Development

# Install dev dependencies
uv sync --all-extras

# Run tests
uv run pytest

# Format code
uv run black server.py oauth.py

# Type checking
uv run mypy server.py oauth.py

# Lint code
uv run flake8 server.py oauth.py

Adding Custom Tools

  1. Define your tool in server.py:
@mcp.tool()
def your_tool_name(param: str) -> str:
    """Tool description for AI agents"""
    # Implement your logic
    return "result"
  1. Add authentication checks if needed:
@mcp.tool()
def protected_tool() -> str:
    """This tool requires authentication"""
    # Auth context is available in session_auth_contexts
    return "authenticated result"
  1. Test your tool:
# Restart server to load changes
docker restart <your-server-name>

# Test via MCP client or direct HTTP calls

Production Deployment

Prerequisites

  • Domain name pointing to your server
  • Ports 80 (HTTP) and 8443 (HTTPS) open
  • Docker installed

Deployment Steps

  1. Configure DNS: Point your domain to your server's IP
  2. Set environment variables: Domain, email, OAuth credentials
  3. Run deployment script: ./scripts/run-with-letsencrypt.sh
  4. Verify: Test HTTPS endpoint and authentication

Monitoring

Check server logs:

docker logs <your-server-name>

Monitor certificate renewal:

# Certificates auto-renew, but you can check status
docker exec <your-server-name> ls -la /etc/letsencrypt/live/

Troubleshooting

Common Issues

TypeError: 'function' object is not subscriptable (Windows/Claude Desktop)

  • This error occurs with incompatible versions of anyio on Windows
  • Solution (Recommended): Use the simple Windows batch script:
    {
      "mcpServers": {
        "my-local-server": {
          "command": "cmd",
          "args": ["/c", "C:/path/to/your/project/run_local_simple.bat"],
          "cwd": "C:/path/to/your/project"
        }
      }
    }
    
  • Alternative: Manual package update:
    cd "your-project-directory"
    python -m pip install --upgrade pip
    python -m pip install --upgrade "mcp>=1.12.0" "anyio>=4.4.0" python-dotenv
    
  • Ensure Python 3.10+ is installed
  • On Windows, use forward slashes (/) in paths

SSL Certificate Errors

  • Ensure domain points to your server IP
  • Check firewall allows ports 80 and 8443
  • Verify Let's Encrypt rate limits aren't exceeded

Authentication Failures

  • Verify Google OAuth credentials are correct
  • Check OAuth redirect URI matches configuration
  • Ensure JWT token hasn't expired (1 hour lifetime)
  • Verify Authorization: Bearer <jwt-token> header format

Connection Issues

  • Verify Docker container is running: docker ps
  • Check server logs: docker logs <your-server-name>
  • Test basic connectivity: curl https://your-domain.com:8443/sse
  • For Claude Desktop: Check the server runs without errors: LOCAL_MODE=true uv run python server.py

Getting Help

  1. Check server logs for specific error messages
  2. Verify environment variables are set correctly
  3. Test each component (SSL, auth, MCP protocol) separately
  4. Review the MCP specification at modelcontextprotocol.io

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

This template provides a solid foundation for building production-ready MCP servers. Customize it according to your specific needs and use cases.

Mode Comparison

Feature Local Mode (Claude Desktop) Web Mode (Claude Code)
Transport stdio SSE over HTTPS
Authentication None OAuth 2.1 + PKCE
SSL/TLS No Yes
Client Claude Desktop Claude Code
Use Case Local development Production deployment
Setup Complexity Minimal Full OAuth setup required

Switch between modes by setting LOCAL_MODE=true (local) or LOCAL_MODE=false (web) in your environment.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选