trackmcp
Back to directory

STDIO Rust MCP server for the Asana API

1 stars RustOthers Updated Apr 1, 2026

Documentation

asanamcp

Crates.io
docs.rs
CI
Coverage
License

MCP server for the Asana API.

Quick Start

1. Get an Asana Personal Access Token at https://app.asana.com/0/my-apps

2. Install:

bash
# Homebrew
brew install adlio/tap/asanamcp

# From crates.io
cargo install asanamcp

# From GitHub
cargo install --git https://github.com/adlio/asanamcp

3. Add to Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

json
{
  "mcpServers": {
    "asana": {
      "command": "asanamcp",
      "env": {
        "ASANA_TOKEN": "your-personal-access-token",
        "ASANA_DEFAULT_WORKSPACE": "your-workspace-gid"
      }
    }
  }
}

The `ASANA_DEFAULT_WORKSPACE` is optional but recommended if you work primarily in one workspace. When set, workspace-based operations (search, list projects, list users, etc.) will use this default, reducing the need to specify workspace GID in every request.

Testing the Server

bash
# Dump tool schemas (useful for debugging)
asanamcp --schema

# Dump a specific tool's schema
asanamcp --schema get

# Launch the MCP Inspector (interactive web UI)
make inspect

Tools

ToolDescription
`asana_workspaces`List all workspaces
`asana_get`Fetch any resource (projects, tasks, portfolios, etc.)
`asana_create`Create resources (tasks, comments, projects, etc.)
`asana_update`Update existing resources
`asana_delete`Permanently delete resources (irreversible)
`asana_link`Manage relationships (task↔project, dependencies, etc.)
`asana_task_search`Search for tasks with rich filters (assignee, due date, etc.)
`asana_resource_search`Search for resources by name (projects, templates, users, teams, etc.)

asana_get

Fetch any Asana resource with recursive traversal support.

json
{"resource_type": "portfolio", "gid": "123", "depth": -1}
resource_typegidOptions
`project`project GID
`portfolio`portfolio GID`depth`: traversal depth
`task`task GID`include_subtasks`, `include_dependencies`, `include_comments`
`my_tasks`workspace GID*Tasks assigned to current user
`workspace_favorites`workspace GID*`depth` for portfolio traversal
`workspace_projects`workspace GID*All projects in workspace
`workspace_templates`team GID (optional)Empty = all accessible templates
`workspace_tags`workspace GID*
`workspace_users`workspace GID*
`workspace_teams`workspace GID*
`project_tasks`project/portfolio GID`subtask_depth`
`task_subtasks`task GID
`task_comments`task GID
`status_update`status update GIDSingle status update by GID
`status_updates`parent GIDList status updates for a project/portfolio
`all_workspaces`(ignored)All accessible workspaces
`workspace`workspace GID
`project_template`template GID
`project_sections`project GID
`section`section GID
`tag`tag GID
`me`(ignored)Current authenticated user
`user`user GID
`team`team GID
`team_users`team GID
`project_custom_fields`project GID
`project_brief`brief GIDProject brief (Key Resources on Overview tab, NOT the Note tab)
`project_project_brief`project GIDGet project's brief via project GID

*Uses `ASANA_DEFAULT_WORKSPACE` if gid is empty.

Depth: `-1` = unlimited, `0` = none, `N` = N levels.

asana_create

json
{"resource_type": "task", "project_gid": "123", "name": "New task", "assignee": "me"}
resource_typeRequired fields
`task``project_gid` or `workspace_gid`*, `name`
`subtask``task_gid`, `name`
`project``workspace_gid` or `team_gid`, `name`
`project_from_template``template_gid`, `name`
`portfolio``workspace_gid`*, `name`
`section``project_gid`, `name`
`comment``task_gid`, `text`
`status_update``parent_gid`, `status_type`, `text`
`tag``workspace_gid`*, `name`
`project_duplicate``source_gid`, `name`
`task_duplicate``source_gid`, `name`
`project_brief``project_gid`, `html_text` (with `` tags)Key Resources on Overview tab (NOT the Note tab)

*Uses `ASANA_DEFAULT_WORKSPACE` if not provided.

asana_update

json
{"resource_type": "task", "gid": "123", "completed": true}

Supports: `task`, `project`, `portfolio`, `section`, `tag`, `comment`, `status_update`, `project_brief` (Key Resources on Overview tab, NOT the Note tab).

asana_delete

Permanently delete an Asana resource. This action is irreversible.

json
{"resource_type": "task", "gid": "123"}

Supports: `task`, `project`, `portfolio`, `section`, `tag`, `comment`, `status_update`, `project_brief`.

json
{"action": "add", "relationship": "task_project", "target_gid": "task123", "item_gid": "proj456"}
relationshiptargetitem
`task_project`task GIDproject GID
`task_tag`task GIDtag GID
`task_parent`task GIDparent task GID
`task_dependency`task GIDblocking task GID(s)
`task_dependent`task GIDdependent task GID(s)
`task_follower`task GIDuser GID(s)
`portfolio_item`portfolio GIDproject GID
`portfolio_member`portfolio GIDuser GID(s)
`project_member`project GIDuser GID(s)
`project_follower`project GIDuser GID(s)

Use `item_gid` for single items or `item_gids` for bulk operations.

Search for tasks with rich filtering options.

json
{"workspace_gid": "123", "text": "bug", "completed": false, "assignee": "me"}
FilterDescription
`workspace_gid`Workspace to search (uses default if not provided)
`text`Search in task name and notes
`assignee`User GID, `me`, or `null` for unassigned
`projects`Filter by project GID(s)
`tags`Filter by tag GID(s)
`sections`Filter by section GID(s)
`completed``true` or `false`
`due_on`, `due_on_before`, `due_on_after`Date filters (YYYY-MM-DD)
`sort_by``due_date`, `created_at`, `completed_at`, `likes`, `modified_at`
`sort_ascending``true` or `false`

Search for any Asana resource by name using typeahead. Use this to find projects, templates, users, teams, and more.

json
{"query": "CloudSmith", "resource_type": "project_template"}
ParameterDescription
`query`Search text (required)
`resource_type``project`, `project_template`, `portfolio`, `user`, `team`, `tag`, or `goal`
`workspace_gid`Workspace to search (uses default if not provided)
`count`Max results (default 20, max 100)

Library Usage

rust
use asanamcp::{AsanaClient, Resource};

#[tokio::main]
async fn main() -> Result {
    let client = AsanaClient::from_env()?;

    let workspaces: Vec = client
        .get_all("/workspaces", &[("opt_fields", "gid,name")])
        .await?;

    for ws in workspaces {
        println!("{}: {:?}", ws.gid, ws.fields.get("name"));
    }
    Ok(())
}

Development

bash
make ci         # Run all checks (fmt, lint, build, docs, test)
make test       # Run tests
make coverage   # Coverage report
make fmt        # Format code
make lint       # Run clippy
make inspect    # Open MCP Inspector web UI
make schema     # Dump tool schemas to stdout

License

MIT

Frequently asked questions

What is asanamcp?

asanamcp is STDIO Rust MCP server for the Asana API

How do I install asanamcp?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is asanamcp open source?

Yes — it is hosted on GitHub at https://github.com/adlio/asanamcp and has 1 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP