Skip to main content
Glama
sohnithakkar

Auth0 MCP Server Demo — CRM

by sohnithakkar
README.md
# Auth0 MCP Server Demo — CRM

A demo showing how to secure an MCP server with Auth0 using:

- **FastMCP Auth0Provider** — OIDC proxy so any MCP client (Claude Desktop, MCP Inspector) gets a standard browser-based OAuth login without manual token handling
- **Role-Based Access Control** — `sales-rep` (read-only) vs `sales-manager` (full access)
- **On-Behalf-Of Token Exchange** — MCP server exchanges the user's token for a CRM API-scoped token, proving the agent acts with delegated user identity

```
MCP Client → FastMCP (OIDC proxy) → Auth0 Universal Login
                  ↓
         JWT validated, permissions checked
                  ↓
         OBO exchange → CRM API token
                  ↓
         Tool result + delegation proof
```

## Architecture

| Package | Port | Stack | Purpose |
|---------|------|-------|---------|
| `packages/mcp-server` | 3010 | Python + FastMCP | MCP server with Auth0 OAuth proxy + OBO |
| `packages/crm-api` | 3011 | Node.js + Express | Mock CRM REST API (downstream service) |

## Auth Flow

1. MCP client connects to `http://localhost:3010/mcp`
2. FastMCP redirects to Auth0 Universal Login
3. User authenticates — FastMCP validates the token and extracts `permissions`
4. On each tool call, the MCP server performs **RFC 8693 Token Exchange** to get a CRM-scoped token
5. Every tool response includes a `delegation` block proving who the agent is acting as

## Demo Roles

| Role | Permissions | Can Do |
|------|------------|--------|
| `sales-rep` | `crm:read` | List/view contacts and deals |
| `sales-manager` | `crm:read` + `crm:write` | Full CRUD |

## Prerequisites

- Node.js 20+
- Python 3.11+
- An Auth0 tenant
- AWS CLI (for CIMD hosting on S3/CloudFront)

## Setup

### 1. Install dependencies

```bash
npm install
pip3 install -r packages/mcp-server/requirements.txt
```

### 2. Host the CIMD document

The CIMD document proves domain ownership when registering the MCP server with Auth0:

```bash
npm run deploy:cimd    # provisions S3 + CloudFront + Route53 at mcp.authgatekeeper.com
```

### 3. Configure Auth0

```bash
# Get a Management API token from:
# Auth0 Dashboard → Applications → APIs → Auth0 Management API → API Explorer

AUTH0_MANAGEMENT_TOKEN=<token> npm run setup:auth0
```

Copy the printed values into your root `.env`.

### 4. Configure OBO token exchange

```bash
# After creating the Custom API client in Auth0:
AUTH0_MANAGEMENT_TOKEN=<token> npx tsx scripts/setup-obo.ts
```

### 5. Start

```bash
npm run dev
```

## Testing

### MCP Inspector

```bash
npx @modelcontextprotocol/inspector
```

Connect to `http://localhost:3010/mcp` — FastMCP handles the Auth0 login automatically.

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "crm": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:3010/mcp"]
    }
  }
}
```

## Available Tools

| Tool | Permission | Description |
|------|-----------|-------------|
| `whoami` | any | Show identity + full delegation chain |
| `list_contacts` | `crm:read` | List contacts, filter by status |
| `get_contact` | `crm:read` | Get contact by ID |
| `create_contact` | `crm:write` | Create a new contact |
| `list_deals` | `crm:read` | List deals, filter by stage or contact |
| `get_deal` | `crm:read` | Get deal by ID |
| `create_deal` | `crm:write` | Create a new deal |

## Test Users

| Email | Password | Role |
|-------|----------|------|
| `sarah.rep@demo.com` | `DemoPass1!` | sales-rep (`crm:read`) |
| `mike.manager@demo.com` | `DemoPass1!` | sales-manager (`crm:read` + `crm:write`) |

## Scripts

| Script | Purpose |
|--------|---------|
| `npm run setup:auth0` | Provision Auth0 tenant (APIs, apps, roles, users) |
| `npm run deploy:cimd` | Deploy CIMD document to S3/CloudFront |
| `npm run update:cimd` | Re-upload CIMD document after changes |
| `npx tsx scripts/setup-obo.ts` | Configure OBO token exchange client |
| `npx tsx scripts/fix-permissions.ts` | Re-assign role permissions (run after audience change) |

## Project Structure

```
mcp-server-auth/
├── packages/
│   ├── mcp-server/
│   │   ├── server.py          # FastMCP server — tools + Auth0 OIDC proxy + OBO
│   │   └── requirements.txt
│   └── crm-api/
│       └── src/
│           ├── index.ts       # Express API with JWT validation
│           └── data.ts        # In-memory contacts and deals
├── scripts/
│   ├── setup.ts               # Auth0 tenant provisioning
│   ├── setup-obo.ts           # OBO client configuration
│   ├── fix-permissions.ts     # Role permission repair utility
│   └── deploy-cimd.sh         # AWS S3/CloudFront/Route53 deployment
└── .env.example
```