asana-full-mcp
by AlexDay3000
README.md
# asana-full-mcp
A local MCP server exposing the **full Asana REST API** — usable directly
from [Claude Code](https://claude.com/claude-code) as a stdio server, or
packaged as an [MCPB bundle](https://github.com/anthropics/mcpb) for
one-click install into Claude Desktop.
## Why
Hosted Asana connectors expose a curated subset of the API, and some
operations just aren't reachable through them (attaching custom fields to
projects, setting library field values, portfolio/goal plumbing, batch
endpoints, …). Working around that meant one-off scripts with a PAT every
time the curated tools fell short.
This server takes the opposite approach: one generic pass-through tool
covering the entire
[Asana API surface](https://developers.asana.com/reference), plus a few
curated convenience tools for the common operations — with the safety
guardrails enforced **in code**, not in prompts, so an over-eager model
can't talk its way past them.
## Tools
| Tool | What it does |
|---|---|
| `asana_request` | Call any Asana REST endpoint (`GET`/`POST`/`PUT`/`DELETE`) with arbitrary query/body — full API coverage |
| `asana_list_workspaces` | List workspaces/organizations visible to the token |
| `asana_search_tasks` | Task search with common filters plus an `extraQuery` escape hatch for any Asana search param |
| `asana_create_task` | Create a task (name, notes, due date, assignee, projects, custom fields, subtask parent) |
| `asana_update_task` | Update fields on an existing task |
## Guardrails
These are enforced in server code, so a confused or over-eager model cannot
talk its way past them:
- **DELETE is blocked by default.** Any `DELETE` via `asana_request` is
refused unless the bundle was installed with *Allow DELETE requests*
turned on. The curated tools cannot delete at all.
- **Optional workspace allowlist.** If configured, every non-GET request is
checked against a list of allowed workspace GIDs. The server resolves the
affected workspace from the request body or target resource; if it cannot
be determined, the request is refused (**fail closed**). Reads are never
restricted.
## Use with Claude Code (stdio)
Build the self-contained server bundle, then register it:
```sh
git clone https://github.com/AlexDay3000/asana-full-mcp && cd asana-full-mcp
npm install
npm run build # bundles src/ into server/index.js (no runtime deps needed)
claude mcp add asana-full \
--env ASANA_PAT=your-asana-pat \
--env ASANA_WORKSPACE_ALLOWLIST= \
--env ASANA_ALLOW_DELETE=false \
-- node "$PWD/server/index.js"
```
Configuration is via environment variables:
| Variable | Required | Notes |
|---|---|---|
| `ASANA_PAT` | yes | Personal Access Token — create at <https://app.asana.com/0/my-apps> |
| `ASANA_WORKSPACE_ALLOWLIST` | no | Comma-separated workspace GIDs writes are restricted to; blank = no restriction |
| `ASANA_ALLOW_DELETE` | no | `true` to permit DELETE via `asana_request`; anything else blocks it |
## Use with Claude Desktop (MCPB)
Build the `.mcpb` bundle (see below) and open it with Claude Desktop.
You'll be prompted for:
| Setting | Required | Notes |
|---|---|---|
| Asana Personal Access Token | yes | Create at <https://app.asana.com/0/my-apps> |
| Workspace GID allowlist | no | Comma-separated GIDs; blank = writes allowed anywhere the token can reach |
| Allow DELETE requests | no | Default off |
The token is stored by the host's user-config mechanism — it is never baked
into the bundle.
## Build from source
```sh
npm install
npm run pack # esbuild-bundles src/ into server/index.js, then packs the .mcpb
```
Requires Node 18+ (uses global `fetch`).
## License
[MIT](LICENSE)
This project is not affiliated with or endorsed by Asana, Inc. "Asana" is a
trademark of Asana, Inc. Your use of the Asana API through this server is
subject to [Asana's API terms](https://asana.com/terms).
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues