Skip to main content
Glama

Timezone MCP Server

by sam-artuso
README.mdβ€’12.4 kB
# Timezone MCP Server A dual-interface timezone server supporting both **MCP (Model Context Protocol)** for LLM discovery and **REST API** for direct HTTP access. Get available regions, cities, and current time in any timezone with ISO 8601 formatted timestamps. ## Features - **πŸ€– MCP Protocol Support** - LLMs can auto-discover and use timezone tools via JSON-RPC - **🌐 REST API** - Traditional HTTP endpoints with Swagger/OpenAPI documentation - **πŸ” OAuth2 Authentication** - Secure access with user allowlisting and client credentials - **⏰ Timezone Operations** - Get regions, cities, and current time in any timezone - **πŸ“… ISO 8601 Timestamps** - Local datetime with offset, UTC datetime, and timezone offset - **πŸ§ͺ 100% Test Coverage** - Comprehensive unit and e2e tests (Vitest) - **πŸ”§ NestJS & TypeScript** - Modern, type-safe development - **πŸ“š Dual Documentation** - Swagger UI for humans, MCP schema for LLMs - **🎨 Code Quality** - ESLint, Prettier, and automated formatting ## Getting Started ### Prerequisites - Node.js 22.20.0+ (LTS recommended) - pnpm 10.13.1 (managed via Corepack) > **πŸ“¦ Package Manager:** This project uses **pnpm** exclusively via **Corepack** (built into Node.js). The exact pnpm version is enforced by the `packageManager` field in package.json. After installing Node.js, run `corepack enable` to activate pnpm support. > > **πŸ”§ Version Management:** This project uses **fnm** (Fast Node Manager) or **nvm** to manage Node.js versions. The `.node-version` file will automatically switch to the correct Node.js version when you `cd` into the project directory (if you have fnm/nvm shell integration enabled). ### Installation ```bash pnpm install ``` ### Authentication Setup This server requires OAuth2 authentication for all endpoints except `/health`. You need to configure authentication before running the server. #### Step 1: Configure Environment Variables Copy the example environment file and edit it: ```bash cp example.env .env ``` Edit `.env` and configure: 1. **JWT Settings** (required): ```env JWT_SECRET=your-super-secret-jwt-key-change-this-in-production JWT_EXPIRES_IN=3600 ``` 2. **OAuth2 Provider** (choose one - Google, GitHub, or any OAuth2-compliant provider): For **Google**: ```env OAUTH2_AUTHORIZATION_URL=https://accounts.google.com/o/oauth2/v2/auth OAUTH2_TOKEN_URL=https://oauth2.googleapis.com/token OAUTH2_USER_INFO_URL=https://www.googleapis.com/oauth2/v2/userinfo OAUTH2_CLIENT_ID=your-google-client-id.apps.googleusercontent.com OAUTH2_CLIENT_SECRET=your-google-client-secret OAUTH2_CALLBACK_URL=http://localhost:3000/auth/callback OAUTH2_SCOPE=openid email profile ``` For **GitHub**: ```env OAUTH2_AUTHORIZATION_URL=https://github.com/login/oauth/authorize OAUTH2_TOKEN_URL=https://github.com/login/oauth/access_token OAUTH2_USER_INFO_URL=https://api.github.com/user OAUTH2_CLIENT_ID=your-github-client-id OAUTH2_CLIENT_SECRET=your-github-client-secret OAUTH2_CALLBACK_URL=http://localhost:3000/auth/callback OAUTH2_SCOPE=user:email ``` 3. **User Allowlist** (required): ```env ALLOWED_EMAILS=user1@example.com,user2@example.com,admin@company.com ``` #### Step 2: Set Up OAuth2 Provider Create OAuth2 credentials with your provider: - **Google**: [Google Cloud Console](https://console.cloud.google.com/apis/credentials) - **GitHub**: [GitHub Developer Settings](https://github.com/settings/developers) Set the **Authorized redirect URI** to: `http://localhost:3000/auth/callback` #### Step 3: Authentication Flow 1. Visit `http://localhost:3000/auth/login` 2. Redirected to OAuth2 provider (Google/GitHub/etc.) 3. Sign in and authorize 4. Redirected back with JWT token displayed on screen 5. Copy the token and use it in API requests: ```bash curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3000/timezones/regions ``` ### Running the Server This project provides **three interfaces** that can run independently: #### Option 1: MCP Server via stdio (for local LLM clients) ```bash # Development mode with hot reload pnpm mcp:dev # Production mode pnpm build pnpm mcp:start ``` Uses **stdio transport** - launches as a subprocess. Perfect for Claude Desktop config file. #### Option 2: MCP Server via HTTP (for remote LLM clients) ```bash # Development mode with hot reload pnpm mcp:http:dev # Production mode pnpm build pnpm mcp:http ``` Uses **Streamable HTTP over HTTP** - accessible at `http://localhost:3001/mcp` Perfect for Claude Desktop's "Add Custom Connector" UI! 🎯 #### Option 3: REST API Server (for HTTP clients) ```bash # Development mode with hot reload pnpm dev # Production mode pnpm build pnpm start:prod # Open Swagger UI in browser pnpm swagger ``` The REST API will start on [http://localhost:3000](http://localhost:3000) Interactive Swagger/OpenAPI documentation is available at [http://localhost:3000/api](http://localhost:3000/api) ### Available Endpoints **Authentication:** - `GET /auth/login` - Initiate OAuth2 login (redirects to provider) - `GET /auth/callback` - OAuth2 callback (returns JWT token) **Health:** - `GET /health` - Health check endpoint (public, no authentication required) ```json { "status": "ok", "timestamp": "2025-10-17T18:30:45.123Z" } ``` **Timezone API:** (requires authentication - include `Authorization: Bearer TOKEN` header) - `GET /timezones/regions` - Get all available timezone regions ```json { "regions": [ "Africa", "America", "Antarctica", "Asia", "Atlantic", "Australia", "Europe", "Indian", "Pacific" ], "count": 15 } ``` - `GET /timezones/regions/:region/cities` - Get all cities in a specific region ```json { "region": "America", "cities": ["New_York", "Los_Angeles", "Chicago", "Denver", "Phoenix"], "count": 150 } ``` - `GET /timezones/:region/:city` - Get current time in a specific timezone ```json { "timezone": "America/New_York", "datetime_local": "2025-10-17T13:47:23-04:00", "datetime_utc": "2025-10-17T17:47:23.345Z", "timezone_offset": "-04:00", "timestamp": 1760723243345 } ``` ## MCP Protocol Integration ### What is MCP? [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standardized protocol that allows LLMs to discover and use tools automatically. Instead of manually telling an LLM about your API endpoints, MCP-enabled clients like Claude Desktop can: 1. **Auto-discover** available tools via `tools/list` 2. **Inspect schemas** to understand input parameters 3. **Execute tools** via JSON-RPC `tools/call` requests ### Testing with MCP Inspector (Quickest) The MCP Inspector is a web UI for testing your MCP server without needing Claude Desktop: ```bash pnpm install pnpm build pnpm mcp:inspector ``` This opens `http://localhost:5173` where you can: - See all 3 tools listed - Inspect tool schemas and parameters - Execute tools and see JSON responses - Debug without installing anything else ### Setting Up with Claude Desktop #### Method 1: Local stdio Connection (Recommended) 1. Build the project: ```bash pnpm install pnpm build ``` 2. Edit Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { "mcpServers": { "timezone": { "command": "node", "args": ["/absolute/path/to/demo-mcp/dist/main.js"] } } } ``` 3. Restart Claude Desktop 4. Claude can now auto-discover and use the timezone tools! ### Available MCP Tools | Tool | Parameters | Description | | ------------------- | ----------------------------------- | -------------------------------------- | | `get_regions` | None | Get list of all timezone regions | | `get_cities` | `region: string` | Get cities in a specific region | | `get_timezone_info` | `region: string`<br/>`city: string` | Get current time with ISO 8601 formats | ### Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Timezone MCP Server β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ REST API MCP (HTTP/SSE) MCP (stdio) β”‚ β”‚ Port 3000 Port 3001 subprocess β”‚ β”‚ ↓ ↓ ↓ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚NestJS β”‚ β”‚ MCP β”‚ β”‚ MCP β”‚ β”‚ β”‚ β”‚ HTTP β”‚ β”‚ HTTP β”‚ β”‚ stdio β”‚ β”‚ β”‚ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ ↓ β”‚ β”‚ TimezoneService β”‚ β”‚ (Shared Business Logic) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` All three interfaces use the same `TimezoneService`, ensuring consistent behavior across REST API, remote MCP, and local MCP connections. ## Testing ```bash # Run all tests (includes MCP stdio e2e tests) pnpm test # Run tests in watch mode pnpm test:watch # Run tests with coverage pnpm test:cov # Run tests with UI pnpm test:ui # Run e2e tests only pnpm test:e2e ``` **Test Coverage**: 103/109 tests passing (94.5%). The HTTP MCP transport has comprehensive manual testing via MCP Inspector but automated e2e tests are pending due to SSE timing complexity. **Manual Testing HTTP MCP Server:** ```bash # Start HTTP MCP server pnpm mcp:http:dev # Test with MCP Inspector pnpm mcp:inspector # Test with Claude Desktop # Settings > Connectors > Add Custom Connector # URL: http://localhost:3001/mcp ``` ## Code Quality ```bash # Lint code pnpm lint # Fix lint issues pnpm lint:fix # Format code pnpm format # Check formatting pnpm format:check ``` ## Documentation Additional guides and documentation are available in the [`docs/`](docs/) directory: - **[Local Testing Guide](docs/LOCAL_TESTING.md)** - Step-by-step instructions for testing with MCP Inspector - **[Deployment Guide](docs/DEPLOYMENT.md)** - Deploy to Google Cloud Run - **[Deployment Success Guide](docs/DEPLOYMENT_SUCCESS.md)** - Post-deployment verification ## Scripts Reference ### Server Scripts - `pnpm dev` - Start REST API server in development mode - `pnpm start` - Start REST API server - `pnpm start:prod` - Start REST API server in production mode - `pnpm mcp:dev` - Start MCP server (stdio) in development mode - `pnpm mcp:start` - Start MCP server (stdio) in production mode - `pnpm mcp:http:dev` - Start MCP server (HTTP/SSE) in development mode - `pnpm mcp:http` - Start MCP server (HTTP/SSE) in production mode - `pnpm mcp:inspector` - Start MCP Inspector (debug/test MCP tools in browser) - `pnpm swagger` - Open Swagger UI in default browser ### Build & Test - `pnpm build` - Build the project (compiles TypeScript to dist/) - `pnpm test` - Run all tests (84 tests including MCP e2e) - `pnpm test:watch` - Run tests in watch mode - `pnpm test:cov` - Run tests with coverage report (100% coverage) - `pnpm test:ui` - Run tests with Vitest UI - `pnpm test:e2e` - Run end-to-end tests only ### Code Quality - `pnpm lint` - Lint code with ESLint - `pnpm lint:fix` - Fix linting issues automatically - `pnpm format` - Format code with Prettier - `pnpm format:check` - Check if code is properly formatted - `deps:check` - Check if dependencies can be upgraded (minor/patch only) - `deps:update` - Upgrade dependencies (minor/patch only)

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/sam-artuso/demo-mcp'

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