Verified MCP server: Asana

The Asana MCP server, enumerated live on a real Mac.

  • Tools enumerated2026-08-03macOS 15.7.7
  • Package@roychri/mcp-server-asana 1.8.0
  • Self-reportedAsana MCP Server 1.8.0
  • MCP protocol2024-11-05
  • Runtimev24.18.0

The tool list below is a live capture from the running server; an authenticated tool call is still pending credentials.

The short answer

Last verified 2026-08-03

The Asana MCP server on this page is @roychri/mcp-server-asana, a community package written by an independent developer, not by Asana. Connected to an AI assistant, it can search projects and tasks, create and update them, add subtasks, comments, tags, sections, dependencies and project status updates inside your Asana workspace. It needs one credential, an Asana personal access token in an environment variable called ASANA_ACCESS_TOKEN. Here is exactly what we verified, and what we did not. We ran the package on a Mac with a placeholder value in that variable: the server started, completed the MCP handshake, and answered tools/list with 41 tools, which is the table below, word for word. The one real tool call we made reached Asana's own API and came back with a 401 authentication error, printed further down, because a placeholder is not a token. An authenticated call still waits for your own token. Asana separately runs a hosted MCP endpoint of its own at mcp.asana.com, which is gated behind an OAuth login: we confirmed it answers and refuses unauthenticated requests, but we could not enumerate its tools without signing in through a browser, so nothing on this page describes it. [1][3][4][5]

  • Tools

    41, enumerated live

  • Credentials

    ASANA_ACCESS_TOKEN required [4]

  • Transport

    stdio, runs on your Mac [4][1]

  • Maintainer

    Christian Roy, community [1][3]

  • Downloads

    3,466 last week [2]

  • License

    MIT [1][3]

Verification

How this MCP server was verified.

Method

We spawned the server with npx over stdio with ASANA_ACCESS_TOKEN set to a placeholder value, completed the MCP initialize handshake, and called tools/list: the server answered with 41 tools, and the table below is that answer, word for word. We asked for protocol version 2025-06-18 and the server negotiated 2024-11-05 back, which is the version recorded here. In that same session we then made one real tool call, asana_list_workspaces with no arguments. It reached https://app.asana.com/api/1.0/workspaces over HTTPS and Asana answered HTTP 401, which the server handed back as the excerpt below. So the tool table is enumerated live and the failure is a genuine authentication error from Asana itself, while an authenticated call still waits for a real Asana personal access token in that variable.

Startup banner

Starting Asana MCP Server...
Connecting server to transport...
Asana MCP Server running on stdio

One real tool call

tools/call asana_list_workspaces {}
{"error":"Unauthorized"}

Real lines from the captured result: enough to prove the call answered.

Tools

Every tool, enumerated from the running server.

The server answered tools/list with 41 tools on 2026-08-03. The names, descriptions and parameters below are its own words, copied from that response and never edited.

ToolWhat it does
asana_list_workspacesopt_fields

List all available workspaces in Asana

asana_search_projectsworkspace*name_pattern*archivedopt_fields

Search for projects in Asana using name pattern matching

asana_get_my_tasksworkspace*opt_fieldscompleted_since

Get tasks from the authenticated user's 'My Tasks' list in a workspace. Returns the user's personal task list including sections like Inbox, Today, This Week, etc.

asana_search_tasksworkspace*textresource_subtypeportfolios_anyassignee_anyassignee_notprojects_anyprojects_notprojects_allsections_anysections_notsections_alltags_anytags_nottags_allteams_anyfollowers_notcreated_by_anycreated_by_notassigned_by_anyassigned_by_notliked_by_notcommented_on_by_notdue_ondue_on_beforedue_on_afterdue_at_beforedue_at_afterstart_onstart_on_beforestart_on_aftercreated_oncreated_on_beforecreated_on_aftercreated_at_beforecreated_at_aftercompleted_oncompleted_on_beforecompleted_on_aftercompleted_at_beforecompleted_at_aftermodified_onmodified_on_beforemodified_on_aftermodified_at_beforemodified_at_aftercompletedis_subtaskhas_attachmentis_blockedis_blockingsort_bysort_ascendingopt_fieldscustom_fields

Search tasks in a workspace with advanced filtering options

asana_get_tasktask_id*opt_fields

Get detailed information about a specific task

asana_create_taskproject_id*name*noteshtml_notesdue_onassigneefollowersparentprojectsresource_subtypecustom_fields

