Change Asana without opening Asana. 75-tool MCP server over the Asana REST API — custom fields that stick, section moves, start dates, rich notes, bulk edits, board-schema design, one-call briefs. PAT + stdio, local-first, every tool MCP-annotated.
Strong tool naming (verb_noun pattern consistently applied). Descriptions are detailed and explain the 'why' (fixing gaps in official MCP). All 12 tools have explicit input schemas with typed properties. However, output schemas are not documented, LLMs cannot predict response structure. Some parameter descriptions are verbose but lack formal constraints (enums, patterns, ranges). Error handling guidance is minimal. File attachment tool has security considerations but no explicit validation messaging. Overall: solid foundation with room for output documentation and tighter parameter constraints.
Add a task to a project, optionally placing it in a specific section. Fixes: no MCP tool for addProject + section placement.
Attach a local file to an Asana task. Requires confirm:true and restricts reads to the current directory or ASANA_MCP_FILE_ROOTS. Max 100MB.
Execute up to 5 Asana API operations in a single HTTP call. ⚠ GET-with-default-fields ONLY — options (opt_fields/completed_since) + PUT data are dropped by the batch endpoint. For filtered reads use asana_search_tasks/asana_list_*; for writes use the dedicated tools.
Update multiple task fields in a single REST call. Combines assignee, dates, custom fields, notes, name, and completion.
Fetch one task with rich fields (assignee, projects, section memberships, custom fields, notes, subtask count). Override opt_fields for more/less.
Output schemas not documented. LLMs cannot predict response structure, field names, or types. Downstream tool chaining requires guessing which fields are returned.
Parameter constraints lack formal enums/patterns. 'sort_by' in asana_search_tasks lists valid values in description ('created_at | modified_at | ...') but not as JSON Schema enum. LLMs may hallucinate invalid values.
asana_attach_file requires 'confirm:true' but lacks actionable error messaging. If confirm is false or missing, the error should guide the user to review file_path and retry with confirm=true.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
List tasks by project, section, tag, OR assignee (provide exactly one anchor). Paginated. assignee uses the workspace default.
Move a task to a different section within its project. Fixes: no MCP tool for section moves.
List the TOKEN OWNER's My Tasks (user task list). NOTE: a personal PAT can only read its own My Tasks; service accounts may see others' if granted.
Advanced workspace task search with filters: text, assignee, project, section, tag, completed, due/created date ranges, custom-field filters (filters passthrough), sorting. Single page (search API caps at 100, no offset).
Set custom fields on a task using correct type handling. Fixes: multi_enum arrays and date object wrappers that fail via official MCP.
Set start_on and/or due_on dates on a task. Fixes: start_on not exposed in official MCP schema, and due_on must be set first.
Set rich-text notes on a task using html_notes. Fixes: "XML is invalid" error from official MCP.
asana_batch_update combines 9 optional fields with no guidance on which combinations are valid or recommended. Descriptions do not clarify if html_notes overrides notes, or if both can coexist.
Pagination tools (asana_list_tasks, asana_my_tasks, asana_search_tasks) accept max_pages but do not document total count or next_cursor in response. LLMs cannot determine if more results exist without calling again.