Skip to main content
Glama
keycardai

Keycard Hello MCP Server

Official
by keycardai
README.md
# πŸ” Keycard Hello MCP Server

A **production-ready MCP server** demonstrating OAuth 2.0 authentication with Keycard's Security Token Service (STS). This project showcases best practices for building secure, type-safe, and modular MCP servers with enterprise-grade observability.

[![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue)](https://typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-18+-green)](https://nodejs.org/)
[![MCP Protocol](https://img.shields.io/badge/MCP-2024--11--05-purple)](https://modelcontextprotocol.io/)
[![OAuth 2.0](https://img.shields.io/badge/OAuth-2.0-orange)](https://oauth.net/2/)

## 🎯 What This Demonstrates

- **πŸ”’ OAuth 2.0 Authentication** - Secure authentication via Keycard STS
- **✨ Type Safety** - Full TypeScript with Zod runtime validation
- **πŸ—οΈ Modular Architecture** - Clean separation of concerns for easy extension
- **πŸš€ Production Ready** - Error handling, validation, and comprehensive logging
- **πŸ“š Educational** - Well-documented code showing MCP best practices
- **πŸ§ͺ Testing Framework** - Jest with coverage, integration tests, and watch modes
- **πŸ“Š Observability** - OpenTelemetry integration with traces and metrics

## πŸš€ Quick Start

## πŸ—οΈ Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Cursor    │───▢│  MCP Server  │───▢│ Keycard STS β”‚
β”‚    IDE      β”‚    β”‚ (localhost:  β”‚    β”‚             β”‚
β”‚             β”‚    β”‚     8888)    β”‚    β”‚             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                   β”‚                   β”‚
   OAuth Flow          JWT Validation      Token Issuance
```

### πŸ”„ Authentication Flow

1. **Cursor** discovers OAuth endpoints from MCP server
2. **User** authenticates via Keycard STS (redirected to identity provider)
3. **Keycard STS** issues JWT access tokens
4. **MCP Server** validates tokens and grants access to tools

### Prerequisites

- **Node.js 18+** and **npm**
- **Cursor IDE** (or any MCP-compatible client)
- **Keycard account** with access to the Console
- **Configured Keycard zone** (for authentication)

### 1. Clone & Install

```bash
git clone https://github.com/keycardai/hello-mcp-server.git
cd hello-mcp-server
npm install
```

### 2. Configure Environment

Create a `.env` file:

```bash
# Required: Your Keycard STS issuer URL
KEYCARD_STS_ISSUER_URL=https://your-zone-id.keycard.cloud

# Optional: Server configuration
PORT=8888
HOST=localhost
```

πŸ’‘ **Finding your Zone ID**: 
1. Log into the [Keycard Console](https://console.keycard.ai)
2. Navigate to **Zone Settings** 
3. Copy the **Zone ID** (e.g., `j434uokph8th1ia1npxiaykh7p`)
4. Replace `your-zone-id` in your STS URL

> **Note**: Use the zone ID, not the zone name or label.

### 3. Start the Server

```bash
# Development mode with auto-reload
npm run dev

# Production mode
npm run build && npm start
```

You should see:
```
πŸš€ Keycard Hello MCP Server started!
πŸ”— MCP Endpoint: http://localhost:8888/mcp
πŸ” STS Issuer: https://your-zone-id.keycard.cloud
πŸ› οΈ  Available Tools: keycard-logo, whoami
```

### 4. Configure Cursor IDE

Add to your Cursor MCP settings:

```json
{
  "mcpServers": {
    "keycard-hello-mcp": {
      "url": "http://localhost:8888/mcp"
    }
  }
}
```

### 5. Test Authentication

1. **Restart Cursor** to pick up the new MCP server
2. **Cursor will show "needs login"** for the server
3. **Click to authenticate** β†’ complete OAuth flow
4. **Use the tools**: `keycard-logo`, `whoami`

## πŸ› οΈ Available Tools

### `keycard-logo`
Displays the official Keycard ASCII art logo.

### `whoami`
Provides detailed information about the authenticated user including:
- Client ID and authentication scopes
- JWT payload with user information
- Token expiration and timing details
- Custom claims and metadata

## πŸ”§ Configuration

### Environment Variables

| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `KEYCARD_STS_ISSUER_URL` | Keycard STS issuer URL (single-tenant mode) | - | βœ…* |
| `ISSUER_BASE_DOMAIN` | Base domain for STS (multi-tenant mode) | - | βœ…* |
| `MCP_BASE_DOMAIN` | Base domain for MCP server (multi-tenant mode) | - | βœ…* |
| `PORT` | Server port | `8888` | |
| `HOST` | Server host | `localhost` | |
| `LOG_LEVEL` | Logging level | `INFO` | |
| `ENABLE_OTEL` | Enable OpenTelemetry | `true` | |
| `OTEL_SERVICE_NAME` | Service name for telemetry | `hello-mcp-server` | |
| `OTEL_ENVIRONMENT` | Environment for telemetry | `development` | |

*Either `KEYCARD_STS_ISSUER_URL` (single-tenant) OR `ISSUER_BASE_DOMAIN` + `MCP_BASE_DOMAIN` (multi-tenant) is required.

### Multi-Tenant Configuration

For multi-tenant deployments (serving multiple organizations/zones), use these environment variables instead:

```bash
# Multi-tenant mode
ISSUER_BASE_DOMAIN=keycard.cloud
MCP_BASE_DOMAIN=mcp.example.com

# Other configuration
PORT=8888
ENABLE_OTEL=true
```

This enables dynamic issuer discovery based on subdomain routing, allowing one deployment to serve multiple Keycard zones.

### Observability

The server includes comprehensive observability features:

- **Structured Logging**: Environment-aware logging with trace correlation
- **Request Tracing**: Full distributed tracing with OpenTelemetry
- **Metrics Collection**: Performance and usage metrics
- **Health Checks**: Available at `/health`

In development, logs are formatted for console readability. In production, logs are sent to configured OTLP endpoints.

## πŸ—οΈ Architecture

```
src/
β”œβ”€β”€ config.ts              # Configuration management
β”œβ”€β”€ index.ts               # Application entry point
β”œβ”€β”€ server.ts              # Express server setup
β”œβ”€β”€ middleware/            # Express middlewares
β”‚   β”œβ”€β”€ auth.ts           # Authentication middleware
β”‚   └── logging.ts        # Request logging and tracing
β”œβ”€β”€ observability/         # Telemetry and logging
β”‚   β”œβ”€β”€ logger.ts         # Structured logger
β”‚   └── telemetry.ts      # OpenTelemetry setup
β”œβ”€β”€ tools/                 # MCP tools
β”‚   β”œβ”€β”€ index.ts          # Tool registration
β”‚   β”œβ”€β”€ logo.ts           # Keycard logo tool
β”‚   └── whoami.ts         # User information tool
└── types/                 # Type definitions
    β”œβ”€β”€ auth.ts           # Authentication types
    └── index.ts          # Exported types
```

## πŸ§ͺ Testing

```bash
# Run all tests
npm test

# Run tests with coverage
npm run test:coverage

# Run integration tests
npm run test:integration

# Watch mode for development
npm run test:watch
```

## πŸ“Š Code Quality

```bash
# Lint code
npm run lint

# Fix linting issues
npm run lint:fix

# Format code
npm run format

# Check all (lint + format)
npm run check

# Fix all issues
npm run check:fix
```

## πŸ”— MCP Integration

### Cursor IDE

1. Start the server: `npm run dev`
2. In Cursor, go to Settings > MCP Servers
3. Add server: `http://localhost:8888/mcp`

## 🚦 Health Checks

The server provides a health check endpoint at `/health`:

```bash
curl http://localhost:8888/health
```

Response:
```json
{
  "status": "healthy",
  "timestamp": "2024-01-01T00:00:00.000Z",
  "service": "hello-mcp-server",
  "version": "1.0.0"
}
```

## 🀝 Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests and quality checks
5. Submit a pull request

## πŸ“„ License

Apache-2.0 License - see LICENSE file for details.