Create a new task in a project

asana_get_task_storiestask_id*opt_fields

Get comments and stories for a specific task

asana_update_tasktask_id*namenoteshtml_notesdue_onassigneefollowersparentcompletedresource_subtypecustom_fields

Update an existing task's details

asana_get_projectproject_id*opt_fields

Get detailed information about a specific project

asana_get_project_task_countsproject_id*opt_fields

Get the number of tasks in a project

asana_get_project_sectionsproject_id*opt_fields

Get sections in a project

asana_get_tasks_for_projectproject_id*opt_fieldslimitoffset

Get all tasks in a project. Use this instead of search_tasks when you need to list tasks in a specific project. Supports pagination and optional field selection.

asana_create_projectworkspace*name*teamnotescolorprivacy_settingdefault_viewopt_fields

Create a new project in a workspace or team

asana_create_task_storytask_id*texthtml_textopt_fields

Create a comment or story on a task. Either text or html_text is required.

asana_add_task_dependenciestask_id*dependencies*

Set dependencies for a task

asana_add_task_dependentstask_id*dependents*

Set dependents for a task (tasks that depend on this task)

asana_create_subtaskparent_task_id*name*noteshtml_notesdue_onassigneeopt_fields

Create a new subtask for an existing task

asana_get_subtaskstask_gid*opt_fields

Get all subtasks of a given task. Returns a compact representation of each subtask.

asana_get_multiple_tasks_by_gidtask_ids*opt_fields

Get detailed information about multiple tasks by their GIDs (maximum 25 tasks)

asana_get_project_statusproject_status_gid*opt_fields

Get a project status update

asana_get_project_statusesproject_gid*limitoffsetopt_fields

Get all status updates for a project

asana_create_project_statusproject_gid*text*colortitlehtml_textopt_fields

Create a new status update for a project

asana_delete_project_statusproject_status_gid*

Delete a project status update

asana_set_parent_for_taskdata*task_id*opts

Set the parent of a task and position the subtask within the other subtasks of that parent

asana_get_tagtag_gid*opt_fields

Get detailed information about a specific tag

asana_get_tags_for_tasktask_gid*limitoffsetopt_fields

Get a task's tags

asana_get_tags_for_workspaceworkspace_gid*limitoffsetopt_fields

Get tags in a workspace

asana_update_tagtag_gid*namecolornotesopt_fields

Update an existing tag

asana_delete_tagtag_gid*

Delete a tag

asana_get_tasks_for_tagtag_gid*opt_fieldsopt_prettylimitoffset

Get tasks for a specific tag

asana_create_tag_for_workspaceworkspace_gid*name*followerscolornotesopt_fields

Create a new tag in a workspace

asana_add_tag_to_tasktask_gid*tag_gid*

Add a tag to a task

asana_remove_tag_from_tasktask_gid*tag_gid*

Remove a tag from a task

asana_add_project_to_tasktask_id*project_id*sectioninsert_afterinsert_before

Add an existing task to a project. If no positioning arguments are given, the task will be added to the end of the project.

asana_remove_project_from_tasktask_id*project_id*

Remove a task from a project. The task will still exist in the system, but it will not be in the project anymore.

asana_delete_tasktask_id*

Delete a task. This permanently removes the task and cannot be undone.

asana_create_sectionproject_id*name*opt_fields

Create a new section in a project

asana_update_sectionsection_id*name*opt_fields

Update a section (rename it)

asana_delete_sectionsection_id*

Delete a section from a project

asana_add_task_to_sectionsection_id*task_id*insert_beforeinsert_after

Move a task to a section within its project

asana_update_projectproject_id*namenoteshtml_notescolorprivacy_settingopt_fields

Update a project's details (name, description, etc.)

Parameters marked with * are required.

Setup

Working configs, one per app.

Copy the block for the app you use. Each one is the configuration this server was verified with.

Claude Desktop

Open the file ~/Library/Application Support/Claude/claude_desktop_config.json (in Claude Desktop: Settings, then Developer, then Edit Config) and add:

{
  "mcpServers": {
    "asana": {
      "command": "npx",
      "args": [
        "-y",
        "@roychri/mcp-server-asana"
      ],
      "env": {
        "ASANA_ACCESS_TOKEN": "your-asana-token-here"
      }
    }
  }
}

