@estebanforge/pi-asana-me

extensionmaintained

Asana Work Graph tool for Pi. Adds 16 LLM-callable tools (asana_*) that query the Asana REST API over plain HTTP. Mirrors a curated subset of the official Asana MCP tool set — no MCP server install required. Personal access token auth via ASANA_ACCE

by · v1.5.1 · published 2d ago

$ pi install npm:@estebanforge/pi-asana-me
downloads/mo
425
stars
0
last push
2d ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

425 downloads · last 12 weeks (weekly)

README

@estebanforge/pi-asana-me

Asana Work Graph tool for the pi coding agent. Adds 16 LLM-callable tools (asana_*) that query the Asana REST API over plain HTTP, mirroring a curated subset of the official Asana MCP tool set — no MCP server install required.

Install

pi install npm:@estebanforge/pi-asana-me

What it adds

ToolPurpose
asana_search_objectsKeyword search across an Asana workspace (one resource type per call: task / project / user / tag)
asana_get_my_tasksTasks assigned to the authenticated user (workspace required)
asana_get_tasksFiltered task list (project / section / tag / assignee)
asana_get_taskFull detail for one task (notes truncated ~2000 chars)
asana_get_task_descriptionFull, untruncated notes/description for one task. Use when asana_get_task's truncation marker fires.
asana_get_task_commentsMost-recent human comments on a task (default: last 5, max 50). On-demand.
asana_get_commentFull, untruncated text of one comment (story). Use when asana_get_task_comments's 700-char truncation marker fires.
asana_list_attachmentsList files + inline images attached to a task (metadata only; no binary).
asana_download_attachmentDownload one attachment to a local file, return the path. Asana-hosted files write to disk; external hosts (Drive/Dropbox/...) return a view_url.
asana_get_projectFull detail for one project (sections optional)
asana_get_projectsList projects in a workspace or team
asana_get_status_overviewAggregated status report across projects
asana_get_meWho am I in Asana + my workspaces
asana_create_tasksCreate up to 50 tasks in a single call. Write.
asana_update_tasksUpdate up to 50 tasks in a single call. Write.
asana_add_commentAdd a text or HTML comment to a task. Write.

Compact tool guidance is injected via the before_agent_start hook (no skill file, to keep token cost minimal). A /asana <verb> [args] slash command pins intent for direct invocation.

How it works

