Google Tasks MCP
Two small tools for reaching Google Tasks from Claude: a remote MCP server for the surfaces without a shell (web, mobile, desktop), and a dependency-free Python CLI for Claude Code.
What it does
The MCP server
- Runs as a custom connector in Claude. It exposes five tools: list the task lists, list the tasks in a list, add a task (title, notes, due date), mark a task complete, and delete a task.
- Signing in is a normal OAuth consent flow. Claude registers itself automatically, so there is no client setup on the Claude side.
- Access is limited to a configured allowlist of Google accounts. Anyone else who completes the Google sign-in is turned away.
- The tool descriptions carry the identifiers of the user's usual lists and a rule of thumb for which list suits what, so Claude can file a task without first looking the lists up.
The CLI
- A single Python file with subcommands for the same operations:
lists,list,add,doneandrm. - Defaults to the primary list. Tasks can be added with notes and a due date.
- The first run opens a browser for Google sign-in and caches the tokens locally; later runs are silent.
Under the hood
- The server is a TypeScript Cloudflare Worker. It plays two OAuth roles: an authorisation server towards Claude (using Cloudflare's OAuth provider library, with dynamic client registration), and an OAuth client towards Google, asking for the Tasks scope plus the account email for the allowlist check.
- The Google refresh token is stored inside the grant issued to Claude. Each tool call exchanges it for a short-lived access token and calls the Tasks REST API directly; nothing is cached between calls, since volume is tiny.
- The server is stateless. It used to run each MCP session in a Durable Object, but the newer MCP spec no longer needs a session, so the Durable Object class was deleted and each request gets a fresh MCP server instance. Auth details reach the tools through the request context.
- Only an explicit list of paths is served (MCP, the OAuth endpoints and their metadata documents); everything else gets a 404 before reaching the OAuth or MCP code, which keeps scanner noise out of the logs.
- A small shim canonicalises the connector path to lowercase. A mobile keyboard that auto-capitalised the URL as it was typed produced
/Mcp, and the OAuth library compares the resource path case-sensitively across the authorise, token and API steps. - The first-time approval page is protected with a CSRF token, and the OAuth state is bound to the browser session by a cookie, so a callback cannot be replayed from another browser.
- The CLI uses only the standard library:
argparse,urlliband a throwaway localhttp.serverto catch the redirect. The sign-in uses the installed-app flow with PKCE, and a 401 triggers one automatic token refresh and retry.