A sample MCP server with human-approved, provider-scoped access to third-party APIs using WorkOS Pipes.
概览
A starter template for building an MCP server with human-approved, provider-scoped access to third-party APIs using WorkOS Pipes. It shows one way to let AI assistants securely interact with services like Linear, Notion, Snowflake, and more with a human in the loop, without trying to prescribe the full deployment story or how approval requests should be delivered. - — AI assistants request access, humans approve via a browser-based consent screen - — humans select exactly which integrations to authorize (not all-or-nothing) - — broad and per-request approvals share one AuthorityGrant model - — authority expires after 5 minutes, configurable - — read and write operations are gated separately - — assistants poll for results and receive user instructions Broad authority and per-request approval now use the same underlying grant record: - kind: "broad" grants temporary session authority for selected providers - kind: "request" approves one exact API call and is consumed on...
README
Pipes MCP Template
A starter template for building an MCP server with human-approved, provider-scoped access to third-party APIs using WorkOS Pipes. It shows one way to let AI assistants securely interact with services like Linear, Notion, Snowflake, and more with a human in the loop, without trying to prescribe the full deployment story or how approval requests should be delivered.
What’s included
- Human-in-the-loop approval flow — AI assistants request access, humans approve via a browser-based consent screen
- Provider-scoped authority — humans select exactly which integrations to authorize (not all-or-nothing)
- Unified authority grants — broad and per-request approvals share one
AuthorityGrantmodel - Time-limited sessions — authority expires after 5 minutes, configurable
- Read/write gating — read and write operations are gated separately
- Approval polling — assistants poll for results and receive user instructions
The approval flow
sequenceDiagram
participant AI as AI Assistant
participant Server as This Server
participant Human as Human
AI->>Server: request_elevated_access(reason, providers)
Server-->>AI: approval URL + request ID
AI->>Human: "Open this URL"
Human->>Server: select providers
Human->>Server: add notes (optional)
Human->>Server: approve / deny
AI->>Server: check_access_request
Server-->>AI: approved + providers
Server-->>AI: user instructions
AI->>Server: call_integration_api
Server-->>AI: API response
Broad authority and per-request approval now use the same underlying grant record:
kind: "broad"grants temporary session authority for selected providerskind: "request"approves one exact API call and is consumed on execution
Authorization structure
Every MCP request is authenticated first, then authorized from the current Pipes session and grant state:
app/[transport]/route.tsrequires AuthKit authentication for every MCP request.lib/mcp/with-authkit.tsverifies the bearer token, loads the WorkOS user, and loads or creates a Redis-backedPipesSessionkeyed bysid + organizationId.- Effective MCP scopes are derived from the session’s current broad authority, not directly from JWT claims.
request_elevated_accesscreates pendingAuthorityGrantrecords:- broad grants request temporary
readorwriteauthority for selected providers - request grants store the exact
url,method, and optionalbodyfor one API call
- broad grants request temporary
- The approval UI resolves that grant:
- approved broad grants become
session.activeGrant - approved request grants stay in Redis as single-use approved grants
- approved broad grants become
call_integration_apienforces access by either:- checking the active broad grant for read/write level and provider access
- or consuming a matching approved request grant bound to the same
sid,userId, andorganizationId
Quick start
Prerequisites
1. Install dependencies
pnpm install
2. Start Redis
Redis is required for session and approval state storage.
# macOS (Homebrew)
brew install redis
brew services start redis
# Docker
docker run -d -p 6379:6379 redis
# Or run directly
redis-server
Verify it’s running:
redis-cli ping
# PONG
3. Configure environment
cp .env.local.example .env.local
Fill in your values:
WORKOS_API_KEY=sk_test_...
WORKOS_CLIENT_ID=client_...
WORKOS_COOKIE_PASSWORD=
WORKOS_REDIRECT_URI=http://localhost:5711/callback
AUTHKIT_DOMAIN=auth.workos.com
REDIS_URL=redis://127.0.0.1:6379
Optional tuning:
SESSION_TTL_MS=604800000 # Session store TTL (default: 7 days)
SESSION_AUTHORITY_TTL_MS=300000 # Authority expiry (default: 5 minutes)
4. Start the dev server
pnpm dev
The server starts at http://localhost:5711.
Connecting an MCP client
Point your MCP client (Claude Code, Claude Desktop, Cursor, etc.) at the server URL. The server uses Streamable HTTP transport at http://localhost:5711/mcp.
Adding a new provider
- Add a new provider module in
lib/mcp/providers/that exports aProviderDefinition - Implement
matchesUrl,buildHeaders, and, if needed,isWriteOperationfor provider-specific write detection - Register the provider in
lib/mcp/providers/index.ts - Update
lib/mcp/token-injection.tsonly if the provider needs auth behavior beyond the default Bearer token injection - Configure the integration in your WorkOS dashboard
The call_integration_api tool auto-detects the provider from the API URL domain and injects the correct authentication headers.
Redis keys
| Key pattern | Data | TTL |
|---|---|---|
pipes:mcp:session:{sid}:{orgId} |
Stored session record with active broad, pending broad, and active request grant IDs | Default 7 days; may be deleted earlier if idle |
pipes:mcp:authority-grant:{id} |
Unified broad/request grant record in pending, approved, or denied state |
Up to 5 min; preserved as remaining grant lifetime after resolution |
pipes:mcp:approval-token:{jti} |
One-time approval-token consumption guard (not the encrypted token itself) | Remaining approval-token lifetime, up to 5 min |
Development
pnpm dev # Start dev server (Turbopack)
pnpm typecheck # Type check
pnpm lint # Lint (Biome)
pnpm format # Format (Biome)
Contributing
See CONTRIBUTING.md for guidelines on how to contribute to this project.
License
MIT License. See LICENSE for details.
安装
docker run -d -p 6379:6379 redis