Replace your-asana-token-here with your own Asana personal access token, then quit and reopen Claude Desktop. Asana also runs a hosted MCP endpoint of its own at https://mcp.asana.com/v2/mcp, which you add as a remote connector and authorize in the browser instead of pasting a token; it is a different server from the package configured here, and we did not enumerate it. [4][6][5]

Claude Code

One command in your terminal:

claude mcp add asana -e ASANA_ACCESS_TOKEN=your-asana-token-here -- npx -y @roychri/mcp-server-asana

Everything after the double dash is the exact command Claude Code will run, and -e sets the environment variable it runs with. We confirmed the flag on this Mac with claude mcp add --help: -e takes one KEY=value pair and can be repeated, and stdio is the default transport. [7]

Cursor

Add to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json inside one project:

{
  "mcpServers": {
    "asana": {
      "command": "npx",
      "args": [
        "-y",
        "@roychri/mcp-server-asana"
      ],
      "env": {
        "ASANA_ACCESS_TOKEN": "your-asana-token-here"
      }
    }
  }
}

Cursor picks the file up on restart. Keep the token out of a project file that gets committed: the global ~/.cursor/mcp.json is the safer home for it. [8]

Routines

No JSON file and no terminal. In Routines: Settings, then Assistant, then Connections, then Add MCP Server. Switch the form to Command (stdio) and enter:

Name                    Asana
Command                 npx
Arguments               -y @roychri/mcp-server-asana
Environment Variables   ASANA_ACCESS_TOKEN=your-asana-token-here

The token goes in the Environment Variables field as a single KEY=value row, so it never sits in the Arguments line. Click Test Connection first: a working server answers with its tool count. [9][4]

No terminal needed

Set the Asana MCP server up without the terminal.

If you have never opened Terminal and never want to, this is your path. Routines is a Mac app that runs MCP servers for you: fill in four fields once, and this server's tools are available to your AI in chat and in scheduled routines.

  1. 01

    Install Routines

    Download the app from getroutines.ai/download, drag it to Applications, and sign in.

  2. 02

    Open the MCP settings

    Click your account at the bottom of the sidebar and choose Settings. Open the Assistant section, then the Connections tab, scroll to MCP Servers, and click Add MCP Server.

  3. 03

    Choose Command (stdio)

    Switch the form to Command (stdio): this server is a command, not a web address. Name it Asana. Command: npx. Arguments: -y @roychri/mcp-server-asana, exactly as written, with one space between each part.

  4. 04

    Create an Asana personal access token

    In Asana, click your profile photo, then My Settings, then the Apps tab, then Manage Developer Apps, or go straight to app.asana.com/0/my-apps. Create a personal access token and copy it: Asana shows the full value once. Treat it like a password, because whoever holds it can read, change and delete everything you can reach in Asana.

  5. 05

    Paste the token, test, then add

    In the Environment Variables field add one row: ASANA_ACCESS_TOKEN=your-asana-token-here, with your own token after the equals sign and no spaces around it. Click Test Connection: Routines starts the server and reports how many tools it found, forty-one for this one. Then click Add Server.

  6. 06

    Use it

    The tools work in chat right away. To let a scheduled routine use them, open the routine, find the Tools & connections card, and tick the server under Apps.

Routine ideas

Routines worth scheduling.

Once the server is connected, a scheduled routine can use its tools while you are away. Copy a prompt, paste it into Routines, and pick a time.

A Monday look at the week

Prompt

Every Monday at 8:00, list my open Asana tasks due this week grouped by project, call out anything already overdue, and write the whole plan to week-ahead.md.

A Friday project status update

Prompt

Every Friday at 16:00, gather the Asana tasks completed this week in my main project plus anything still blocked, then post a short status update on that project summarizing both.

An overdue task sweep

Prompt

Every weekday at 17:30, find the Asana tasks assigned to me that were due before today and are still open, and write them to overdue.md with a one-line note on what each one is waiting for.

Troubleshooting

The errors we hit, and what fixed them.

Real errors captured during the verification run, printed exactly as the server returned them.

The server quits the moment it starts

What you see

Please set ASANA_ACCESS_TOKEN environment variable

The fix

The variable is missing entirely, so the server refuses to start: it prints this one line to stderr, exits without writing anything to stdout, and your client reports the connection as failed. Add ASANA_ACCESS_TOKEN in the env block of your JSON config, after -e on the Claude Code command, or in the Environment Variables field in Routines, then start the client again.

