achimstruve/mcp-https-OAuth-database-template
If you are the rightful owner of mcp-https-OAuth-database-template and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
This document provides a comprehensive guide to setting up and deploying a secure, production-ready Model Context Protocol (MCP) server with HTTPS support, OAuth authentication, and Docker deployment.
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
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- 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
-
Fork this repository
-
Update
server.py
:- Replace example tools with your own tools
- Update the server name in
FastMCP("YourServerName")
- Add your custom resources
-
Update
pyproject.toml
:- Change
name
to your project name - Update
description
- Add any additional dependencies
- Change
-
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)
- 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
- 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:
- Discover OAuth server capabilities
- Register itself as a dynamic client (RFC 7591)
- Open your browser for Google authentication
- 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
- 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"
- 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"
- 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
- Configure DNS: Point your domain to your server's IP
- Set environment variables: Domain, email, OAuth credentials
- Run deployment script:
./scripts/run-with-letsencrypt.sh
- 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
- Check server logs for specific error messages
- Verify environment variables are set correctly
- Test each component (SSL, auth, MCP protocol) separately
- Review the MCP specification at modelcontextprotocol.io
License
MIT License - see file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- 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.