MCP server by f
Weather MCP Server with GitHub OAuth & Location Management
This project demonstrates an advanced Model Context Protocol (MCP) server with GitHub OAuth authentication, personalized location management, and weather data retrieval using Open-Meteo's free API.
Features
- 🔐 GitHub OAuth 2.0 Authentication: Secure authentication using GitHub Apps
- 📍 Personal Location Management: Save and manage custom location labels (e.g., "home", "office")
- 🌤️ Smart Weather Queries: Check weather using saved labels or direct location names
- 💾 SQLite Database: Persistent storage for users and their locations
- 🆓 Free Weather API: Uses Open-Meteo API - no API key required!
- 🔄 Streamable HTTP Transport: Modern HTTP transport with MCP SDK
- 🛠️ Multiple Tools: Weather lookup, location management (add, list, delete), user info
- 👤 User Profiles: Automatic user creation from GitHub profile data with profile retrieval
Prerequisites
- Node.js (v18 or higher recommended)
- GitHub Account
- GitHub OAuth App (instructions below)
- OpenAI API Key (optional, for the client example)
Setup
1. Install dependencies:
npm install
2. Create GitHub OAuth App:
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in the application details:
- Application name: Weather MCP Server (or your preferred name)
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/oauth/callback
- Click "Register application"
- Copy your Client ID
- Click "Generate a new client secret" and copy it
3. Configure Environment Variables:
cp .env.example .env
Edit .env and add your GitHub OAuth credentials:
GITHUB_CLIENT_ID=your_github_client_id_here
GITHUB_CLIENT_SECRET=your_github_client_secret_here
GITHUB_REDIRECT_URI=http://localhost:3000/oauth/callback
PORT=3000
4. Start the MCP server:
node server.js
The server will start on http://127.0.0.1:3000
5. Authenticate with GitHub:
- Open your browser and visit:
http://localhost:3000/oauth/login - Click "Authorize" to connect with GitHub
- Copy the access token displayed on the success page
- Use this token in the Authorization header:
Bearer <your-token>
6. Configure Claude Desktop
Add the configuration to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Option A: Automatic OAuth (Recommended)
{
"mcpServers": {
"weather-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://127.0.0.1:3000/mcp"
]
}
}
}
Claude Desktop will automatically discover the OAuth endpoints and open your browser for authentication. Just authorize with GitHub when prompted!
Option B: Manual Token
{
"mcpServers": {
"weather-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://127.0.0.1:3000/mcp",
"--header",
"Authorization: Bearer YOUR_GITHUB_ACCESS_TOKEN",
"--no-auth"
]
}
}
}
First get your token by visiting http://localhost:3000/oauth/login, then replace YOUR_GITHUB_ACCESS_TOKEN with your token.
Usage Examples
Once connected via Claude Desktop, you can:
Basic Weather Queries
- "What is the weather like in San Francisco?"
- "Tell me the current weather in Tokyo"
- "How's the weather in Paris?"
Save Personal Locations
- "Save my home location as New York"
- "Add my office location as San Francisco"
- "Save the gym location as 123 Main Street, Boston"
Query Using Saved Labels
- "What's the weather at home?"
- "How's the weather at the office?"
- "Check the weather at the gym"
Manage Locations
- "List all my saved locations"
- "Show my locations"
- "Delete my home location"
User Profile
- "Who am I?"
- "Show my profile"
- "What's my GitHub username?"
How It Works
- OAuth Flow: User authenticates via GitHub OAuth 2.0
- Token Exchange: Server exchanges authorization code for access token
- User Creation: Server creates or updates user profile from GitHub data
- Authentication: Client sends Bearer token in Authorization header
- Token Validation: Server validates token against SQLite database
- Session Creation: Server creates authenticated session with user context
- Tool Discovery: Client discovers available MCP tools from server
- Tool Execution:
- Weather queries resolve location labels to actual addresses
- Location management stores data per-user in database
- All operations are scoped to the authenticated user
- Weather Data: Server fetches real-time weather from Open-Meteo API
- Response: Results returned to client with user-specific context
Architecture
User Browser
│
│ 1. Visit /oauth/login
▼
GitHub OAuth Server
│
│ 2. Authorization
▼
/oauth/callback
│
│ 3. Access Token
▼
┌─────────────────────────────────────────────┐
│ Claude Desktop / MCP Client │
│ (with Authorization: Bearer token) │
└─────────────────┬───────────────────────────┘
│ Streamable HTTP + Auth
▼
┌─────────────────────────────────────────────┐
│ server.js (MCP Server) │
│ ┌───────────────────────────────────────┐ │
│ │ OAuth Authentication (auth.js) │ │
│ │ ↓ │ │
│ │ Token Validation Middleware │ │
│ │ ↓ │ │
│ │ Session Management (per-user) │ │
│ │ ↓ │ │
│ │ MCP Tools: │ │
│ │ - get_current_weather │ │
│ │ - add_location │ │
│ │ - list_locations │ │
│ │ - delete_location │ │
│ └───────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────┐ │
│ │ SQLite Database (weather.db) │ │
│ │ - users (with GitHub data) │ │
│ │ - locations │ │
│ └───────────────────────────────────────┘ │
└─────────────────┬───────────────────────────┘
│
▼
Open-Meteo Weather API
MCP Tools
1. get_current_weather
Fetches real-time weather data for any location or saved label.
- Parameters:
location(string): Location name or saved label (e.g., "New York", "home")unit(enum): Temperature unit - "celsius" or "fahrenheit" (default: celsius)
- Returns: Temperature, condition, humidity, wind speed, pressure, cloud cover
- Special: Automatically resolves saved location labels to addresses
2. add_location
Save a location with a custom label for quick access.
- Parameters:
label(string): Custom label (e.g., "home", "office", "gym")location(string): Actual location name or address
- Returns: Confirmation message
- Note: Replaces existing label if it already exists
3. list_locations
Display all saved locations for the authenticated user.
- Parameters: None
- Returns: List of all saved locations with their labels
4. delete_location
Remove a saved location by its label.
- Parameters:
label(string): Label of the location to delete
- Returns: Confirmation or error message
5. get_user_info
Get information about the currently logged-in user.
- Parameters: None
- Returns: User profile with GitHub username, name, email, avatar URL, and user ID
Project Structure
komunite-bootcamp-mcp/
├── server.js # MCP HTTP server with OAuth
├── database.js # SQLite database operations
├── auth.js # GitHub OAuth authentication
├── index.js # OpenAI function calling example (legacy)
├── .env.example # Environment variables template
├── .env # Your environment variables (create this)
├── package.json # Dependencies and scripts
├── weather.db # SQLite database (created on first run)
└── README.md # This file
Database Schema
Users Table
CREATE TABLE users (
id TEXT PRIMARY KEY,
github_id TEXT UNIQUE,
github_username TEXT,
github_email TEXT,
name TEXT,
avatar_url TEXT,
access_token TEXT,
refresh_token TEXT,
token_expires_at DATETIME,
auth_token TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
Locations Table
CREATE TABLE locations (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
label TEXT NOT NULL,
location_name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE(user_id, label)
)
Security Features
- GitHub OAuth 2.0: Industry-standard OAuth authentication flow
- PKCE (RFC 7636): Proof Key for Code Exchange with S256 for public clients
- Dynamic Client Registration (RFC 7591): Automatic client registration
- State Parameter: CSRF protection with state verification
- Bearer Token Authentication: All MCP endpoints require valid authentication
- Token Validation: Access tokens validated against database
- User Isolation: Each user can only access their own locations
- Session Management: Secure session handling with user context
- Database Constraints: Foreign key constraints ensure data integrity
- Automatic Token Expiration: Token expiry tracking for enhanced security
Customization
Adding Custom MCP Tools
- Open
server.js - Register a new tool after existing tools:
sessionServer.tool(
'your_tool_name',
'Tool description',
{
param1: z.string().describe('Parameter description'),
},
async ({ param1 }) => {
const userId = sessionUsers[transport.sessionId]?.id;
// Your tool logic here
return {
content: [{ type: 'text', text: 'Result' }],
};
}
);
- The tool will automatically be discovered by clients
API Endpoints
OAuth Discovery Endpoints (RFC 8414 & RFC 9728)
- GET /.well-known/oauth-authorization-server - OAuth 2.0 Authorization Server Metadata
- GET /.well-known/oauth-protected-resource - OAuth 2.0 Protected Resource Metadata
OAuth Endpoints (Standards-Compliant)
- POST /oauth/register - Dynamic Client Registration (RFC 7591)
- GET /oauth/authorize - OAuth 2.0 Authorization Endpoint
- POST /oauth/token - OAuth 2.0 Token Endpoint
- POST /oauth/revoke - OAuth 2.0 Token Revocation (RFC 7009)
- GET /oauth/login - Manual OAuth flow (browser-based)
- GET /oauth/callback - OAuth callback handler
- GET /oauth/me - Returns current user info (requires authentication)
MCP Endpoints
- POST /mcp - Main MCP endpoint for tool calls
- GET /mcp - Server-Sent Events for notifications
- DELETE /mcp - Session termination
Utility Endpoints
- GET /health - Health check endpoint
Notes
- Based on the Model Context Protocol (MCP) specification
- Uses @modelcontextprotocol/sdk for MCP server implementation
- Streamable HTTP transport: Modern HTTP transport with session management
- SQLite Database: Lightweight, file-based database with better-sqlite3
- GitHub OAuth 2.0: Secure authentication via GitHub Apps
- Uses Open-Meteo API - free and open-source weather API
- No API key required for weather data!
- Per-user location management with database isolation
- Automatic label resolution for convenient weather queries
- User profiles automatically created from GitHub data
Logout / Revoke Access
To logout from OAuth when using Claude Desktop:
Option 1: Clear mcp-remote Cache
rm -rf ~/.cache/mcp-remote/auth/
Option 2: Manual Token Revocation
curl -X POST http://localhost:3000/oauth/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=YOUR_ACCESS_TOKEN"
Then clear the cache and restart Claude Desktop.
Troubleshooting
Token Expired
If you get authentication errors, your GitHub token may have expired:
- Visit
http://localhost:3000/oauth/loginagain - Get a new access token
- Update your Claude Desktop configuration with the new token
Testing with cURL
You can test the API directly with cURL:
# Check OAuth server metadata:
curl http://localhost:3000/.well-known/oauth-authorization-server
# Check protected resource metadata:
curl http://localhost:3000/.well-known/oauth-protected-resource
# Get your access token first by visiting:
open http://localhost:3000/oauth/login
# Then test the authenticated endpoint:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
http://localhost:3000/oauth/me
References
- Model Context Protocol Documentation
- MCP Authorization Specification
- OAuth 2.1 Draft Specification
- RFC 7009: OAuth 2.0 Token Revocation
- RFC 7591: OAuth 2.0 Dynamic Client Registration
- RFC 7636: PKCE - Proof Key for Code Exchange
- RFC 8414: OAuth 2.0 Authorization Server Metadata
- RFC 9728: OAuth 2.0 Protected Resource Metadata
- GitHub OAuth Documentation
- Open-Meteo Weather API