Asana MCP

Live

OAUTH 2.1

TASK MANAGEMENT

Project Management

Asana MCP gives agents OAuth 2.1 authenticated access to your task management: create work, search the workspace, and post project status updates.

  • Per-user credentials: each call uses the actual user's token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Asana MCP
agent · Acme Q3
Run
What is on my plate this week, and is the website redesign on track?
S
asanamcp_get_my_tasks
78ms
Asana agent
9 tasks due this week, 3 overdue. Website redesign: 14 of 22 tasks complete, status on track, next milestone Oct 24.
Sources: 9 tasks, 2 projects
asanamcp
9 tasks
18:29
Message Claude...

Tools your work agent reaches for on Asana, scoped per user.

CALL ANY TOOL
Task management end to end: fetch your assignments, create and update work in bulk, search the workspace, and report project status.
asanamcp_add_comment
Add comment
Add a comment to a task. Use ONLY for human-authored discussion, feedback, questions, or additional context. Exactly one of text or html_text must be provided. Do NOT use for actions that are automatically logged (assignments, status changes, completion, field updates). Returns the created story with ID, content, author, and timestamp.
Parameters
Name
Type
Required
Description
task_id
string
Required
Globally unique identifier for the task. Example: '1234567890123456'
html_text
string
Optional
Exactly one of text or html_text must be provided. Allowed elements only: <body>, <strong>, <em>, <u>, <s>, <code>, <ol>, <ul>, <li>, <a>, <blockquote>, <pre>. Do not use <h1>, <h2>, <hr/>, or <img> here. Must be well-formed XML with a single root <body>...</body>. Only <a> may have custom attributes; any attribute on any other element is invalid. Do not use elements outside the allowed list (400). . <a> links: For <a> tags specifically, to make it easier to create @-mentions through the API, we only require that you provide the GID of the object you wish to reference. If you have access to that object, the API will automatically generate the appropriate href and other attributes for you. For example, to create a link to a task with GID "123", you can send the tag <a data-asana-gid="123"/> which will then be expanded to <a href="https://app.asana.com/0/0/123/f" data-asana-accessible="true" data-asana-dynamic="true" data-asana-type="task" data-asana-gid="123">Task Name</a>. You can also generate a link to a task in a specific project or tag by including a data-asana-project or data-asana-tag attribute in the <a> tag. All other attributes, as well as the contents of the tag, are ignored. To keep the contents of your tag and make a custom vanity link, include the property data-asana-dynamic="false" when setting the contents of the tag. You would send <a data-asana-gid="123" data-asana-dynamic="false">This is some custom text!</a> and receive <a data-asana-accessible="true" data-asana-dynamic="false" data-asana-type="task" data-asana-gid="123">This is some custom text!</a> If you do not have access to the referenced object when you try to create a link, the API will not generate an href for you, but will instead look for an href you provide. This allows you to write back <a> tags unmodified even if you do not have access to the resource. If you do not have access to the referenced object and no href is provided, your request will be rejected with a 400 Bad Request error. Similarly, if you provide neither a GID nor a valid href, the request will be rejected with the same error.
is_pinned
boolean
Optional
Pinned comments stay at the top of the task's activity feed.
opt_fields
string
Optional
Comma-separated list of optional fields to include in the response. Name each subfield explicitly as parent.child; wildcard and glob syntax such as parent.* is not supported. Returns gid,name,task,created_by,created_at,text,html_text,is_pinned by default. Example: 'name,assignee,due_on,completed'
text
string
Optional
Plain-text comment body. Exactly one of text or html_text must be provided. Example: 'This looks good, approved!'
asanamcp_create_project
Create project
asanamcp_create_project_confirm
Confirm create project
asanamcp_create_project_confirm_populate
Create project confirm populate
asanamcp_create_project_preview
Preview create project
asanamcp_create_project_status_update
Update create project status
asanamcp_create_task_confirm
Confirm create task
asanamcp_create_task_preview
Preview create task
asanamcp_create_task_preview_v4
Create task preview v4
asanamcp_delete_task
Delete task
asanamcp_get_agent
Get agent
asanamcp_get_attachments
Get attachments
asanamcp_get_items_for_portfolio
Get items for portfolio
asanamcp_get_me
Get me
asanamcp_get_portfolio
Get portfolio
asanamcp_get_portfolios
Get portfolios
asanamcp_get_project
Get project
asanamcp_get_projects
Get projects
asanamcp_get_status_overview
Get status overview
asanamcp_get_task
Get task
asanamcp_get_task_stories
Get task stories
asanamcp_get_teams
Get teams
asanamcp_get_user
Get user
asanamcp_get_users
Get users
asanamcp_log_widget_event
Log widget event
asanamcp_save_project_changes_confirm
Confirm save project changes
asanamcp_search_objects
Search objects
asanamcp_search_objects_internal
Search objects internal
asanamcp_search_tasks
Search tasks
asanamcp_update_tasks
Update tasks

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Asana tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["asanamcp"], toolNames: [
    "asanamcp_get_my_tasks",
    "asanamcp_create_tasks",
    "asanamcp_search_tasks"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "What tasks are due this week?" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["asanamcp"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Which of my projects are at risk this sprint?" }],
  tools,
});

