End-to-end flow demonstrating JWT-based authentication for MCP servers.
→ Full technical documentation (DOCUMENTATION.md)
Visualization UI (npm run ui → http://127.0.0.1:4003):
User login → OAuth
↓
Agent receives JWT
↓
JWT passed to MCP server
↓
MCP verifies + extracts roles
↓
Context attached to tool calls
↓
Downstream APIs use scoped tokens
| Component | Port | Role |
|---|---|---|
| auth-service | 4000 | Mock OAuth; issues JWTs with sub, roles, scope |
| mcp-server | 4001 | Verifies JWT, extracts roles, attaches user context to tools |
| downstream-api | 4002 | Validates JWT, returns data based on user roles |
| agent | - | MCP client; connects with JWT, invokes tools |
npm install
npm start # Starts auth, MCP, and downstream API
npm run ui # In another terminal: start UI on http://127.0.0.1:4003
npm run agent # Or run agent CLI (default: alice)For UI + all services: npm run start:full
Or run the full demo:
npm run demo- Login –
POST /loginwithusername/password→ returns JWT - Agent – Connects to MCP with
Authorization: Bearer <jwt> - MCP – Middleware verifies JWT, extracts
sub,roles→req.user - Context –
AsyncLocalStoragepropagates user + token into tool handlers - Tools – Call
getUserContext(); forward JWT to downstream API - Downstream API – Validates JWT, enforces role-based access (reader/admin)
sub– User IDroles– Array, e.g.["admin", "reader"]scope– Space-separated scopes, e.g."data:read data:write"aud– Audience (MCP server URL)
| User | Password | Roles | Downstream /data |
|---|---|---|---|
| alice | pass123 | admin, reader | Full data |
| bob | pass123 | reader | Reader data only |
| charlie | pass123 | (none) | 403 Forbidden |
