asana
List Asana workspaces, projects, sections, users, and tasks; search tasks in a workspace; get, create, update, and complete tasks; add and list comments (stories). Uses the Asana REST API with retries on rate limits. Use when the user needs Asana project management, task lists, search, assignments, or collaboration on tasks.
Published by
Sai Ko
—Sign in to rate
How to install
Point your Sulala Agent at this store, then install this skill.
- Set the registry URL (e.g. in
.env):
SKILLS_REGISTRY_URL=https://hub.sulala.ai/api/sulalahub/registryThen run: sulala skill install asana or install from the dashboard Skills page. This installs the latest version (currently v1.0.0); you can pin a specific version in your skill config if needed.
Skill files
README.md
---
name: asana
description: List Asana workspaces, projects, sections, users, and tasks; search tasks in a workspace; get, create, update, and complete tasks; add and list comments (stories). Uses the Asana REST API with retries on rate limits. Use when the user needs Asana project management, task lists, search, assignments, or collaboration on tasks.
credentials:
- ASANA_ACCESS_TOKEN
metadata:
sulala:
emoji: "✅"
requires:
bins:
- node
---
# Asana
Workspaces → projects → sections → tasks; list users for assignees; **search** tasks in a workspace; **get / update / complete** tasks; **comments** (stories). All HTTP calls go through shared helpers: non-2xx responses are surfaced on stderr and exit non-zero; **429 / 502 / 503 / 504** are retried with backoff (uses `Retry-After` when present).
Use the `exec` tool with `skill_id: "asana"` so `ASANA_ACCESS_TOKEN` from skill config is injected automatically.
## When to use
- List workspaces, projects, sections, tasks, and workspace users
- Search tasks by text in a workspace (see limitations below)
- Create tasks; fetch, update, or complete tasks; add or list comments
## Prerequisites
1. Add the `asana` skill to your agent.
2. Configure `ASANA_ACCESS_TOKEN` in skill settings.
## Setup
1. Sign in to [Asana](https://app.asana.com/0/my-apps).
2. Open **Developer Console** (from the Apps tab in your Asana account settings) or use **My Settings → Apps → Personal access tokens** (wording varies by Asana UI).
3. Create a **Personal access token** with scopes for tasks, projects, stories, and users as needed.
4. Paste the token into the skill config as `ASANA_ACCESS_TOKEN`.
OAuth access tokens from an Asana app work the same way if your deployment uses OAuth instead of a PAT.
## Typical flow
1. `list_workspaces.js` — pick a workspace `gid`.
2. `list_projects.js <workspace_gid>` — pick a project `gid`.
3. `list_sections.js <project_gid>` — pick a section `gid` (optional; list may be empty for list-style projects).
4. `list_workspace_users.js <workspace_gid>` — pick user `gid` for assignee fields.
5. `list_tasks_project.js` or `list_tasks_section.js` — inspect tasks (use `next_page.offset` for pagination).
6. `search_tasks.js <workspace_gid> "keywords"` — find tasks when GIDs are unknown (workspace search API).
7. `get_task.js <task_gid>` — full detail before update or comment.
8. `create_task.js` / `update_task.js` / `set_task_completed.js` / `add_story.js` — writes.
## Pagination
List endpoints accept optional **`limit`** and **`offset`** (after prior args). If the JSON response includes `next_page.offset`, pass that string as the **offset** argument for the next page. **Offset values are URL-encoded** by the scripts.
## Scripts
### Read
| Script | Purpose |
|--------|---------|
| `list_workspaces.js` | `[limit] [offset]` — workspaces (`gid`, `name`). |
| `list_projects.js` | `<workspace_gid> [limit] [offset]` — non-archived projects. |
| `list_sections.js` | `<project_gid> [limit] [offset]` — sections in a project. |
| `list_tasks_project.js` | `<project_gid> [limit] [offset]` — tasks in a project. |
| `list_tasks_section.js` | `<section_gid> [limit] [offset]` — tasks in a section. |
| `list_workspace_users.js` | `<workspace_gid> [limit] [offset]` — users (`gid`, `name`, `email`). |
| `get_task.js` | `<task_gid>` — task detail (notes, assignee, projects, memberships, due dates). |
| `list_stories.js` | `<task_gid> [limit] [offset]` — comments/system stories on a task. |
| `search_tasks.js` | `<workspace_gid> <text> [limit]` — full-text search (see notes). |
### Write
| Script | Purpose |
|--------|---------|
| `create_task.js` | `<project_gid> <task_name> [section_gid\|-]` — create task; optional section. |
| `update_task.js` | `<task_gid> [json_file\|-]` — PUT merge; JSON is the **inner** task object (see below). |
| `set_task_completed.js` | `<task_gid> <true\|false>` — mark complete or reopen. |
| `add_story.js` | `<task_gid> <comment_text>` — add a comment. |
## Exec examples
### List workspaces
```json
{
"skill_id": "asana",
"command": "node ./scripts/list_workspaces.js"
}
```
### List projects (page 2)
```json
{
"skill_id": "asana",
"command": "node ./scripts/list_projects.js 1234567890 50 eyJ..."
}
```
### List tasks in a project with pagination
```json
{
"skill_id": "asana",
"command": "node ./scripts/list_tasks_project.js 111222333 100"
}
```
Next page: use `next_page.offset` from the response as the third argument.
### Search tasks (workspace)
```json
{
"skill_id": "asana",
"command": "node ./scripts/search_tasks.js 9876543210 \"invoice reminder\" 25"
}
```
### List users (for assignee)
```json
{
"skill_id": "asana",
"command": "node ./scripts/list_workspace_users.js 9876543210"
}
```
### Get task
```json
{
"skill_id": "asana",
"command": "node ./scripts/get_task.js 444555666"
}
```
### Update task (inner `data` fields as JSON)
Rename, set due date, assign (user `gid` from `list_workspace_users.js`). Pipe JSON on stdin (second argument `-`):
```json
{
"skill_id": "asana",
"command": "echo '{\"name\":\"New title\",\"due_on\":\"2025-12-01\",\"assignee\":\"USER_GID\"}' | node ./scripts/update_task.js 444555666 -"
}
```
Alternatively pass a path to a small JSON file as the second argument instead of `-`.
### Complete / reopen task
```json
{
"skill_id": "asana",
"command": "node ./scripts/set_task_completed.js 444555666 true"
}
```
### Create task (unchanged)
In a section:
```json
{
"skill_id": "asana",
"command": "node ./scripts/create_task.js 111222333 'Ship release' SECTION_GID"
}
```
### Add comment
```json
{
"skill_id": "asana",
"command": "node ./scripts/add_story.js 444555666 'Blocked on vendor reply.'"
}
```
### List stories
```json
{
"skill_id": "asana",
"command": "node ./scripts/list_stories.js 444555666"
}
```
## Notes
- Responses are raw Asana API JSON (`data`, `next_page`, errors as returned by the API).
- **Search** (`search_tasks.js`) mirrors advanced search; it often requires a **paid tier** that includes the search API, indexes can lag **writes by ~10–60s**, and sort order may vary between calls — see [Asana search tasks](https://developers.asana.com/reference/searchtasksforworkspace).
- Common failures: **401** invalid/expired token; **403** missing scopes; **404** wrong/inaccessible `gid`; **400** invalid body (e.g. section not in project); **429** throttling (retried automatically, then fails after several attempts).
- List-style projects may have no sections; use `list_tasks_project.js` for those.
- Internal helper: `scripts/_asana_lib.js` (used by other scripts; not run directly).Comments
Sign in to leave a comment.
Loading comments…