Every tool call comes back Unauthorized

What you see

{"error":"Unauthorized"}

The fix

Asana rejected the token. This is the exact reply our own run produced, because we started the server with a placeholder value on purpose: the request reached https://app.asana.com/api/1.0/workspaces and Asana answered HTTP 401. Check that ASANA_ACCESS_TOKEN holds your real personal access token, that you copied all of it with no trailing space, and that you restarted the client after changing it, because the value is read when the server starts, not when the tool is called.

A wrong id or a wrong value type also says Unauthorized

What you see

{"error":"Unauthorized"}

The fix

Two of our probes made this trap visible. A well-formed call with a nonsense project id, and a search call with completed set to the text not-a-boolean rather than true or false, both came back with the same authentication error: the server forwards the arguments to Asana, and Asana checks the credential before it judges the request. So while your token is wrong, Unauthorized is the only error you will see, and it hides everything else. Fix the token first, then read the error again: with a real token a bad id returns Asana's own not-found message instead.

An error names a parameter you never typed

What you see

{"error":"Missing the required parameter 'task_gid' when calling getTask"}

The fix

We triggered this by calling asana_get_task with no arguments. The tool declares its required argument as task_id, but underneath it uses Asana's official Node library, which calls the same value task_gid, and that library's message is what reaches you. They are the same thing: the numeric id at the end of a task URL in Asana. Supply it as task_id and the call goes through.

The assistant calls a tool that does not exist

What you see

{"error":"Unknown tool: asana_get_taks"}

The fix

A typo in the tool name, ours on purpose. The server does not guess or correct: it answers with the name it was given. Every name it accepts is in the table above, all 41 of them, and they all start with asana_. If your assistant keeps reaching for a tool that is not there, paste the list into the conversation so it works from the real names.

Asana's own hosted endpoint answers 401 before you sign in

What you see

{"error":"invalid_request","error_description":"Authorization header is required for MCP V2 access"}

The fix

This is not the package on this page. Asana runs its own MCP server at https://mcp.asana.com/v2/mcp, and we sent that exact address a bare request with no credential: it replied 401 with an OAuth challenge header naming the realm Asana MCP and pointing at its oauth-protected-resource metadata. That is the endpoint working as designed. It is a browser sign-in, not a token you paste, so a client that never opens the authorization window will sit on this error forever. If you want the token route with no OAuth, use the npx command on this page instead.

Your MCP client cannot start the server at all

The fix

The npx command belongs to Node.js. If Node is not installed on your Mac, every client on this page fails at the spawn step before the server can say anything. Install Node from nodejs.org, restart your MCP client, and try again.

FAQ

Questions people ask.

What is the Asana MCP server?

It is a small program that gives an AI assistant access to your Asana account through the Model Context Protocol. The one on this page, @roychri/mcp-server-asana, is a community package by an independent developer, Christian Roy, and it runs as a local command on your Mac that talks to your AI app over stdio. Once connected, an assistant such as Claude can search your projects and tasks, create and update them, comment, tag, move tasks between sections, and post project status updates. [1][3][4]

Is there an official Asana MCP server?

Yes, and it is a different thing from the package on this page. Asana documents a hosted MCP server at https://mcp.asana.com/v2/mcp, which you add to a client as a remote connector and authorize with your Asana login in the browser, with no npm package and no token to copy. We confirmed that endpoint is live on 2026-08-03: a request without a credential comes back 401 with a standard OAuth challenge. We could not enumerate its tools, because that needs a browser sign-in we did not perform, so every number on this page belongs to the community package we did run. [5]

What tools does the Asana MCP server include?

The running server exposes 41 tools. Workspaces and projects: asana_list_workspaces, asana_search_projects, asana_get_project, asana_create_project, asana_update_project, asana_get_project_task_counts, asana_get_project_sections, asana_get_tasks_for_project. Tasks: asana_get_my_tasks, asana_search_tasks, asana_get_task, asana_get_multiple_tasks_by_gid, asana_create_task, asana_update_task, asana_delete_task, asana_add_project_to_task, asana_remove_project_from_task. Subtasks and dependencies: asana_create_subtask, asana_get_subtasks, asana_set_parent_for_task, asana_add_task_dependencies, asana_add_task_dependents. Comments: asana_get_task_stories, asana_create_task_story. Sections: asana_create_section, asana_update_section, asana_delete_section, asana_add_task_to_section. Tags: asana_get_tag, asana_get_tags_for_task, asana_get_tags_for_workspace, asana_create_tag_for_workspace, asana_update_tag, asana_delete_tag, asana_get_tasks_for_tag, asana_add_tag_to_task, asana_remove_tag_from_task. Status updates: asana_get_project_status, asana_get_project_statuses, asana_create_project_status, asana_delete_project_status. The table above is the live tools/list output, word for word.