// Execute the tool call with the user's vaulted Asana credential
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["asanamcp"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Create tasks for each action item from today's standup." }],
  tools,
});

// Tool call runs with the user's vaulted Asana credential
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["asanamcp"] }, pageSize: 100,
});

const agent = new Agent({
  name: "asana_work_agent",
  model: "gemini-2.5-pro",
  instruction: "Manage Asana tasks and projects for the signed-in user.",
  tools,
});

await agent.run("Post a status update to the Q3 launch project.");
Try these prompts
Copy any prompt into your agent. Each maps directly to an Asana tool. Click to copy, paste into your agent, done.
Stay on top of work
Copy the prompt
Copied
What tasks are assigned to me and due this week?
Copy the prompt
Copied
Search the workspace for tasks mentioning the pricing page.
Copy the prompt
Copied
Show every open task in the mobile app project, grouped by assignee.
Create and update
Copy the prompt
Copied
Create a task for each action item in this meeting summary.
Copy the prompt
Copied
Mark these 5 tasks complete and add a closing comment to each.
Copy the prompt
Copied
Draft the Q3 launch project and show me a preview before creating it.
Report status
Copy the prompt
Copied
Give me a status overview of the design team's projects.
Copy the prompt
Copied
Post an on-track status update to the website redesign project.
Copy the prompt
Copied
List my portfolios and the health of every project inside them.
SEE HOW AUTH WORKS
Your users connect once. Their Asana credentials stay vaulted, every call is scope-checked, and every action is logged.
1
Authorize
Your user connects
Asana MCP
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Asana MCP
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Asana MCP
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Asana MCP
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other project management connectors.
Engineering Teams
Engineering standup agent
Pulls commits from GitHub and GitLab, tracks issue movement in Jira, and posts a per-engineer standup brief to Slack. Each engineer's activity is read on their own delegated OAuth.
Engineering Teams
DevOps assistant agent
Polls GitHub for failing checks and stale PRs, opens Linear issues for the ones that need work, and posts a daily digest to Slack. It acts as the engineer, not a shared service account.
Engineering Teams
Slack triage
Polls Slack for new messages, classifies bugs and support requests with a LangGraph router, files GitHub issues or Zendesk tickets, and confirms in the thread.
People Ops and HR teams
Performance review collector
Collects review feedback from Airtable and Google Forms scoped to each manager's direct reports, writes per-employee summaries to Notion, and DMs the manager a Slack digest.
Test other agents
See the same per-user auth pattern across other project management connectors.
ENGINEERING
Engineering standup agent
Pull commits from GitHub and GitLab, track Jira issue movement, and post a per-engineer standup brief to Slack.
ENGINEERING
DevOps assistant agent
Poll GitHub for failing checks and stale pull requests, open Linear issues for the ones that need work, and digest to Slack.
ENGINEERING
Slack triage agent
Classify new Slack messages as bugs or support requests, file the GitHub issue or Zendesk ticket, and reply in the thread.
PEOPLE OPS
Performance review collector agent
Collect review feedback from Airtable and Google Forms per manager, summarise each report in Notion, and DM the digest in Slack.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Asana token looks fine in a demo. In production every task created, updated, or deleted is attributed to one service account, and you cannot tell who did what. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Asana today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Asana as the user or through a shared key?
As the user. Scalekit resolves the credential of the person who triggered the agent at request time, so every task created, comment posted, and status update in your audit trail is attributed to a real user, not a shared service account.
Where is the Asana token stored?
In an AES-256 encrypted vault with per-tenant namespacing. Tokens are resolved at request time, never enter LLM context, refresh automatically, and can be revoked from one dashboard.
Can I limit what the agent does in Asana?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example read and search tools without create or update. Scalekit also enforces scope checks before every API call.
What happens when a user revokes access?
The credential is invalidated at the next tool call. The call fails closed, other users' connections are unaffected, and the revocation is logged in the audit chain.
Can the agent permanently delete tasks?
Only if you let it. Asana's delete_task removes a task and its subtasks with no undo, so most teams exclude it from listScopedTools and keep the agent on create, update, and search. Asana MCP also ships preview tools, like create_task_preview and create_project_preview, that show the user a draft before anything is written.
What other MCP connectors does Scalekit support?
Scalekit runs the Linear MCP server, Monday MCP server, and ClickUp MCP server on the same per-user auth, token vault, and audit trail. Browse 500+ connectors in the MCP connector directory.
How do I build a Asana agent?
Follow a step-by-step tutorial: Build a Multi-User Asana Agent with Claude and Scalekit; Build a Multi-User Asana Agent with Mastra and Scalekit. Each one covers per-user auth, tool scoping, and working agent code for Asana.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""asanamcp"": {
""url"": ""https://mcp.scalekit.com/asanamcp"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.asanamcp]
url = ""https://mcp.scalekit.com/asanamcp""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""asanamcp"": {
""url"": ""https://mcp.scalekit.com/asanamcp"",
""type"": ""http""
}
}
}