gtasks-mcp
Wraps the full Google Tasks API v1, providing tools to manage tasklists and tasks, including creating, updating, completing, moving, deleting, searching, and clearing completed tasks, plus convenience tools like get_today and get_due_soon.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
gtasks-mcp
Self-hosted, streamable-HTTP MCP server wrapping the full Google Tasks API v1.
One Python module of tools (server.py), an httpx wrapper with OAuth refresh-token
auth (google_client.py), and a one-time auth bootstrap (auth.py). No database,
no local state — all state lives in Google Tasks.
Tools
Tasklists: list_tasklists, get_tasklist, create_tasklist, update_tasklist, delete_tasklist.
Tasks: list_tasks, get_task, search_tasks, create_task, create_task_series,
update_task, complete_task, uncomplete_task, delete_task, move_task,
clear_completed_tasks, plus the get_today / get_due_soon conveniences.
All tools accept an optional tasklist_id (defaults to GTASKS_DEFAULT_LIST, else
Google's @default). Errors are structured {error, message, detail?} with stable
codes: not_found, invalid_request, rate_limited, auth_expired,
upstream_unavailable, internal_error.
Related MCP server: Google Tasks MCP Server
Configuration
Environment variables (see .env.example):
Variable | Required | Description |
| yes | OAuth client ID (Desktop-app type) |
| yes | OAuth client secret |
| yes | Long-lived refresh token from |
| yes when public | Shared secret required as |
| no | Bind address, default |
| no | Bind port, default |
| no | Comma-separated extra |
| no | Default |
| no | Default list id when a tool omits |
Scope: https://www.googleapis.com/auth/tasks (read/write), nothing else.
Finding a list id
List ids are not shown anywhere in the Google Tasks UI. Run the helper with the same credentials as the server to print every list's title next to its id:
uv run python find_list_id.py # loads ./.env automatically if present
uv run python find_list_id.py --env-file ~/secrets/gtasks.envThen set GTASKS_DEFAULT_LIST=<id> in your server .env.
Auth bootstrap (run once, on your laptop)
uv run python auth.py # loads ./.env automatically if present
uv run python auth.py --env-file ~/secrets/gtasks.env
# or explicitly: python auth.py --client-id ... --client-secret ...
# or via shell: set -a; source .env; set +a; uv run python auth.pyOpens the consent screen with a loopback listener on port 4466 (register
http://localhost:4466 and http://127.0.0.1:4466 as redirect URIs in the Google
Cloud OAuth client) and prints a GOOGLE_REFRESH_TOKEN. The token is never stored
by this project — put it in .env on the server only.
Run locally
cp .env.example .env # fill in secrets (MCP_BEARER_TOKEN: openssl rand -hex 32)
uv sync
uv run python server.py # auto-loads ./.env; serves HTTP on $MCP_HOST:$MCP_PORT/mcp (default 0.0.0.0:8080)
curl http://127.0.0.1:8080/healthzserver.py loads ./.env at startup when present (real environment variables
take precedence), same as auth.py. In Docker, compose injects .env via
env_file instead — the file itself is never baked into the image.
Deploy (Docker Compose on the VPS, behind the existing Cloudflare tunnel)
cp .env.example .env # fill in secrets
docker compose up -d --buildThe service joins the tunnel's compose network (TUNNEL_NETWORK, default
cloudflared) and exposes only the container port (${MCP_PORT:-8080}) — it is
never published to the host. Point the existing tunnel route at it, e.g.
gtasks.<your-domain> → http://gtasks-mcp:${MCP_PORT:-8080}, set
MCP_ALLOWED_HOSTS=gtasks.<your-domain> in .env, then add a custom MCP connector
in Vibe: URL https://gtasks.<your-domain>/mcp with header
Authorization: Bearer <MCP_BEARER_TOKEN>.
Security checklist before going public
MCP_BEARER_TOKENis mandatory wheneverMCP_HOSTis not loopback: the server refuses to start without it (fail closed), rejects tokens shorter than 16 chars, compares them in constant time, and never logs the token — only 401 events.The built-in FastMCP Host/Origin guard (
host_origin_protection) is always on: requests with aHostother thanlocalhost/127.0.0.1/::1plusMCP_ALLOWED_HOSTSget a 421, which blocks DNS-rebinding and direct-IP probing with a wrong Host header.Keep the origin port firewalled: compose uses
expose, notports, so the port is reachable only from the tunnel network. Do not add a publicports:mapping.Put a Cloudflare Access (Zero Trust) policy in front of the hostname, restricted to your own email — the bearer token is a static shared secret, Access adds a second factor. Optionally add WAF rate-limiting rules on the route.
Only ever send the bearer token over HTTPS (the tunnel provides it); treat the token like a password and rotate it (
openssl rand -hex 32) if leaked./healthzstays unauthenticated on purpose (Docker healthcheck); it only reports status/version, never secrets. Block it at the tunnel if you don't need it.The Google OAuth scope is
tasksonly (read/write), nothing else; the refresh token lives only in the server.env, which is never baked into the image.The container runs as a non-root user and
.envis injected at runtime.
Tests
uv sync
uv run pytestUnit tests mock httpx (httpx.MockTransport): every tool happy path, date
normalization, pagination merging, 401 → refresh → retry, and every error mapping.
This server cannot be deployed
Maintenance
Related MCP Connectors
Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.
Headless task management for bots, apps and AI agents. Remote MCP server, OAuth or access token.
Local-first task manager: create, edit, and complete tasks, projects, and checklists via MCP.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for TickTick — create, update, complete, move, and filter tasks (plus subtasks, completed-task retrieval, and recurring reminders) via the TickTick v2 API. Maintained fork of jen6/ticktick-mcp adding field-preserving updates, day-of-week date validation, completion tracking and more.141GPL 3.0
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol (MCP) server that brings your Google Tasks into Claude and other MCP-compatible clients, enabling task and task list management through natural conversation.56 npm10MIT
- AlicenseNot gradedqualityDmaintenanceA small Model Context Protocol server that exposes a personal task tracker to any MCP-compatible client. Tasks live in a local SQLite database; no cloud, no surprises.MIT
- AlicenseAqualityDmaintenanceA small MCP server for read-write access to Google Tasks, Calendar, and Drive, enforcing human approval for all mutating operations.1MIT