{"id":50999047,"url":"https://github.com/workos/pipes-mcp","last_synced_at":"2026-06-20T12:34:28.163Z","repository":{"id":345576547,"uuid":"1180156748","full_name":"workos/pipes-mcp","owner":"workos","description":"A sample MCP server with human-approved, provider-scoped access to third-party APIs using WorkOS Pipes.","archived":false,"fork":false,"pushed_at":"2026-04-28T18:34:51.000Z","size":175,"stargazers_count":22,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-28T20:29:05.017Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://workos.com/docs/pipes","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/workos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-12T18:58:11.000Z","updated_at":"2026-04-28T18:32:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/workos/pipes-mcp","commit_stats":null,"previous_names":["workos/pipes-mcp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/workos/pipes-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fpipes-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fpipes-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fpipes-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fpipes-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/workos","download_url":"https://codeload.github.com/workos/pipes-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fpipes-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34570538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T12:34:26.034Z","updated_at":"2026-06-20T12:34:28.156Z","avatar_url":"https://github.com/workos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pipes MCP Template\n\nA starter template for building an MCP server with human-approved, provider-scoped access to third-party APIs using [WorkOS Pipes](https://workos.com/docs/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.\n\n## What's included\n\n- **Human-in-the-loop approval flow** — AI assistants request access, humans approve via a browser-based consent screen\n- **Provider-scoped authority** — humans select exactly which integrations to authorize (not all-or-nothing)\n- **Unified authority grants** — broad and per-request approvals share one `AuthorityGrant` model\n- **Time-limited sessions** — authority expires after 5 minutes, configurable\n- **Read/write gating** — read and write operations are gated separately\n- **Approval polling** — assistants poll for results and receive user instructions\n\n## The approval flow\n\n```mermaid\nsequenceDiagram\n       participant AI as AI Assistant\n       participant Server as This Server\n       participant Human as Human\n\n       AI-\u003e\u003eServer: request_elevated_access\u003cbr\u003e(reason, providers)\n       Server--\u003e\u003eAI: approval URL + request ID\n\n       AI-\u003e\u003eHuman: \"Open this URL\"\n\n       Human-\u003e\u003eServer: select providers\n       Human-\u003e\u003eServer: add notes (optional)\n       Human-\u003e\u003eServer: approve / deny\n\n       AI-\u003e\u003eServer: check_access_request\n       Server--\u003e\u003eAI: approved + providers\n       Server--\u003e\u003eAI: user instructions\n\n       AI-\u003e\u003eServer: call_integration_api\n       Server--\u003e\u003eAI: API response\n```\n\nBroad authority and per-request approval now use the same underlying grant record:\n\n- `kind: \"broad\"` grants temporary session authority for selected providers\n- `kind: \"request\"` approves one exact API call and is consumed on execution\n\n## Authorization structure\n\nEvery MCP request is authenticated first, then authorized from the current Pipes session and grant state:\n\n1. `app/[transport]/route.ts` requires AuthKit authentication for every MCP request.\n2. `lib/mcp/with-authkit.ts` verifies the bearer token, loads the WorkOS user, and loads or creates a Redis-backed `PipesSession` keyed by `sid + organizationId`.\n3. Effective MCP scopes are derived from the session's current broad authority, not directly from JWT claims.\n4. `request_elevated_access` creates pending `AuthorityGrant` records:\n   - broad grants request temporary `read` or `write` authority for selected providers\n   - request grants store the exact `url`, `method`, and optional `body` for one API call\n5. The approval UI resolves that grant:\n   - approved broad grants become `session.activeGrant`\n   - approved request grants stay in Redis as single-use approved grants\n6. `call_integration_api` enforces access by either:\n   - checking the active broad grant for read/write level and provider access\n   - or consuming a matching approved request grant bound to the same `sid`, `userId`, and `organizationId`\n\n## Quick start\n\n### Prerequisites\n\n- Node.js 20+\n- [pnpm](https://pnpm.io/)\n- Redis\n- A [WorkOS](https://workos.com) account with AuthKit and Pipes configured\n\n### 1. Install dependencies\n\n```bash\npnpm install\n```\n\n### 2. Start Redis\n\nRedis is required for session and approval state storage.\n\n```bash\n# macOS (Homebrew)\nbrew install redis\nbrew services start redis\n\n# Docker\ndocker run -d -p 6379:6379 redis\n\n# Or run directly\nredis-server\n```\n\nVerify it's running:\n\n```bash\nredis-cli ping\n# PONG\n```\n\n### 3. Configure environment\n\n```bash\ncp .env.local.example .env.local\n```\n\nFill in your values:\n\n```bash\nWORKOS_API_KEY=sk_test_...\nWORKOS_CLIENT_ID=client_...\nWORKOS_COOKIE_PASSWORD=\u003cgenerate with: openssl rand -base64 32\u003e\nWORKOS_REDIRECT_URI=http://localhost:5711/callback\nAUTHKIT_DOMAIN=auth.workos.com\nREDIS_URL=redis://127.0.0.1:6379\n```\n\nOptional tuning:\n\n```bash\nSESSION_TTL_MS=604800000          # Session store TTL (default: 7 days)\nSESSION_AUTHORITY_TTL_MS=300000   # Authority expiry (default: 5 minutes)\n```\n\n### 4. Start the dev server\n\n```bash\npnpm dev\n```\n\nThe server starts at `http://localhost:5711`.\n\n## Connecting an MCP client\n\nPoint your MCP client (Claude Code, Claude Desktop, Cursor, etc.) at the server URL. The server uses Streamable HTTP transport at `http://localhost:5711/mcp`.\n\n## Adding a new provider\n\n1. Add a new provider module in `lib/mcp/providers/` that exports a `ProviderDefinition`\n2. Implement `matchesUrl`, `buildHeaders`, and, if needed, `isWriteOperation` for provider-specific write detection\n3. Register the provider in `lib/mcp/providers/index.ts`\n4. Update `lib/mcp/token-injection.ts` only if the provider needs auth behavior beyond the default Bearer token injection\n5. Configure the integration in your WorkOS dashboard\n\nThe `call_integration_api` tool auto-detects the provider from the API URL domain and injects the correct authentication headers.\n\n## Redis keys\n\n| Key pattern | Data | TTL |\n|-------------|------|-----|\n| `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 |\n| `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 |\n| `pipes:mcp:approval-token:{jti}` | One-time approval-token consumption guard (not the encrypted token itself) | Remaining approval-token lifetime, up to 5 min |\n\n## Development\n\n```bash\npnpm dev          # Start dev server (Turbopack)\npnpm typecheck    # Type check\npnpm lint         # Lint (Biome)\npnpm format       # Format (Biome)\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to contribute to this project.\n\n## License\n\nMIT License. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fpipes-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fworkos%2Fpipes-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fpipes-mcp/lists"}