Skip to content
firstsun-devPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

anas-mcp

Cloudflare-hosted, read-only Remote MCP service for Firstsun analytics.

Architecture

Mode A: ChatGPT / OAuth client      Mode B: agent / CI / automation
        | Managed OAuth + PKCE                | CF-Access-Client-Id / -Secret
        +------------------+------------------+
                           v
        Cloudflare Access (one application, https://mcp.firstsun.org/anas/mcp)
                           | Cf-Access-Jwt-Assertion
                           v
Cloudflare Worker: anas-mcp
        |
        | validate the Access JWT BEFORE MCP initialization / tool execution
        v
createMcpHandler() --> read-only analytics tools
        |
        |
        +--> Google Analytics Data API
        +--> Google Search Console API
        +--> Hyperdrive --> PostgreSQL --> Clarity analytics
  • HTTP API contract: repository-root openapi.yaml uses OpenAPI 3.2.0 and is intended for Swagger-compatible tooling. It documents the HTTP surface; MCP tools remain MCP-native schemas rather than fake REST endpoints.
  • MCP authentication: production /anas/mcp is protected by one Cloudflare Access application that concurrently accepts Mode A, Managed OAuth (interactive clients such as ChatGPT) and Mode B, Access Service Token (headless agents). The Worker validates Cf-Access-Jwt-Assertion before any MCP/tool/database work. /health stays public and minimal. Cloudflare configuration is owned by firstsun-dev/infra-config.
  • Search Console: direct Search Console API queries with the shared Google OAuth credential and the non-secret GSC_ALLOWED_SITES property allowlist. Tools: gsc_list_sites, gsc_search_analytics (see docs/gsc.md). Fail-closed if GSC_ALLOWED_SITES is missing or malformed; configured identifiers are not yet verified against the Google account.
  • Clarity: read normalized PostgreSQL data populated by firstsun-dev/windmill-flows; this service never calls the Clarity API directly. Tools: clarity_overview, clarity_pages, clarity_acquisition, clarity_page (see docs/clarity.md; needs the CLARITY_PROJECT_KEYS var). health lists enabledSources and plannedSources.
  • GA4: read through the Google Analytics Data API with the shared Google OAuth credential (Secrets Store binding GOOGLE_OAUTH_CREDENTIALS, secret ANAS_PROD_GOOGLE_OAUTH_CREDENTIALS) and the non-secret GA4_PROPERTY_IDS allowlist. Tools: ga4_overview, ga4_pages (groupBy path default / fullUrl), ga4_acquisition, ga4_run_report (see docs/ga4.md). Disabled and fail-closed until both are configured.
  • Credentials: Secrets Store first. Any long-lived secret consumed directly by this Worker should come from Cloudflare Secrets Store whenever supported.
  • Google OAuth: one JSON credential stored in Cloudflare Secrets Store.
  • Database: read-only PostgreSQL access through Cloudflare Hyperdrive; the database password remains managed by Hyperdrive and is not duplicated into Worker secrets.
  • CI/CD: Cloudflare Worker deployment is implemented centrally in firstsun-dev/.github; this repository must use a thin caller for the shared _cf-worker-v2.yml workflow (production-only) rather than duplicating deploy steps.

See:

  • openapi.yaml and docs/api.md for the HTTP/OpenAPI contract
  • docs/mcp-authentication.md and docs/cloudflare-access.md for dual-mode Access authentication, client setup, and rollout
  • docs/gsc.md for the Search Console tools, data caveats and operator checklist
  • docs/clarity.md for the Clarity tools, data semantics and configuration
  • docs/credentials.md for credential ownership/storage policy
  • docs/cicd.md for centralized deployment policy and caller-workflow contract

OpenAPI / Swagger policy

openapi.yaml is the canonical HTTP API description.

Current documented HTTP surface:

GET  /health
POST /anas/mcp

Use Swagger-compatible OpenAPI 3.2 tooling to inspect/render the contract.

Do not represent MCP tools such as clarity_page, future ga4_run_report, or gsc_search_analytics as fake REST routes. Those contracts belong to MCP tool schemas and are discovered through MCP.

Any change to an HTTP route, method, authentication requirement, status code, content type, or stable payload must update openapi.yaml in the same change.

Automated OpenAPI validation is tracked in openspec/changes/adopt-openapi-http-contract/ and must be included in the project check/centralized CI path before being considered complete.

Authentication policy summary

Production /anas/mcp accepts two authentication modes at the same time through one Cloudflare Access application: Mode A, Managed OAuth (authorization code + PKCE) for interactive clients, and Mode B, Access Service Token (CF-Access-Client-Id + CF-Access-Client-Secret) for headless agents. This is not a toggle, fallback chain, or pair of endpoints.

Cloudflare Access owns OAuth and Service Token evaluation. The Worker only verifies the resulting Cf-Access-Jwt-Assertion (signature, issuer, AUD, expiry) and fails closed with a generic 401 (or 503 if its non-secret Access config is missing). Service Tokens identify machines, not users. CLOUDFLARE_API_TOKEN and provider/database/CI credentials are never valid substitutes, credentials are never accepted via query string, and IP allowlisting or User-Agent checks are not authentication. anas-mcp must not add OAuth endpoints, KV, D1, Durable Objects, or PostgreSQL auth tables for MCP client authentication.

Credential policy summary

Use Cloudflare Secrets Store as the production source of truth for application-held secrets such as Google OAuth credentials, API tokens, client secrets, signing keys, and encryption keys.

Do not put production credentials in:

  • Wrangler vars
  • committed configuration
  • .env or .dev.vars
  • source code
  • logs

Do not use wrangler secret when Secrets Store can serve the same production credential unless an accepted OpenSpec change documents why.

Intentional exceptions:

  • MCP client authentication holds no Worker secret: Access OAuth tokens, assertions, and Service Token credentials are Access-managed or client-held. The Worker only has non-secret ACCESS_TEAM_DOMAIN / ACCESS_AUD vars.
  • PostgreSQL credentials stay in the Hyperdrive connection.
  • The Microsoft Clarity API token stays in firstsun-dev/windmill-flows because this service never calls Clarity directly.
  • Derived short-lived Google OAuth access tokens stay in runtime memory only.
  • CI bootstrap credentials such as the Cloudflare deploy token/account ID may use the protected GitHub Actions mechanism required by the organization-managed reusable deployment workflow.

CI/CD policy summary

The deployment implementation belongs to:

firstsun-dev/.github/.github/workflows/_cf-worker-v2.yml

anas-mcp keeps a thin caller (.github/workflows/cicd.yml): deployment_strategy: production-only, uses and tools_ref pinned to the same full commit SHA, push trigger only. See docs/cicd.md for the exact inputs.

Do not copy the shared wrangler versions upload/deploy, rollback, or generic runner logic into this repository.

The project uses pnpm (packageManager pinned, pnpm-lock.yaml committed) to match the central workflow. .github/workflows/cicd.yml calls _cf-worker-v2.yml pinned to a commit SHA (production-only): every branch push runs verification, only main deploys. There is no automatic rollback; post-deploy smoke failures require operator action.

See docs/cicd.md and openspec/changes/adopt-cf-worker-v2-ci/.

Current state

The repository currently contains the MCP foundation and architecture specifications:

  • stateless /anas/mcp endpoint using Cloudflare Agents SDK
  • /health HTTP endpoint
  • MCP health tool
  • OpenAPI 3.2.0 HTTP contract
  • OpenSpec architecture, requirements, design, and implementation tasks
  • Secrets Store first credential policy
  • Cloudflare Access assertion validation for /anas/mcp (Worker validation + local tests implemented; Access application, Managed OAuth, Service Token, and production E2E pending infra-config#59 rollout)
  • centralized firstsun-dev/.github Cloudflare Worker CI/CD decision

Cloudflare Access rollout and E2E (ChatGPT OAuth, Service Token, concurrent use), datasource integrations, deployment caller, automated OpenAPI validation, and end-to-end ChatGPT authentication are not considered verified until actually tested.

Development

pnpm install
pnpm run dev

Health endpoint:

http://localhost:8787/health

MCP endpoint:

http://localhost:8787/anas

Test MCP locally with:

pnpm dlx @modelcontextprotocol/inspector@latest

Locally, /anas/mcp requires an Access assertion that only Cloudflare Access can mint, so the test suite signs assertions with a generated key (see docs/mcp-authentication.md). Do not add an auth bypass for development. Production authentication must be verified against the deployed Worker through Access.

Verification

pnpm run check

The final project check should also validate openapi.yaml with an OpenAPI 3.2-capable validator. Until that validator is actually wired in, OpenAPI automated validation remains pending.

For production auth, follow docs/cloudflare-access.md and verify Managed OAuth and Service Token (concurrently), blocked identities/tokens, and the origin 401 against the deployed system.

Deployment

Do not make pnpm run deploy or locally copied Wrangler deployment commands the normal production CI path.

Production/development CI deployment must be invoked through the reusable workflow maintained by firstsun-dev/.github. The application repository should contain only the thin caller after package-manager compatibility, versioning, URLs, and Cloudflare bootstrap credentials have been resolved.

See docs/cicd.md.

Do not commit real Cloudflare resource IDs, database credentials, Google OAuth credentials, Access assertions, Service Token secrets, or private analytics payloads.

OpenSpec

Start with:

  • openspec/project.md — project architecture and boundaries
  • openspec/specs/analytics-mcp/spec.md — baseline capability requirements
  • openspec/changes/bootstrap-analytics-mcp/ — bootstrap design/tasks
  • openspec/changes/support-dual-access-auth/ — active concurrent Managed OAuth + Service Token authentication decision
  • openspec/changes/use-mcp-api-key-auth/, openspec/changes/add-cloudflare-access-auth/ — superseded decisions (historical only)
  • openspec/changes/use-centralized-cf-worker-ci/ — organization-managed Cloudflare Worker CI/CD decision
  • openspec/changes/adopt-openapi-http-contract/ — OpenAPI/Swagger HTTP contract decision
  • docs/api.md — OpenAPI/Swagger ownership and drift policy
  • docs/mcp-authentication.md — dual-mode Access authentication model and client setup
  • docs/cloudflare-access.md — Access ownership, rollout ordering, verification matrix
  • docs/credentials.md — credential ownership, storage, and exception policy
  • docs/cicd.md — reusable deployment workflow policy

See AGENTS.md before making code or architecture changes.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages