nathanjclark/mcp-server
If you are the rightful owner of mcp-server 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.
The Shuttle MCP Server is a comprehensive Model Context Protocol server built using Rust, Axum, and Shuttle, designed for production-ready deployment with advanced features like OAuth 2.1 authentication and AI integration.
Shuttle MCP Server
A complete Model Context Protocol (MCP) server built with Rust, Axum, and Shuttle. This template provides everything you need to build a production-ready MCP server with OAuth 2.1 authentication, database integration, AI tools, and a clean registry-based architecture.
π What You Get
- π OAuth 2.1 Authentication - Secure authentication via Auth0
- ποΈ PostgreSQL Database - Managed database with automatic migrations
- π€ AI Integration - AI-powered tools via the
rig
crate - π Built-in Tools - Text processing, database queries, timestamps, and more
- π§ Registry System - Centralized management of tools, resources, and prompts
- β‘ Full MCP Compliance - Complete JSON-RPC 2.0 implementation with proper authentication
- π One-Click Deploy - Deploy to Shuttle with a single command
ποΈ Architecture Overview
This server implements the complete MCP specification with authentication:
βββββββββββββββββββ JSON-RPC 2.0 βββββββββββββββββββ
β MCP Client β βββββββββββββββββββββΆβ Shuttle MCP β
β (Claude, etc.) β β Server β
β β βββββ Tools ββββββββββ β
β β βββ Resources ββββββββ π OAuth 2.1 β
β β ββββ Prompts βββββββββ ποΈ PostgreSQL β
βββββββββββββββββββ β π€ AI Tools β
βββββββββββββββββββ
Authentication Flow
- Public Methods:
initialize
,notifications/initialized
,exit
- Protected Methods: All tools, resources, and prompts require authentication
- Security: Users authenticate via OAuth 2.1 before accessing any functionality
π Prerequisites
-
Rust - Install from rustup.rs
-
Shuttle CLI - Recommended installation method:
# Linux/macOS curl -sSfL https://www.shuttle.dev/install | bash # Windows (PowerShell) # iwr https://www.shuttle.dev/install-win | iex # Alternative: Using Cargo # cargo install cargo-shuttle
-
Auth0 Account - Free at auth0.com
-
Docker
π Quick Start
1. Clone and Setup
git clone <this-repo-url>
cd mcp-server
2. Configure Auth0
- Go to Applications and click "Create Application"
- Choose "Regular Web Application"
- Go to connections and enable Google Social Connection
- Note your domain, client ID, and client secret from the application's settings
3. Create Secrets
# Create Secrets.toml in project root
cat > Secrets.toml << EOF
AUTH0_DOMAIN = 'your-tenant.auth0.com'
AUTH0_CLIENT_ID = 'your-client-id'
AUTH0_CLIENT_SECRET = 'your-client-secret'
AUTH0_CALLBACK_URL = 'http://localhost:8000/auth/callback'
SESSION_JWT_SECRET = 'your-very-long-random-secret-key-at-least-32-chars'
OPENAI_API_KEY = 'sk-your-openai-api-key' # Optional
EOF
4. Run Locally
shuttle run
5. Test Your Server
The easiest way to test your MCP server is using the official MCP Inspector - a visual testing tool designed specifically for MCP development.
Using MCP Inspector (Recommended)
The MCP Inspector provides a complete testing interface with no installation required:
# Test the Shuttle server directly
npx @modelcontextprotocol/inspector shuttle run
- Copy session token from CLI ouput after running the above command
- Open MCP Inspector in the Browser
- Choose Streamable HTTP as the transport type.
- Set URL as "http://localhost:8000/mcp"
- Click "Configuration" and then enter the copied session token into the "Proxy Session Token" field.
- Click Connect
- Go the "Auth" tab, select guided or quick auth flow and follow the steps.
The Inspector provides:
- Visual Interface: Interactive UI for testing tools, resources, and prompts
- Authentication Support: Built-in bearer token authentication for testing protected methods
- Real-time Debugging: Monitor JSON-RPC messages and server responses
- Export Configuration: Generate
mcp.json
files for client integration
Basic Testing with curl
For quick verification, you can test public endpoints:
# Test MCP endpoint (initialize is public - no auth required)
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "test-client", "version": "1.0.0"}
},
"id": 1
}'
# Test authentication flow (will redirect to Auth0)
curl -I http://localhost:8000/auth/login
Note: Testing protected MCP methods (tools, resources, prompts) requires authentication, which is much easier to handle with the MCP Inspector's built-in auth support.
π Deploy to Production
1. Setup Shuttle
shuttle login
2. Deploy
shuttle deploy
Note: This deployment will not fully work as it does not yet have the required secrets. However, we need the deployment url in order to confugure the secrets - seee the next step.
3. Update Auth0 Settings
In your Auth0 application:
- Allowed Callback URLs:
https://your-mcp-server.shuttleapp.dev/auth/callback
- Allowed Logout URLs:
https://your-mcp-server.shuttleapp.dev/
4. Update Production Secrets
# Update Secrets.toml
AUTH0_CALLBACK_URL = 'https://your-mcp-server.shuttleapp.dev/auth/callback'
# Keep other secrets the same
5. Re-Deploy
shuttle deploy
π API Endpoints
Authentication
OAuth 2.1 Endpoints
Endpoint | Method | Description |
---|---|---|
/.well-known/oauth-authorization-server | GET | OAuth server metadata (RFC8414) |
/authorize | GET | Authorization endpoint with PKCE support |
/token | POST | Token endpoint for access tokens |
/register | POST | Dynamic client registration (RFC7591) |
OAuth Flow
- Client registers using
/register
endpoint - Client initiates auth flow via
/authorize
with PKCE - User authenticates and authorizes
- Client exchanges code for token via
/token
- Client uses access token for MCP requests
Auth0 Callback Endpoint
This endpoint handles the Auth0 callback as part of the OAuth flow:
GET /auth/callback
- Handle Auth0 callback and bind users to OAuth authorization codes
MCP Protocol
POST /mcp
- Main MCP JSON-RPC 2.0 endpoint
π οΈ Available MCP Capabilities
Core Protocol Methods
Method | Authentication | Description |
---|---|---|
initialize | β Public | Exchange capabilities and server info |
notifications/initialized | β Public | Complete MCP handshake |
tools/list | β Required | List available tools with schemas |
tools/call | β Required | Execute tools |
resources/list | β Required | List available data resources |
resources/read | β Required | Read resource content |
prompts/list | β Required | List available prompt templates |
prompts/get | β Required | Get specific prompts |
Built-in Tools
Tool | Description | Arguments |
---|---|---|
text_length | Get character count | text: string |
text_transform | Transform text case | text: string, transform: enum |
text_search | Search for patterns | text: string, pattern: string |
timestamp | Get current UTC time | None |
ai_complete | Complete text prompts | prompt: string |
ai_summarize | Summarize long text | text: string |
user_stats | Get database statistics | None |
Built-in Resources
Resource | Description | Content Type |
---|---|---|
user://stats | User statistics from database | application/json |
Built-in Prompts
Prompt | Description | Arguments |
---|---|---|
code_review | Generate code review prompts | code: string, language?: string |
explain_error | Generate error explanation prompts | error: string |
π§ Extending Your Server
Adding New Tools
- Implement the tool in
src/tools/
:
// src/tools/my_tools.rs
pub fn calculate_fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => calculate_fibonacci(n - 1) + calculate_fibonacci(n - 2)
}
}
- Register in the registry (
src/registries.rs
):
Tool {
name: "fibonacci",
description: "Calculate Fibonacci number",
},
- Add the handler in
src/mcp.rs
(handle_tool_call
function):
"fibonacci" => {
let n = arguments.get("n").and_then(|v| v.as_u64()).unwrap_or(0) as u32;
let result = crate::tools::my_tools::calculate_fibonacci(n);
Ok(serde_json::json!({
"content": [{
"type": "text",
"text": format!("Fibonacci({}) = {}", n, result)
}]
}))
}
- Add the schema in
get_tool_schema
function:
"fibonacci" => serde_json::json!({
"type": "object",
"properties": {
"n": {
"type": "integer",
"description": "The position in Fibonacci sequence",
"minimum": 0
}
},
"required": ["n"]
}),
Adding New Resources
- Register the resource (
src/registries.rs
):
Resource {
uri: "system://health",
name: "System Health",
description: "Current system health metrics",
mime_type: "application/json",
},
- Add the handler in
handle_resource_read
function (src/mcp.rs
):
"system://health" => {
let health_data = serde_json::json!({
"status": "healthy",
"uptime": "2h 30m",
"memory_usage": "45%"
});
Ok(serde_json::json!({
"contents": [{
"uri": uri,
"mimeType": resource.mime_type,
"text": serde_json::to_string_pretty(&health_data).unwrap()
}]
}))
}
Adding New Prompts
- Register the prompt (
src/registries.rs
):
Prompt {
name: "write_tests",
description: "Generate unit tests for code",
arguments: vec![
PromptArgument {
name: "code",
description: "The code to test",
required: true,
},
PromptArgument {
name: "framework",
description: "Testing framework",
required: false,
},
],
},
- Add the handler in
handle_prompt_get
function (src/mcp.rs
):
"write_tests" => {
let code = arguments.and_then(|args| args.get("code"))
.and_then(|v| v.as_str()).unwrap_or("// No code provided");
let framework = arguments.and_then(|args| args.get("framework"))
.and_then(|v| v.as_str()).unwrap_or("jest");
Ok(serde_json::json!({
"messages": [{
"role": "user",
"content": {
"type": "text",
"text": format!("Write {} unit tests for this code:\n\n{}", framework, code)
}
}]
}))
}
π Project Structure
src/
βββ main.rs # Application entry point and routing
βββ auth/ # Authentication system
β βββ mod.rs # Module exports
β βββ handlers.rs # OAuth and session handlers
β βββ middleware.rs # Authentication middleware and helpers
β βββ models.rs # User and auth data models
βββ database.rs # Database initialization and migrations
βββ mcp.rs # MCP JSON-RPC protocol implementation
βββ registries.rs # Central registries for tools, resources, and prompts
βββ tools/ # Tool implementations
βββ mod.rs # Tool module exports
βββ ai.rs # OpenAI integration tools
βββ db.rs # Database query tools
βββ text.rs # Text processing utilities
βββ utils.rs # General utility tools
migrations/ # Database migration files
π Learn More
- Model Context Protocol Documentation
- Shuttle Documentation
- Auth0 Documentation
- Axum Web Framework
- OpenAI API Documentation
π License
This project is licensed under the MIT License - see the file for details.