asana-mcp
by djy89
README.md
# asana-mcp
A minimal, zero-destructive MCP server for Asana — built because the official Anthropic/Asana connector is broken.
## Why this exists
The official Asana connector surfaced in Claude Code as `mcp__claude_ai_Asana__*` tools. As of mid-2026 it stopped working — claude.ai's registry returns "Server not found" and Asana's `/sse` endpoint has been deprecated. There's no ETA on a fix.
Rather than wait, this is a clean TypeScript MCP server using the official `asana` npm SDK (v3.x) and a Personal Access Token. It gives Claude Code full Asana access with no third-party middleman, no destructive operations, and a minimal dependency footprint.
## Features
- **26 tools** — 13 read, 13 write, 0 destructive (no delete operations)
- **Custom field support** — set enum, multi-enum, number, text, and date custom fields on create and update
- **Read-only mode** — set `READ_ONLY_MODE=true` to hide all write tools
- **Minimal deps** — `asana` SDK, `zod`, `@modelcontextprotocol/sdk`, `dotenv`
## Tools
| Category | Tools |
|----------|-------|
| Tasks | `search_tasks`, `get_task`, `get_task_stories`, `create_task`, `update_task`, `create_subtask`, `create_task_story`, `get_multiple_tasks_by_gid`, `set_parent_for_task`, `add_task_dependencies`, `add_task_dependents` |
| Projects | `search_projects`, `get_project`, `get_project_sections`, `get_project_task_counts`, `get_project_status`, `create_project`, `create_project_status` |
| Tags | `get_tags_for_workspace`, `get_tags_for_task`, `create_tag`, `add_tag_to_task`, `remove_tag_from_task` |
| Misc | `list_workspaces`, `add_project_to_task`, `remove_project_from_task` |
## Requirements
- Node.js ≥ 18
- An Asana account with a Personal Access Token
## Setup
### 1. Get an Asana PAT
Go to **Asana → Settings → Developer apps → Personal access tokens** and create a token.
### 2. Configure environment
```bash
cp .env.example .env
# Edit .env and fill in your values
```
`.env`:
```
ASANA_ACCESS_TOKEN=your_token_here
ASANA_WORKSPACE_ID=your_workspace_gid
ASANA_DEFAULT_PROJECT_ID=your_default_project_gid # optional fallback
READ_ONLY_MODE=false
```
**Finding your Workspace GID:** Open Asana in a browser and navigate to any project. The URL looks like `https://app.asana.com/0/<workspace_gid>/<project_gid>`. The first long number after `/0/` is your workspace GID. Alternatively, after setup you can call `asana_list_workspaces` and it will return it.
> **Note:** Always pass `project` explicitly when creating tasks. If omitted, the server falls back to `ASANA_DEFAULT_PROJECT_ID`.
### 3. Build
```bash
npm install
npm run build
```
### 4. Register with Claude Code
```bash
claude mcp add asana -s user -- node /absolute/path/to/asana-mcp/dist/index.js
```
Or with env vars inline (if you prefer not to use a `.env` file):
```bash
claude mcp add asana -s user \
-e ASANA_ACCESS_TOKEN=your_token \
-e ASANA_WORKSPACE_ID=your_workspace_gid \
-- node /absolute/path/to/asana-mcp/dist/index.js
```
Restart Claude Code, then enable via `/mcp`.
## Custom fields
`asana_create_task` and `asana_update_task` accept a `custom_fields` object. Keys are custom-field GIDs; value shape depends on field type:
```json
{
"custom_fields": {
"1234567890000001": "9876543210000001",
"1234567890000002": ["9876543210000002", "9876543210000003"],
"1234567890000003": 42,
"1234567890000004": "plain text",
"1234567890000005": { "date": "2026-12-31" }
}
}
```
| Field type | Value |
|-----------|-------|
| Single-select enum | Option GID string |
| Multi-select enum | Array of option GID strings |
| Number | Number |
| Text | String |
| Date | `{"date":"YYYY-MM-DD"}` |
The field must be enabled on the task's project/portfolio for the API to accept it.
## Development
```bash
npm run build # tsc → dist/
```
After rebuilding, restart your Claude Code session — stdio MCP servers are spawned at session start and don't hot-reload.
## License
UNLICENSED
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessSyncing