google-tasks-mcp
# google-tasks-mcp
A local [MCP](https://modelcontextprotocol.io) server that lets Claude read and manage your **Google Tasks**.
TypeScript, MCP SDK v2, stdio transport, Google Tasks API v1. No third-party Google libraries.
## Tools
| Tool | What it does |
|---|---|
| `gtasks_list_task_lists` | List your task lists |
| `gtasks_create_task_list` | Create a list |
| `gtasks_delete_task_list` | Delete a list and all its tasks (destructive) |
| `gtasks_list_tasks` | List tasks; filter by completed state and due/completed date range; paginated |
| `gtasks_get_task` | Get one task |
| `gtasks_create_task` | Create a task (title, notes, due date, optional parent) |
| `gtasks_update_task` | Change title, notes, due date or status (can clear due/notes with `null`, or reopen) |
| `gtasks_complete_task` | Mark a task as done |
| `gtasks_delete_task` | Delete a task (destructive) |
All tools take `response_format` (`markdown` default, or `json`). `list_id` defaults to `@default` (your main list).
**Google Tasks limits:** `due` holds a day only (no time of day), there are no timed reminders, and tasks cannot be assigned to other people.
## Setup
Requires Node 20.3+.
```bash
npm install
npm run build
```
### 1. Create the Google OAuth client (one time, ~5 min)
1. Open <https://console.cloud.google.com/> and create a project (e.g. `google-tasks-mcp`).
2. **APIs & Services → Library** → search **Google Tasks API** → **Enable**.
3. **APIs & Services → OAuth consent screen** (or *Google Auth platform*):
- User type **External**, fill app name and your email.
- **Audience / Test users**: add your own Google account. (Leave the app in *Testing*; for a single user that is fine. Note that in Testing mode Google expires refresh tokens after 7 days. To avoid that, click **Publish app**; an unverified personal app still works for you, with a warning screen.)
- Scopes: add `https://www.googleapis.com/auth/tasks`.
4. **APIs & Services → Credentials → Create credentials → OAuth client ID** → application type **Desktop app**.
5. **Download JSON** and save it as:
- Windows: `%USERPROFILE%\.google-tasks-mcp\credentials.json`
- macOS/Linux: `~/.google-tasks-mcp/credentials.json`
(Override the folder with the `GOOGLE_TASKS_MCP_DIR` environment variable.)
### 2. Authorize (one time)
```bash
npm run auth
```
Your browser opens on Google's consent page. The redirect comes back to a temporary `127.0.0.1` port on your machine, and the tokens are saved to `~/.google-tasks-mcp/token.json`. Nothing is pasted into a chat or a prompt, and the tokens never live inside this repository (`.gitignore` also blocks `credentials.json` and `token.json` just in case).
To revoke access: <https://myaccount.google.com/permissions>.
### 3. Verify end to end
```bash
npm run smoke
```
Creates a throwaway list in your account, exercises every tool, then deletes the list.
## Connect to Claude
### Claude Code (local, stdio)
```bash
claude mcp add google-tasks --scope user -- node /absolute/path/to/google_tasks_mcp/dist/index.js
```
On Windows use the full path, e.g. `node C:\Users\you\Documents\proyectos\google_tasks_mcp\dist\index.js`.
Check with `claude mcp list`.
### Claude Desktop (local, stdio)
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"google-tasks": {
"command": "node",
"args": ["C:\\path\\to\\google_tasks_mcp\\dist\\index.js"]
}
}
}
```
### claude.ai (web) and scheduled/cloud runs
claude.ai custom connectors only accept **remote** MCP servers, so this local stdio server cannot be added there directly. The options:
| Option | Needs |
|---|---|
| **Local (this repo)**: Claude Code / Claude Desktop | Nothing beyond the setup above. Tokens stay on your machine. |
| **Remote custom connector** for claude.ai | A public **HTTPS** URL serving MCP over Streamable HTTP, plus an **OAuth 2.1 authorization layer of your own** in front of it (so claude.ai can authenticate to *your server*), which in turn holds the Google tokens. That means hosting, TLS, token storage, and implementing the MCP authorization flow (the SDK has `requireBearerAuth` and OAuth examples). Substantially more work and a larger security surface. |
If your automated daily summary runs locally (Claude Code or Claude Desktop on your PC), the local server is enough. Only a summary that runs in claude.ai's cloud needs the remote variant, which this repo does not implement yet.
## Security notes
- Scope is `https://www.googleapis.com/auth/tasks` (read and write Tasks only).
- OAuth uses the authorization-code flow with PKCE and a random `state`, over a loopback redirect.
- Tokens are written with mode `0600` outside the repo; they are never logged. Logging goes to stderr only.
- Deleting a list deletes its tasks; the delete tools are marked `destructiveHint`, so clients can ask for confirmation.
## Development
```bash
npm run dev # run from source
npm run build # compile to dist/
npx @modelcontextprotocol/inspector node dist/index.js
```
## License
MIT
TDQS
Scored across 9 tools
Each tool targets a distinct resource+action pair, and descriptions explicitly route overlapping cases (e.g. update_task says to use gtasks_complete_task for finishing a task, delete_task says to use complete_task to keep a record). The only real overlap is that update_task can set status, which duplicates complete_task, but the descriptions handle it well.
Every tool follows the same gtasks_<verb>_<noun> snake_case pattern (create/delete/list/get/update/complete). No style mixing or inconsistent verb conventions.
Nine tools cleanly cover the domain: three for lists, six for tasks. Each tool earns its place with no redundant or filler operations.
Full lifecycle coverage for tasks (create, get, list, update, complete, delete) and near-full for lists (create, list, delete). Minor gaps: no way to rename a task list, and no explicit tools for subtasks, moving/reordering tasks, or clearing completed tasks, though most can be worked around.