Skip to main content
Glama

Weather MCP Server with GitHub OAuth & Location Management

by f
README.md•15.1 kB
# 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: ```bash npm install ``` ### 2. Create GitHub OAuth App: 1. Go to [GitHub Developer Settings](https://github.com/settings/developers) 2. Click **"New OAuth App"** 3. 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` 4. Click **"Register application"** 5. Copy your **Client ID** 6. Click **"Generate a new client secret"** and copy it ### 3. Configure Environment Variables: ```bash cp .env.example .env ``` Edit `.env` and add your GitHub OAuth credentials: ```bash 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: ```bash node server.js ``` The server will start on `http://127.0.0.1:3000` ### 5. Authenticate with GitHub: 1. Open your browser and visit: `http://localhost:3000/oauth/login` 2. Click **"Authorize"** to connect with GitHub 3. Copy the **access token** displayed on the success page 4. 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)** ```json { "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** ```json { "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 1. **OAuth Flow**: User authenticates via GitHub OAuth 2.0 2. **Token Exchange**: Server exchanges authorization code for access token 3. **User Creation**: Server creates or updates user profile from GitHub data 4. **Authentication**: Client sends Bearer token in Authorization header 5. **Token Validation**: Server validates token against SQLite database 6. **Session Creation**: Server creates authenticated session with user context 7. **Tool Discovery**: Client discovers available MCP tools from server 8. **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 9. **Weather Data**: Server fetches real-time weather from Open-Meteo API 10. **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 ```sql 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 ```sql 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 1. Open `server.js` 2. Register a new tool after existing tools: ```javascript 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' }], }; } ); ``` 3. 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 ```bash rm -rf ~/.cache/mcp-remote/auth/ ``` ### Option 2: Manual Token Revocation ```bash 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: 1. Visit `http://localhost:3000/oauth/login` again 2. Get a new access token 3. Update your Claude Desktop configuration with the new token ## Testing with cURL You can test the API directly with cURL: ```bash # 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](https://modelcontextprotocol.io/) - [MCP Authorization Specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization) - [OAuth 2.1 Draft Specification](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13) - [RFC 7009: OAuth 2.0 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009) - [RFC 7591: OAuth 2.0 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591) - [RFC 7636: PKCE - Proof Key for Code Exchange](https://datatracker.ietf.org/doc/html/rfc7636) - [RFC 8414: OAuth 2.0 Authorization Server Metadata](https://datatracker.ietf.org/doc/html/rfc8414) - [RFC 9728: OAuth 2.0 Protected Resource Metadata](https://datatracker.ietf.org/doc/html/rfc9728) - [GitHub OAuth Documentation](https://docs.github.com/en/developers/apps/building-oauth-apps) - [Open-Meteo Weather API](https://open-meteo.com/)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/f/komunite-mcp-bootcamp-weather-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server