This file provides guidance for contributors working with code in this repository.
# Build the project (uses esbuild)
npm run build
# Run in development mode with ts-node (requires Node.js 18+)
npm run dev
# Start the built server
npm run start
# Watch mode for TypeScript compilation
npm run watch
# Test with MCP Inspector UI (opens client on port 5173, server on port 3000)
npm run inspector
# Use custom ports if defaults are taken
CLIENT_PORT=5009 SERVER_PORT=3009 npm run inspector- Node.js 18+: Required for development and MCP Inspector
- Build/Start: Works on all modern Node.js versions (18+)
Use nvm to switch versions: nvm use 20
ASANA_ACCESS_TOKEN- Required. Your Asana personal access tokenREAD_ONLY_MODE- Optional. Set to'true'to disable all write operations
This is an enhanced MCP (Model Context Protocol) server that exposes comprehensive Asana functionality to AI assistants. It includes advanced batch operations, direct section assignment, and enterprise-grade reliability features.
src/index.ts- Entry point. Creates the MCP Server instance, initializes the Asana client, registers all handlers, and implements selective tool activationsrc/asana-client-wrapper.ts- Wraps theasananpm package, providing typed methods for all Asana API operations with enhanced error handlingsrc/tool-handler.ts- Defines thelist_of_toolsarray,READ_ONLY_TOOLSarray, and the maintool_handlerfunction that routes tool calls with HTML validation and error isolationsrc/prompt-handler.ts- Defines MCP prompts (task-summary, task-completeness, create-task) with filtered read-only mode supportsrc/resource-handler.ts- Exposes Asana workspaces and projects as MCP resources (readable viaasana://workspace/{gid}andasana://project/{gid}URIs)src/asana-validate-xml.ts- Validates HTML/XML content for Asana'shtml_notesandhtml_textfields with detailed error reporting
Tools are organized by functional categories for efficient workflow management:
asana_list_workspaces- List all available workspaces
asana_search_projects- Search for projects using name patternsasana_get_project- Get detailed project informationasana_get_project_task_counts- Get task counts for projectsasana_get_project_sections- Get project sectionsasana_create_project- Create new projects
asana_get_project_status- Get project status updatesasana_get_project_statuses- Get all status updates for a projectasana_create_project_status- Create new status updatesasana_delete_project_status- Delete status updates
asana_search_tasks- Advanced task search with 25+ filter optionsasana_get_task- Get detailed task informationasana_create_task- Create new tasks with direct section assignmentasana_create_task_with_subtasks- Create tasks with subtasks in one operationasana_update_task- Update existing tasksasana_delete_task- Delete tasks permanentlyasana_get_multiple_tasks_by_gid- Batch retrieve multiple tasksasana_add_project_to_task- Add tasks to projectsasana_remove_project_from_task- Remove tasks from projects
asana_create_subtask- Create individual subtasks
asana_batch_create_tasks- Create multiple tasks in batchasana_batch_update_tasks- Update multiple tasks in batchasana_batch_create_subtasks- Create multiple subtasks in batchasana_batch_delete_tasks- Delete multiple tasks in batchasana_batch_create_tasks_with_subtasks- Create tasks with subtasks in batch
asana_add_task_dependencies- Set task dependenciesasana_add_task_dependents- Set task dependentsasana_set_parent_for_task- Set parent-child relationships
asana_get_task_stories- Get task comments and storiesasana_create_task_story- Create comments with HTML support
asana_get_tag- Get tag detailsasana_get_tags_for_task- Get task tagsasana_get_tags_for_workspace- Get workspace tagsasana_update_tag- Update tag propertiesasana_delete_tag- Delete tagsasana_get_tasks_for_tag- Find tasks by tagasana_create_tag_for_workspace- Create new tagsasana_add_tag_to_task- Tag tasksasana_remove_tag_from_task- Remove task tags
asana_section_operations- Batch create/update/delete project sections
Each tool file exports Tool objects with name, description, and inputSchema following the MCP SDK types.
When adding a new tool, ensure you complete ALL of these steps:
-
Define the tool in
src/tools/<category>-tools.ts:- Export a
Toolobject withname,description,inputSchema - Use
asana_prefix for the tool name - Include comprehensive parameter descriptions
- Export a
-
Add API method in
src/asana-client-wrapper.ts:- Add the method that calls the Asana SDK
- Include proper error handling and type annotations
-
Register the tool in
src/tool-handler.ts:- Import the tool from the tools file
- Add to
all_toolsarray - If it's a READ-ONLY tool: Add tool name to
READ_ONLY_TOOLSarray - Add the
casehandler in the switch statement with HTML validation
-
Add to tool categories in
src/index.ts:- Add to appropriate
TOOL_CATEGORIESgroup - Update
TOOL_REGISTRYwith tool reference
- Add to appropriate
-
Update documentation in
README.md:- Add tool to the appropriate category section
- Include all parameters with descriptions and requirements
-
Test the tool:
- Build:
npm run build - Test using the MCP Inspector
- Verify HTML validation works for applicable parameters
- Build:
When READ_ONLY_MODE=true:
- Only tools listed in
READ_ONLY_TOOLSarray are available - Write tool calls return an error with clear messaging
- The
create-taskprompt is automatically filtered out
Important: When adding a new read-only tool, you MUST add its name to the READ_ONLY_TOOLS array in tool-handler.ts.
Source the helper script to get testing functions:
source scripts/test-mcp.sh
# List all available tools
mcp_list_tools
# Call a tool and get JSON result
mcp_call asana_list_workspaces '{}'
# Call a tool and parse the result
mcp_call_json asana_search_tasks '{"workspace":"YOUR_WORKSPACE_GID","completed":false}'
# Test a tool with expected result
mcp_test asana_list_workspaces '{}' 'length > 0'
# Run tag operations test suite
mcp_test_tags YOUR_WORKSPACE_GID
# Health check
mcp_health_checkMCP servers communicate via JSON-RPC 2.0 over stdio. You can test manually:
# Build first
npm run build
# Send JSON-RPC messages (requires jq)
echo '{"jsonrpc":"2.0","method":"initialize","id":0,"params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0"},"protocolVersion":"2024-11-05"}}' | node dist/index.js 2>/dev/nullThe Asana API uses dot notation for filter parameters (e.g., assignee.any, sections.all), but MCP tool schemas use underscore notation (e.g., assignee_any, sections_all) for JSON compatibility.
The searchTasks method in asana-client-wrapper.ts automatically maps underscore parameters to dot notation. If adding new search parameters, ensure they're included in the keyMappings object.
If search filters appear to be ignored:
- Check the parameter is in the
keyMappingsobject insearchTasks() - Verify the parameter name matches the Asana API documentation
- Test with an impossible filter value to confirm filtering is working
When tools fail with HTML validation errors:
- Ensure HTML tags are properly closed and nested
- Check that only supported Asana HTML tags are used
- Use plain text for
notesif HTML validation continues to fail - Review the detailed validation error messages for specific issues
Uses esbuild (build.js) to bundle TypeScript into a single ESM file. The version is injected at build time from package.json via __VERSION__ define.