I wanted MCP clients to create Google Tasks for me. The Google Tasks API requires a Workspace-style setup I don’t have. IFTTT already bridges webhooks to Google Tasks—but a Maker webhook URL is itself the credential. Storing that key in local MCP config is a bad idea.

The fix is a thin Cloudflare Worker plus Cloudflare Access Managed OAuth:

  1. Worker holds the IFTTT key as a secret and speaks MCP over HTTP
  2. Access sits in front, handles OAuth login with your IdP
  3. Worker verifies the Access JWT (Cf-Access-Jwt-Assertion) before running tools

The full example: doitian/google-task-ifttt-webhook-mcp. Most of it was scaffolded by AI; the interesting part is the structure, not the TypeScript.

The problem

PieceConstraint
Google Tasks APINeeds a Workspace-style setup I don’t want to pay for
IFTTT Maker webhookWorks, but the URL is the credential
MCP clientsExpect remote HTTP tools with OAuth
MCP Client
  → Cloudflare Access (OAuth)
  → Worker (JWT)
  → IFTTT
  → Google Tasks

Clients never see IFTTT_MAKER_TASK_KEY. They only hold a short-lived Access token after login.

IFTTT side

One applet:

  • If: Maker Webhooks → Receive a web request, event name task
  • Then: Google Tasks → Create a task (title / notes / due from the payload)

The Worker posts to:

https://maker.ifttt.com/trigger/task/json/with/key/{KEY}

with { "title", "notes?", "due?" }. The key never leaves Cloudflare.

Three secrets

npx wrangler secret put IFTTT_MAKER_TASK_KEY
npx wrangler secret put CF_ACCESS_TEAM_DOMAIN
npx wrangler secret put CF_ACCESS_AUD
SecretRole
IFTTT_MAKER_TASK_KEYMaker webhook key
CF_ACCESS_TEAM_DOMAINZero Trust team domain (e.g. myteam.cloudflareaccess.com)
CF_ACCESS_AUDAccess application audience tag (validates JWT aud)

No custom authorize page, no signing keys you mint yourself. Access is the authorization server.

Cloudflare Access

In the Zero Trust dashboard:

  1. AccessApplicationsAddSelf-hosted
  2. Point the app at your Worker hostname (*.workers.dev or a custom domain)
  3. Pick an IdP (Google, GitHub, email OTP, …) and an allow policy for yourself
  4. Enable Managed OAuth (Beta)—this is what MCP clients need for the OAuth dance
  5. Copy the team domain and Application Audience (AUD)

Access issues JWTs; MCP clients send them as Cf-Access-Jwt-Assertion. The Worker verifies with the team’s JWKS:

const JWKS = createRemoteJWKSet(
  new URL(`${issuer}/cdn-cgi/access/certs`),
);
await jwtVerify(token, JWKS, {
  issuer,
  ...(env.CF_ACCESS_AUD ? { audience: env.CF_ACCESS_AUD } : {}),
});

(jose on Workers with nodejs_compat.)

Worker: just MCP + verify

The business logic is small:

  • POST / or POST /mcp—JSON-RPC (initialize, tools/list, tools/call)
  • One tool: create_google_task (title required; notes, due optional)
  • Reject anything without a valid Access JWT

No OAuth endpoints in the Worker. Access owns login; the Worker only checks the assertion header.

Client config

Point the client at the Worker URL and enable OAuth. Example structure (keys vary by client):

{
  "mcp": {
    "google-tasks": {
      "type": "remote",
      "url": "https://google-task-mcp.yourdomain.com"
    }
  }
}

The client discovers OAuth via Access, opens the browser for your IdP, then attaches the Access JWT on MCP calls.

Why this structure works with AI

The task decomposes cleanly:

  1. MCP handler—fixed JSON-RPC + one tool schema
  2. IFTTT fetch—secret from env
  3. Access JWT verify—JWKS + aud
  4. Wrangler secrets—nothing in git

Describe the constraints (“don’t expose the IFTTT URL”, “Cloudflare Access OAuth”, “Worker MCP”) and get a deployable skeleton. Review JWT verification and secret handling; treat the tool body as glue.

Takeaways

  • Skip the official Tasks API if IFTTT already has the integration.
  • Keep Maker keys in Worker secrets, not client config.
  • Cloudflare Access Managed OAuth turns IdP login into MCP-friendly OAuth without requiring custom authorize/token endpoints.
  • The Worker only needs to verify Cf-Access-Jwt-Assertion and call IFTTT.

Source: github.com/doitian/google-task-ifttt-webhook-mcp.