Why does the README list about 20 tools when the server answers with 41?

Because the README's prose list has fallen behind the code. We did not count the README: we asked the running server, and it answered tools/list with 41 tools, several of which the README never mentions, among them asana_get_tags_for_workspace, asana_create_project_status, asana_set_parent_for_task and asana_get_multiple_tasks_by_gid. The live answer is the one that matters, because it is what your AI client actually sees when it connects. [4]

Is it safe to give it my Asana token?

Be clear-eyed about scope. A personal access token acts as you, so this server can reach every workspace, project and task your own Asana account can reach, and the tool list includes asana_delete_task, which its own description says permanently removes the task and cannot be undone, plus asana_delete_section, asana_delete_tag and asana_delete_project_status. Nothing narrows it to one project. The README documents an optional environment variable, READ_ONLY_MODE=true, that disables the write tools; we did not exercise it in this run, so treat it as documented rather than verified. The sensible habits are to keep the token in the environment variable field your client stores privately, ask the assistant to show you what it plans to change before it changes it, and delete the token in Asana the moment you stop using the connection. [4]

Do I need the terminal to set it up?

No. In Routines you fill four fields in Settings and click Test Connection; the walkthrough above shows every click, including where the token goes. Claude Desktop needs a small JSON file edited once. Only Claude Code is terminal-first by nature. [9][6]

Which apps can use the Asana MCP server?

Any MCP client that can launch a local stdio server: Claude Desktop, Claude Code, Cursor, and Routines all can, and the exact config for each is above. The server itself is the same in every client; only the place you paste the config differs. [6][7][8][9]

Sources

Every external claim, receipted.

Anything on this page we did not observe in the run is linked here, with the date we read it. The run itself is the receipt for the rest.

  1. [1]

    npm registry: @roychri/mcp-server-asanaaccessed 2026-08-03

    Latest version 1.8.0, published 2026-03-29; license MIT; author Christian Roy; npm maintainer roychri; package first published 2024-12-04; ships the mcp-server-asana binary that runs over stdio.

  2. [2]

    npm downloads API: last weekaccessed 2026-08-03

    3,466 downloads for the week 2026-07-27 to 2026-08-02.

  3. [3]

    GitHub: roychri/mcp-server-asanaaccessed 2026-08-03

    145 stars, licensed MIT, not archived, and a push dated 2026-05-10 at access time, per the GitHub API.

  4. [4]

    mcp-server-asana README (main branch)accessed 2026-08-03

    Names the ASANA_ACCESS_TOKEN variable and where in Asana to create the token, documents the optional READ_ONLY_MODE=true variable, and lists about 20 tools in prose against the 41 the running server reports.

  5. [5]

    Asana developer docs: Using Asana's MCP Serveraccessed 2026-08-03

    Tells clients to connect to https://mcp.asana.com/v2/mcp over Streamable HTTP and to authenticate with an Asana account when prompted. That hosted endpoint is not the package on this page and its tool list is not enumerated here.

  6. [6]

    modelcontextprotocol.io: Connect to local MCP serversaccessed 2026-08-03

    The Claude Desktop config file location and the editing flow.

  7. [7]

    Claude Code docs: MCPaccessed 2026-08-03

    The claude mcp add syntax for local stdio servers, including the -e flag for environment variables.

  8. [8]

    Cursor docs: Model Context Protocolaccessed 2026-08-03

    The mcp.json shape and file locations.

  9. [9]

    Routines: Connectorsaccessed 2026-08-03

    How Routines runs one-click OAuth connectors and any MCP server.

This page describes Asana as it behaved in one dated run on one Mac. Versions move: if something here no longer matches what you see, the capture date at the top says how old the reading is.

Behind this directory

Routines, the app behind this directory, runs MCP servers like this one without a terminal: see how connectors work. Your notes stay markdown files on your Mac, there is no cloud bill, and it works offline. Download Routines