@estebanforge/pi-asana
Asana Work Graph tool for Pi. Adds 12 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
Package details
Install @estebanforge/pi-asana from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@estebanforge/pi-asana- Package
@estebanforge/pi-asana- Version
1.4.0- Published
- Jul 22, 2026
- Downloads
- 434/mo · 153/wk
- Author
- estebanforge
- License
- MIT
- Types
- extension
- Size
- 175 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@estebanforge/pi-asana
Asana Work Graph tool for the pi coding agent. Adds 14 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
What it adds
| Tool | Purpose |
|---|---|
asana_search_objects |
Keyword search across an Asana workspace (one resource type per call: task / project / user / tag) |
asana_get_my_tasks |
Tasks assigned to the authenticated user (workspace required) |
asana_get_tasks |
Filtered task list (project / section / tag / assignee) |
asana_get_task |
Full detail for one task (notes truncated ~2000 chars) |
asana_get_task_description |
Full, untruncated notes/description for one task. Use when asana_get_task's truncation marker fires. |
asana_get_task_comments |
Most-recent human comments on a task (default: last 5, max 50). On-demand. |
asana_get_comment |
Full, untruncated text of one comment (story). Use when asana_get_task_comments's 700-char truncation marker fires. |
asana_get_project |
Full detail for one project (sections optional) |
asana_get_projects |
List projects in a workspace or team |
asana_get_status_overview |
Aggregated status report across projects |
asana_get_me |
Who am I in Asana + my workspaces |
asana_create_tasks |
Create up to 50 tasks in a single call. Write. |
asana_update_tasks |
Update up to 50 tasks in a single call. Write. |
asana_add_comment |
Add 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-apps → Create 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:
| Command | Effect |
|---|---|
/asana config |
Settings modal (TUI) to toggle the gate; status line elsewhere. |
/asana confirm on / /asana confirm off |
One-shot toggle. |
The value is persisted in <piDir>/pi-asana.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.
| Invocation | Maps to |
|---|---|
/asana me |
asana_get_me |
/asana my / /asana my incomplete / /asana my completed |
asana_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 create <text> |
asana_create_tasks |
/asana config |
Toggle the write review gate (settings modal in TUI) |
/asana confirm on|off |
Toggle the write review gate (one-shot) |
Bare /asana prints a usage reminder.
Tool selection guidance
Reach for them in this order:
asana_search_objects— when you do not know a GID.asana_get_me— identity + workspace membership lookup.asana_get_my_tasks— shortcut for "what is on my plate".asana_get_tasks/asana_get_project(s)— bulk read scoped to a project / section / tag / assignee.asana_get_task— full detail on one task.asana_get_task_description— the full, untruncated task notes/description.asana_get_tasktruncates notes to 2000 chars and prints a marker; reach for this when you need the whole body (acceptance criteria, background, implementation notes).asana_get_status_overview— aggregated status report (do not chain a search before it).asana_get_task_comments— clarifications and reviewer threads live in comments, not innotes. Pull on demand when the task context is a conversation, not a record. Each comment truncates at 700 chars; the footer names thestory_gidto pass toasana_get_comment.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).- 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 enumtask/project/user/tag); it does not accept a CSV. Call the tool once per type to fan out across types. - The
/tasksendpoint requires either project/section/tag, OR (assignee AND workspace).asana_get_my_tasksenforces this by makingworkspacea required parameter. - Asana enforces rate limits (~150 req/min per PAT). A 429 response surfaces a clear retry message.
- The 14-tool surface omits several official MCP tools that did not age well in an LLM agent context: interactive
*_previewtools (Claude/ChatGPT-only confirmation UI),get_attachments(binary blobs),search_tasks(Premium-only; overlapssearch_objects),get_portfolio*(niche),get_agent*(AI Teammates only), anddelete_task(destructive — add on request). - Do not pass secrets or PII in
notesortextarguments 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.