# Pinpole MCP parity matrix Every user-triggered Pinpole API action (excluding OAuth callbacks, webhooks, cron, telemetry ingest, and pure browser flows) has a matching `pinpole_*` MCP tool or `pinpole_open_*` link tool. `npm run test:parity` enforces that every **MCP tool** row below is registered. | API route | MCP tool | Status | |-----------|----------|--------| | `POST /api/ai-architect` (build) | `pinpole_build_architecture` | MCP_TOOL | | `POST /api/projects` + workspace | `pinpole_create_architecture` | MCP_TOOL | | `POST /api/simulation/run` (cost) | `pinpole_simulate_cost` | MCP_TOOL | | `PATCH .../workspaces/[id]` (graph) | `pinpole_draw_on_canvas` | MCP_TOOL | | — (link) | `pinpole_open_canvas` | MCP_TOOL | | `GET /api/projects` | `pinpole_list_projects` | MCP_TOOL | | `POST /api/projects` | `pinpole_create_project` | MCP_TOOL | | `GET /api/projects/[id]` | `pinpole_get_project` | MCP_TOOL | | `PATCH /api/projects/[id]` | `pinpole_update_project` | MCP_TOOL | | `DELETE /api/projects/[id]` | `pinpole_delete_project` | MCP_TOOL | | `GET .../workspaces/[id]` | `pinpole_get_workspace` | MCP_TOOL | | `GET .../workspaces` | `pinpole_list_workspaces` | MCP_TOOL | | `POST .../workspaces` | `pinpole_create_workspace` | MCP_TOOL | | `PATCH .../workspaces/[id]` | `pinpole_update_workspace` | MCP_TOOL | | `DELETE .../workspaces/[id]` | `pinpole_delete_workspace` | MCP_TOOL | | offline bundle | `pinpole_export_terraform` | MCP_TOOL | | service-config JSON | `pinpole_list_services` | MCP_TOOL | | service-config JSON | `pinpole_get_service_spec` | MCP_TOOL | | `POST /api/ai-architect/chat` | `pinpole_ai_chat` | MCP_TOOL | | `POST /api/ai-architect/vision` | `pinpole_ai_vision` | MCP_TOOL | | `POST /api/recommend-connection` | `pinpole_recommend_connection` | MCP_TOOL | | `POST /api/simulation/recommendations` | `pinpole_simulation_recommendations` | MCP_TOOL | | `POST /api/simulation/run` | `pinpole_run_simulation` | MCP_TOOL | | `GET /api/simulation/[id]` | `pinpole_get_simulation` | MCP_TOOL | | `GET /api/simulation/executions` | `pinpole_list_simulations` | MCP_TOOL | | `GET /api/deploy/deployments` | `pinpole_list_deployments` | MCP_TOOL | | `GET /api/deploy/status` | `pinpole_get_deploy_status` | MCP_TOOL | | `GET /api/deploy/latest` | `pinpole_get_deploy_latest` | MCP_TOOL | | `GET /api/deploy/drift` | `pinpole_get_drift` | MCP_TOOL | | `GET /api/deploy/resource-info` | `pinpole_get_resource_info` | MCP_TOOL | | `POST /api/deploy/execute` | `pinpole_deploy_execute` | MCP_TOOL | | `POST /api/deploy/apply-changes` | `pinpole_deploy_apply_changes` | MCP_TOOL | | `POST /api/deploy/cancel` | `pinpole_deploy_cancel` | MCP_TOOL | | `POST /api/canvas/sync` | `pinpole_canvas_sync` | MCP_TOOL | | `POST /api/deploy/connect` | `pinpole_start_aws_connect` | MCP_TOOL | | `GET /api/deploy/gcp/oauth/start` | `pinpole_start_gcp_connect` | MCP_TOOL | | `POST /api/deploy/cloudflare/connect` | `pinpole_start_cloudflare_connect` | MCP_TOOL | | `POST /api/deploy/gcp/execute` | `pinpole_deploy_gcp_execute` | MCP_TOOL | | `GET /api/deploy/gcp/drift` | `pinpole_get_gcp_drift` | MCP_TOOL | | `GET /api/templates` | `pinpole_list_templates` | MCP_TOOL | | `GET /api/templates/[id]` | `pinpole_get_template` | MCP_TOOL | | `POST /api/templates/[id]/apply` | `pinpole_apply_template` | MCP_TOOL | | `POST /api/templates/[id]/clone` | `pinpole_clone_template` | MCP_TOOL | | `POST /api/templates/[id]/rollback` | `pinpole_rollback_template` | MCP_TOOL | | `POST /api/templates/from-image` | `pinpole_create_template_from_image` | MCP_TOOL | | `GET /api/teams` | `pinpole_list_teams` | MCP_TOOL | | `GET /api/teams/[id]` | `pinpole_get_team` | MCP_TOOL | | `GET /api/teams/[id]/members` | `pinpole_list_team_members` | MCP_TOOL | | `GET /api/teams/[id]/invites` | `pinpole_list_team_invites` | MCP_TOOL | | `POST /api/teams/[id]/invites` | `pinpole_create_team_invite` | MCP_TOOL | | `GET /api/teams/[id]/projects` | `pinpole_list_team_projects` | MCP_TOOL | | `POST /api/teams/[id]/projects` | `pinpole_create_team_project` | MCP_TOOL | | `GET /api/accounts` | `pinpole_list_accounts` | MCP_TOOL | | `GET /api/connectors` | `pinpole_list_connectors` | MCP_TOOL | | `GET /api/connectors/github/repos` | `pinpole_github_repos` | MCP_TOOL | | `GET /api/connectors/github/lambda-functions` | `pinpole_github_lambda_functions` | MCP_TOOL | | `GET /api/connectors/github/start` | `pinpole_start_github_connect` | MCP_TOOL | | `GET /api/auth/me` | `pinpole_get_me` | MCP_TOOL | | `GET /api/settings/api-tokens` | `pinpole_list_api_tokens` | MCP_TOOL | | `POST /api/settings/api-tokens` | `pinpole_create_api_token` | MCP_TOOL | | `DELETE /api/settings/api-tokens/[id]` | `pinpole_revoke_api_token` | MCP_TOOL | | `GET /api/subscription` | `pinpole_get_subscription` | MCP_TOOL | | `GET /api/usage` | `pinpole_get_usage` | MCP_TOOL | | `POST /api/stripe/portal` | `pinpole_open_billing_portal` | MCP_TOOL | | `POST /api/export/terraform` | `pinpole_export_terraform_server` | MCP_TOOL | | `POST /api/export/gif/share` | `pinpole_export_gif_share` | MCP_TOOL | | `GET /api/notifications` | `pinpole_list_notifications` | MCP_TOOL | ## Browser-only (no MCP tool) | Flow | Status | |------|--------| | Login / signup / password reset | BROWSER_ONLY | | MFA enrollment & challenge | BROWSER_ONLY | | OAuth provider callbacks | BROWSER_ONLY | | Stripe checkout | BROWSER_ONLY (use `pinpole_open_billing_portal`) | | Interactive canvas drag-and-drop | BROWSER_ONLY (use graph PATCH tools) | | Cron, webhooks, telemetry ingest | BROWSER_ONLY | | Admin impersonation | BROWSER_ONLY | ## Auth MCP calls Pinpole APIs with `Authorization: Bearer pp_live_…` (personal access token) or OAuth access token (`pp_mcp_…`). Local dev may use `PINPOLE_DEV_USER_ID` + `ALLOW_DEV_USER_HEADER=1` on the Pinpole app.