Asana publishes an MCP server (https://mcp.asana.com/v2/mcp) for AI clients, but MCP tokens are workspace-scoped and do not work with the Asana REST API — they are only valid against the MCP server. This extension calls the Asana REST API directly (https://app.asana.com/api/1.0/) with a personal access token, so the same API surface Asana documents publicly is available inside pi without requiring you to register an MCP app, configure OAuth, or install an MCP adapter.

Configuration

This extension reads only the ASANA_ACCESS_TOKEN environment variable. No file fallback, no other env vars, no config file, no keyring integration.

export ASANA_ACCESS_TOKEN="2/12345/67890:abcdef..."

Create a personal access token at https://app.asana.com/0/my-appsCreate personal access token. The token grants the same access your Asana user account has — no extra scopes to set.

If the environment variable is missing, every tool returns a single error message pointing to this section.

Write review gate (default on)

The three write tools (asana_add_comment, asana_create_tasks, asana_update_tasks) prompt you for review before posting:

  • Comments open in an editable preview — trim the model's prose, then accept (Enter) or cancel (Esc). The posted text is whatever you leave in the editor. The dialog title shows the target task's name and Asana URL, not just its GID.
  • Task batches show a readable summary and ask yes/no. Each task (and its parent, where set) renders as 'Name' (url) when resolvable.
  • Summaries resolve GIDs to names + URLs best-effort; any GID that can't be resolved falls back to gid: <gid>, so nothing ever blocks on a lookup miss.
  • In headless sessions (no interactive UI) the gate is skipped so unsupervised runs never deadlock, and no extra lookups are issued.

Toggle it:

CommandEffect
/asana configSettings modal (TUI) to toggle the gate; status line elsewhere.
/asana confirm on / /asana confirm offOne-shot toggle.

The value is persisted in <piDir>/pi-asana-me.json ({ "confirmWrite": bool }), where <piDir> is process.env.PI_CODING_AGENT_DIR || ~/.pi/agent. The asana-confirm-write flag is also registered for /settings visibility and the --asana-confirm-write CLI override, but the gate reads the JSON file.

Usage

You do not need to mention Asana. The agent reaches for these tools whenever a request touches Asana data:

What tasks do I have assigned this week?
Find the Wicket project in my workspace and list its incomplete tasks.
Show me the details of task 1234567890123456.
Create a task in the Bugs project: "Investigate flaky test",
  due Friday, assign it to me.
Mark task 1234567890123456 as complete.

Slash command (pinned intent): /asana <verb> prefills the editor with an explicit ask. Hit Enter to run.

InvocationMaps to
/asana measana_get_me
/asana my / /asana my incomplete / /asana my completedasana_get_my_tasks
/asana show <gid>asana_get_task
/asana project <gid>asana_get_project
/asana search <workspace> <query>asana_search_objects (defaults to resource_type=task)
/asana status <gid>...asana_get_status_overview
/asana comments <gid> [N]asana_get_task_comments (last N comments; default 5)
/asana comment <gid>asana_get_comment (full text of one comment)
/asana attachments <gid>asana_list_attachments (files + inline images on a task)
/asana download <gid>asana_download_attachment (fetch one attachment to disk)
/asana create <text>asana_create_tasks
/asana configToggle the write review gate (settings modal in TUI)
/asana confirm on|offToggle the write review gate (one-shot)

Bare /asana prints a usage reminder.

Tool selection guidance

Reach for them in this order:

  1. asana_search_objects — when you do not know a GID.
  2. asana_get_me — identity + workspace membership lookup.
  3. asana_get_my_tasks — shortcut for "what is on my plate".
  4. asana_get_tasks / asana_get_project(s) — bulk read scoped to a project / section / tag / assignee.
  5. asana_get_task — full detail on one task.
  6. asana_get_task_description — the full, untruncated task notes/description. asana_get_task truncates notes to 2000 chars and prints a marker; reach for this when you need the whole body (acceptance criteria, background, implementation notes).
  7. asana_get_status_overview — aggregated status report (do not chain a search before it).
  8. asana_get_task_comments — clarifications and reviewer threads live in comments, not in notes. Pull on demand when the task context is a conversation, not a record. Each comment truncates at 700 chars; the footer names the story_gid to pass to asana_get_comment.
  9. asana_get_comment — the full, untruncated body of a single comment. Reach for it when a comment's truncation marker fired and that comment is the work (a decision, a Q&A, a spec).
  10. asana_list_attachments — files uploaded to a task AND images pasted inline into comments both live here. Call it whenever a task or comment references an attached file/image, to discover the attachment_gid for the next step.
  11. asana_download_attachment — fetch one attachment's bytes to a local file (returns the path). Run the read tool on the path to view an image, or parse a csv/xls/json from disk. External hosts (Drive/Dropbox/Box/OneDrive) return a view_url instead of a file.
  12. Write tools (create_tasks, update_tasks, add_comment) — only after you have the IDs. The extension shows the drafted payload for accept/edit/cancel; you do not need to ask the user first.

Notes

  • These tools make real calls against your Asana workspace. Write tools (create_tasks, update_tasks, add_comment) prompt you for review before posting when the write review gate is on (default); see Configuration.
  • The typeahead endpoint (asana_search_objects) accepts only ONE resource type per call (single enum task / project / user / tag); it does not accept a CSV. Call the tool once per type to fan out across types.
  • The /tasks endpoint requires either project/section/tag, OR (assignee AND workspace). asana_get_my_tasks enforces this by making workspace a required parameter.
  • Asana enforces rate limits (~150 req/min per PAT). A 429 response surfaces a clear retry message.
  • Downloaded attachments land in a per-process temp dir under os.tmpdir() (/tmp on Linux, the per-user sandbox temp on macOS, %TEMP% on Windows) that is wiped when the pi session ends, so files never accumulate and no cleanup routine is needed. Pass output_dir to asana_download_attachment only when you want to keep a file beyond the session; a caller-supplied dir is caller-owned and not auto-cleaned.
  • The 16-tool surface omits several official MCP tools that did not age well in an LLM agent context: interactive *_preview tools (Claude/ChatGPT-only confirmation UI), search_tasks (Premium-only; overlaps search_objects), get_portfolio* (niche), get_agent* (AI Teammates only), and delete_task (destructive — add on request). Attachments ARE supported, split into a metadata list (asana_list_attachments) and an on-demand disk download (asana_download_attachment) instead of the MCP server's binary-blob get_attachments.
  • Do not pass secrets or PII in notes or text arguments to write tools — they land in your Asana workspace directly.

License

MIT

Based on the Asana REST API and the Asana MCP V2 tool reference.