Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Asana MCP server

Vendor MCP
Open markdown

The Asana MCP connector routes your AI agent's tool calls to Asana's own MCP server through Scalekit. Each user signs in to Asana once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 36 tools.

Tools
36
What they doRead · write · destructive
25 · 7 · 425 read7 write4 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Asana MCP connection

    In AgentKit > Connections, create an Asana MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Asana, so you don't need to register an OAuth app. To show your own app on the consent screen, use your own credentials instead.

    Use your own OAuth app

    Register your Scalekit environment with the Asana MCP connector so Scalekit handles the OAuth flow and token lifecycle for your users. Asana MCP requires a dedicated MCP app — not an API app or a personal access token.

    1. Copy the redirect URI from Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections > Create Connection.
      • Search for Asana MCP and click Create.
      • Copy the Redirect URI from the connection details panel. It looks like:
        https://<YOUR_ENV>.scalekit.cloud/sso/v1/oauth/conn_<ID>/callback
    2. Create an MCP app in Asana

      Asana developer console showing existing apps and the Create new app button

      • In the Create new app dialog:
        • Enter an App name, for example Agent Auth.
        • Under App type, select MCP app (“Connect LLMs to Asana”). Do not select API app.
        • Check I agree to the Asana API Terms.
        • Click Create app.

      Create new app dialog with MCP app type selected

    3. Add the redirect URI to your app

      • Inside your new MCP app, open the left menu and click OAuth.
      • Under Redirect URLs, click Add redirect URL, paste the redirect URI from Scalekit, and click Add.
    4. Copy your app credentials

      • In the same OAuth section, copy your Client ID and Client Secret.
    5. Add credentials in Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections and open the Asana MCP connection you created.
      • Enter:
        • Client ID — from your Asana MCP app
        • Client Secret — from your Asana MCP app
      • Click Save.
  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'asanamcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Asana MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'asanamcp_get_me',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • asanamcp_create_project_preview_v3Show a visual preview of a project structure before the project is created in Asana.Read-only

    Create Project Preview V3

    Show a visual preview of a project structure before the project is created in Asana. Do not use this tool for ordinary creation requests—use create_project instead when the user asks to create, set up, or add a project (with or without sections and tasks). Call this tool only when the user explicitly asks to preview first, see the plan before creating, review or confirm before creating, or postpone creation until they approve. Tasks in `sections` may include optional `subtasks` arrays (one level only; limit to no more than 5 per task unless necessary).

    Inputs

    project_namestringrequired
    Name of the project to create. Example: 'Q4 Product Launch'
    sectionsarrayrequired
    Users will give you a request to create a project with a certain purpose. Use your own knowledge of project management and the principles and guidance below to design the best project structure possible. JSON array of section objects. Each section must have: - sectionName (string): Name of the section. - tasks (array): Array of task objects. Each task object must have: - taskName (string): Name of the task. - description (string | null): Task details as Markdown (not raw HTML), or null. Use real list lines (`- item` or `1. item`); avoid one line of middot bullets — they will not become lists. The preview rich-text supports headings **h1** and **h2**, marks **strong**, **em**, **u**, **s**, inline **code**, and lists **ul** / **ol** / **li** — use the same constructs in Markdown. The server normalizes Markdown to HTML for the preview and Asana `html_notes`. - isComplete (boolean): Whether the task is completed. Defaults to false if not provided. - startDate (string | null): Start date of the task in YYYY-MM-DD format, or null if the task has no start date. If the start date is provided, the due date must also be provided. If both the start date and due date are provided, the due date must be greater than or equal to the start date. Defaults to null if not provided. - dueDate (string | null): Due date of the task in YYYY-MM-DD format, or null if the task has no due date. If both the start date and due date are provided, the due date must be greater than or equal to the start date. Defaults to null if not provided. - assignee (string | null): Assignee of the task, or null if the task is unassigned. This can be "me", an email, or a user GID chosen among those found using asana_get_workspace_users. Defaults to null if not provided. - priority ("low" | "medium" | "high" | null): Priority level of the task. Must be one of 'low', 'medium', 'high', or null. Defaults to null if not provided. This is general guidance for creating good project structures. Follow these principles and guidance as closely as possible unless the user specifically asks you to do otherwise: Create the project structure in the same language as the user's request. - Project should have >=4 sections. - Limit the number of tasks to no more than 5 tasks per section. - Limit sections up to 6. - Every section should have at least one task. - If the user does not specifically give you tasks they want to include in their project, make tasks for the project that are aligned with the project's purpose. - Only mark tasks as complete (isComplete: true) if the user specifically mentioned they already completed that work. Otherwise, all tasks should be incomplete (isComplete: false). - When adding dates to tasks, always provide BOTH startDate and dueDate together as a date range. Never provide only dueDate without startDate. Add date ranges to several tasks so they will be useful for timeline and calendar views when the project is created. - All dates must be in the future (today or later), never in the past. - Create logical, sequential timelines that make sense for the project's purpose. Tasks should progress in a meaningful order (e.g., beginner tasks before advanced tasks, setup tasks before execution tasks). - Dates should form a coherent timeline, not be randomly scattered. - Prefer including the 'priority' custom field for every task (one of 'low', 'medium', or 'high'), unless the user has specifically instructed you not to. This helps users organize their work by importance. - Tasks may include an optional 'subtasks' array (one level only). Limit to no more than 5 subtasks per task unless necessary. Each subtask has taskName and optionally description. Example: [ { "sectionName": "Backlog", "tasks": [ { "taskName": "Design homepage", "description": "Create a modern and responsive homepage design", "isComplete": false, "startDate": "2025-01-10", "dueDate": "2025-01-15", "assignee": "123456789", "priority": "high" }, { "taskName": "Write documentation", "description": null, "isComplete": false, "startDate": "2025-01-15", "dueDate": "2025-01-20", "assignee": "987654321", "priority": "medium" } ] }, { "sectionName": "In Progress", "tasks": [ { "taskName": "Implement API endpoints", "description": "Build RESTful API endpoints for user management", "isComplete": false, "startDate": "2025-01-10", "dueDate": "2025-01-25", "assignee": "123456789", "priority": "high" }, { "taskName": "Code review", "description": null, "isComplete": false, "startDate": "2025-01-25", "dueDate": "2025-01-30", "assignee": null, "priority": "medium" }, { "taskName": "Deploy to staging", "description": "Deploy the latest version to staging environment", "isComplete": false, "startDate": "2025-01-05", "dueDate": "2025-01-08", "assignee": "987654321", "priority": "high" } ] } ]
  • asanamcp_create_task_preview_v4Generates a visual preview of a single task and asks for confirmation before creation.Read-only

    Create Task Preview V4

    Generates a visual preview of a single task and asks for confirmation before creation. NON-DEFAULT tool for task creation: Use only when the user explicitly opts in with visually previewing, reviewing, or confirming a task before creation, or when the user implies they want to check or verify before the task is saved. Do not use when the user wants to create multiple tasks (2 or more) - use create_task or create_tasks instead. When the user's request implies a project, suggest a project via project_gid. When you set project_gid, it is preferable to also set section_gid when you can reasonably resolve a section (e.g. call get_project with include_sections true to list section GIDs for that project and match the user's intent); omit section_gid when the section is unknown, not specified, or irrelevant. When the user wants subtasks on the new task, pass a subtasks array (one level only; at most 5 subtasks; entries are not added to any project).

    Inputs

    taskNamestringrequired
    Name of the task. Example: 'Review Q4 report'
    assigneestring
    Assignee of the task, or null if the task is unassigned. This can be "me", an email, or a user GID chosen among those found using asana_get_workspace_users. Defaults to null if not provided. Example: 'me or 1234567890123456'
    descriptionstring
    Task details as Markdown (not raw HTML), or null. Use real list lines (`- item` or `1. item`); avoid one line of middot bullets — they will not become lists. The preview rich-text supports headings **h1** and **h2**, marks **strong**, **em**, **u**, **s**, inline **code**, and lists **ul** / **ol** / **li** — use the same constructs in Markdown. The server normalizes Markdown to HTML for the preview and Asana `html_notes`. Example: 'Please review the Q4 financial report.'
    dueDatestring
    Due date of the task in YYYY-MM-DD format, or null if the task has no due date. If both the start date and due date are provided, the due date must be greater than or equal to the start date. Defaults to null if not provided. Example: '2025-01-15'
    isCompleteboolean
    Whether the task is completed. Defaults to false if not provided.
    project_gidstring
    GID of an existing project to add the task to, or null. When you set this, it is preferable to also pass section_gid when you can resolve a section for that project (call get_project with include_sections true to list section GIDs for that project); omitting section_gid is fine when placement is unclear or irrelevant. Example: '1234567890123456'
    section_gidstring
    GID of an existing section to add the task to, or null. Project must also be set if section is provided, and the section must be in the project. Optional; omit when unknown or not specified. When project_gid is set, including section_gid is preferable if you can infer or look up a section (call get_project with include_sections true to list section GIDs for that project). Example: '1234567890123456'
    startDatestring
    Start date of the task in YYYY-MM-DD format, or null if the task has no start date. If the start date is provided, the due date must also be provided. If both the start date and due date are provided, the due date must be greater than or equal to the start date. Defaults to null if not provided. Example: '2025-01-10'
    subtasksarray
    Optional array of subtasks (one level only; subtasks are not added to any project). Limit to no more than 5 unless necessary. Each entry may include taskName (required), description, isComplete, startDate and dueDate (YYYY-MM-DD), and assignee (me, email, or user id). Example: [{"taskName": "Gather feedback", "assignee": "me"}]
  • asanamcp_get_agentReturns the full record for a single AI Teammate agent by GID.Read-only

    Get Agent

    Returns the full record for a single AI Teammate agent by GID. Includes name, description, behavior_guidance, workspace, and photo URLs. Use get_workspace_agents first to discover agent GIDs, then call this tool for full details.

    Inputs

    agent_gidstringrequired
    Globally unique identifier for the agent. Example: '1234567890123456'
    opt_fieldsstring
    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. Available fields: gid, resource_type, resource_subtype, name, description, behavior_guidance, workspace, photo. Example: 'name,assignee,due_on,completed'
  • asanamcp_get_attachmentsList all attachments for a project, project brief, or task.Read-only

    Get Attachments

    List all attachments for a project, project brief, or task. By default, returns attachment names, IDs, and URLs (download_url, permanent_url, view_url). To expose other attachment fields use opt_fields. Use for accessing files attached to Asana objects. Supports pagination for objects with many attachments.

    Inputs

    parentstringrequired
    The GID of the parent project, project_brief, or task to retrieve attachments for. Must be a GID for a project, project_brief, or task. Example: '1234567890123456'
    limitnumber
    Results per page (1-100). Maximum number of results to return per page (1-100). Example: 50
    offsetstring
    Pagination offset token. Pagination token copied from a previous response. Leave blank to fetch the first page. Example: 'eyJ0eXAiOiJKV1Qi'
    opt_fieldsstring
    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. Example: 'name,assignee,due_on,completed'
  • asanamcp_get_items_for_portfolioList projects, goals, and other items in a portfolio.Read-only

    Get Items for Portfolio

    List projects, goals, and other items in a portfolio. Returns item names, IDs, and types. Use for portfolio content exploration and management. Supports pagination for portfolios with many items.

    Inputs

    portfolio_gidstringrequired
    Globally unique identifier for the portfolio. Example: '1234567890123456'
    limitnumber
    Results per page (1-100). Maximum number of results to return per page (1-100). Example: 50
    offsetstring
    Pagination offset token. Pagination token copied from a previous response. Leave blank to fetch the first page. Example: 'eyJ0eXAiOiJKV1Qi'
    opt_fieldsstring
    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. Example: 'name,assignee,due_on,completed'
  • asanamcp_get_meGet details of current authenticated user.Read-only

    Get Me

    Get details of current authenticated user. Tools accept 'me' as a user identifier, so you rarely need to call this just to get the user's GID. Only call this when you need specific user details (e.g., name, email), when tools such as get_projects or search_objects require filtering results by user GID, or when tools do not accept 'me' as a user identifier.

    Inputs

    This tool takes no inputs.

  • asanamcp_get_my_tasksGet the current user's tasks.Read-only

    Get My Tasks

    Get the current user's tasks. Shortcut for common "what's on my plate" queries. Returns tasks assigned to the user. Use when the user asks about their tasks, workload, or what they need to do. If the user's request includes words like 'preview', 'visualization', or 'rendered view' in reference to seeing their tasks, you MUST use search_tasks_preview with assignee_any='me' instead. Do not use this to answer questions about project membership or ownership. Use get_me plus get_projects or search_objects instead.

    Inputs

    completed_sincestring
    Filter by completion. Use "now" for incomplete tasks only. Omit for all tasks. Use ISO datetime for tasks completed since a date.
    limitnumber
    Results per page (1-100). Default: 50. Maximum number of results to return per page (1-100).
    offsetstring
    Pagination offset token from the next_page field of a previous response. If omitted, returns the first page of results. Example: 'eyJ0eXAiOiJKV1Qi'
    opt_fieldsstring
    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,assignee,due_on,completed by default.
  • asanamcp_get_portfolioGet detailed portfolio data by ID including name, owner, and projects.Read-only

    Get Portfolio

    Get detailed portfolio data by ID including name, owner, and projects. Use after finding portfolio ID via search_objects. Returns complete portfolio configuration. Essential for understanding portfolio context and content.

    Inputs

    portfolio_gidstringrequired
    Globally unique identifier for the portfolio. Example: '1234567890123456'
    opt_fieldsstring
    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. Example: 'name,assignee,due_on,completed'