asana_search_tasks
Search tasks in Asana workspaces using text queries and advanced filters for assignees, projects, due dates, custom fields, and completion status to find specific work items.
Instructions
Search tasks in a workspace with advanced filtering options
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | No | The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set) | |
| text | No | Text to search for in task names and descriptions | |
| resource_subtype | No | Filter by task subtype (e.g. milestone) | |
| portfolios_any | No | Comma-separated list of portfolio IDs | |
| assignee_any | No | Comma-separated list of user IDs | |
| assignee_not | No | Comma-separated list of user IDs to exclude | |
| projects_any | No | Comma-separated list of project IDs | |
| projects_not | No | Comma-separated list of project IDs to exclude | |
| projects_all | No | Comma-separated list of project IDs that must all match | |
| sections_any | No | Comma-separated list of section IDs | |
| sections_not | No | Comma-separated list of section IDs to exclude | |
| sections_all | No | Comma-separated list of section IDs that must all match | |
| tags_any | No | Comma-separated list of tag IDs | |
| tags_not | No | Comma-separated list of tag IDs to exclude | |
| tags_all | No | Comma-separated list of tag IDs that must all match | |
| teams_any | No | Comma-separated list of team IDs | |
| followers_not | No | Comma-separated list of user IDs to exclude | |
| created_by_any | No | Comma-separated list of user IDs | |
| created_by_not | No | Comma-separated list of user IDs to exclude | |
| assigned_by_any | No | Comma-separated list of user IDs | |
| assigned_by_not | No | Comma-separated list of user IDs to exclude | |
| liked_by_not | No | Comma-separated list of user IDs to exclude | |
| commented_on_by_not | No | Comma-separated list of user IDs to exclude | |
| due_on | No | ISO 8601 date string or null | |
| due_on_before | No | ISO 8601 date string | |
| due_on_after | No | ISO 8601 date string | |
| due_at_before | No | ISO 8601 datetime string | |
| due_at_after | No | ISO 8601 datetime string | |
| start_on | No | ISO 8601 date string or null | |
| start_on_before | No | ISO 8601 date string | |
| start_on_after | No | ISO 8601 date string | |
| created_on | No | ISO 8601 date string or null | |
| created_on_before | No | ISO 8601 date string | |
| created_on_after | No | ISO 8601 date string | |
| created_at_before | No | ISO 8601 datetime string | |
| created_at_after | No | ISO 8601 datetime string | |
| completed_on | No | ISO 8601 date string or null | |
| completed_on_before | No | ISO 8601 date string | |
| completed_on_after | No | ISO 8601 date string | |
| completed_at_before | No | ISO 8601 datetime string | |
| completed_at_after | No | ISO 8601 datetime string | |
| modified_on | No | ISO 8601 date string or null | |
| modified_on_before | No | ISO 8601 date string | |
| modified_on_after | No | ISO 8601 date string | |
| modified_at_before | No | ISO 8601 datetime string | |
| modified_at_after | No | ISO 8601 datetime string | |
| completed | No | Filter for completed tasks | |
| is_subtask | No | Filter for subtasks | |
| has_attachment | No | Filter for tasks with attachments | |
| is_blocked | No | Filter for tasks with incomplete dependencies | |
| is_blocking | No | Filter for incomplete tasks with dependents | |
| sort_by | No | Sort by: due_date, created_at, completed_at, likes, modified_at | modified_at |
| sort_ascending | No | Sort in ascending order | |
| opt_fields | No | Comma-separated list of optional fields to include | |
| custom_fields | No | Object containing custom field filters. Keys should be in the format "{gid}.{operation}" where operation can be: - {gid}.is_set: Boolean - For all custom field types, check if value is set - {gid}.value: String|Number|String(enum_option_gid) - Direct value match for Text, Number or Enum fields - {gid}.starts_with: String - For Text fields only, check if value starts with string - {gid}.ends_with: String - For Text fields only, check if value ends with string - {gid}.contains: String - For Text fields only, check if value contains string - {gid}.less_than: Number - For Number fields only, check if value is less than number - {gid}.greater_than: Number - For Number fields only, check if value is greater than number Example: { "12345.value": "high", "67890.contains": "urgent" } |
Input Schema (JSON Schema)
{
"properties": {
"assigned_by_any": {
"description": "Comma-separated list of user IDs",
"type": "string"
},
"assigned_by_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"assignee_any": {
"description": "Comma-separated list of user IDs",
"type": "string"
},
"assignee_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"commented_on_by_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"completed": {
"description": "Filter for completed tasks",
"type": "boolean"
},
"completed_at_after": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"completed_at_before": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"completed_on": {
"description": "ISO 8601 date string or null",
"type": "string"
},
"completed_on_after": {
"description": "ISO 8601 date string",
"type": "string"
},
"completed_on_before": {
"description": "ISO 8601 date string",
"type": "string"
},
"created_at_after": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"created_at_before": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"created_by_any": {
"description": "Comma-separated list of user IDs",
"type": "string"
},
"created_by_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"created_on": {
"description": "ISO 8601 date string or null",
"type": "string"
},
"created_on_after": {
"description": "ISO 8601 date string",
"type": "string"
},
"created_on_before": {
"description": "ISO 8601 date string",
"type": "string"
},
"custom_fields": {
"description": "Object containing custom field filters. Keys should be in the format \"{gid}.{operation}\" where operation can be:\n- {gid}.is_set: Boolean - For all custom field types, check if value is set\n- {gid}.value: String|Number|String(enum_option_gid) - Direct value match for Text, Number or Enum fields\n- {gid}.starts_with: String - For Text fields only, check if value starts with string\n- {gid}.ends_with: String - For Text fields only, check if value ends with string\n- {gid}.contains: String - For Text fields only, check if value contains string\n- {gid}.less_than: Number - For Number fields only, check if value is less than number\n- {gid}.greater_than: Number - For Number fields only, check if value is greater than number\n\nExample: { \"12345.value\": \"high\", \"67890.contains\": \"urgent\" }",
"type": "object"
},
"due_at_after": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"due_at_before": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"due_on": {
"description": "ISO 8601 date string or null",
"type": "string"
},
"due_on_after": {
"description": "ISO 8601 date string",
"type": "string"
},
"due_on_before": {
"description": "ISO 8601 date string",
"type": "string"
},
"followers_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"has_attachment": {
"description": "Filter for tasks with attachments",
"type": "boolean"
},
"is_blocked": {
"description": "Filter for tasks with incomplete dependencies",
"type": "boolean"
},
"is_blocking": {
"description": "Filter for incomplete tasks with dependents",
"type": "boolean"
},
"is_subtask": {
"description": "Filter for subtasks",
"type": "boolean"
},
"liked_by_not": {
"description": "Comma-separated list of user IDs to exclude",
"type": "string"
},
"modified_at_after": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"modified_at_before": {
"description": "ISO 8601 datetime string",
"type": "string"
},
"modified_on": {
"description": "ISO 8601 date string or null",
"type": "string"
},
"modified_on_after": {
"description": "ISO 8601 date string",
"type": "string"
},
"modified_on_before": {
"description": "ISO 8601 date string",
"type": "string"
},
"opt_fields": {
"description": "Comma-separated list of optional fields to include",
"type": "string"
},
"portfolios_any": {
"description": "Comma-separated list of portfolio IDs",
"type": "string"
},
"projects_all": {
"description": "Comma-separated list of project IDs that must all match",
"type": "string"
},
"projects_any": {
"description": "Comma-separated list of project IDs",
"type": "string"
},
"projects_not": {
"description": "Comma-separated list of project IDs to exclude",
"type": "string"
},
"resource_subtype": {
"description": "Filter by task subtype (e.g. milestone)",
"type": "string"
},
"sections_all": {
"description": "Comma-separated list of section IDs that must all match",
"type": "string"
},
"sections_any": {
"description": "Comma-separated list of section IDs",
"type": "string"
},
"sections_not": {
"description": "Comma-separated list of section IDs to exclude",
"type": "string"
},
"sort_ascending": {
"default": false,
"description": "Sort in ascending order",
"type": "boolean"
},
"sort_by": {
"default": "modified_at",
"description": "Sort by: due_date, created_at, completed_at, likes, modified_at",
"type": "string"
},
"start_on": {
"description": "ISO 8601 date string or null",
"type": "string"
},
"start_on_after": {
"description": "ISO 8601 date string",
"type": "string"
},
"start_on_before": {
"description": "ISO 8601 date string",
"type": "string"
},
"tags_all": {
"description": "Comma-separated list of tag IDs that must all match",
"type": "string"
},
"tags_any": {
"description": "Comma-separated list of tag IDs",
"type": "string"
},
"tags_not": {
"description": "Comma-separated list of tag IDs to exclude",
"type": "string"
},
"teams_any": {
"description": "Comma-separated list of team IDs",
"type": "string"
},
"text": {
"description": "Text to search for in task names and descriptions",
"type": "string"
},
"workspace": {
"description": "The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set)",
"type": "string"
}
},
"required": [],
"type": "object"
}
Implementation Reference
- src/tools/task-tools.ts:3-242 (schema)Tool schema definition with comprehensive input schema for task search parameters including filters, dates, custom fields, sorting, and pagination options.export const searchTasksTool: Tool = { name: "asana_search_tasks", description: "Search tasks in a workspace with advanced filtering options", inputSchema: { type: "object", properties: { workspace: { type: "string", description: "The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set)" }, text: { type: "string", description: "Text to search for in task names and descriptions" }, resource_subtype: { type: "string", description: "Filter by task subtype (e.g. milestone)" }, "portfolios_any": { type: "string", description: "Comma-separated list of portfolio IDs" }, "assignee_any": { type: "string", description: "Comma-separated list of user IDs" }, "assignee_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "projects_any": { type: "string", description: "Comma-separated list of project IDs" }, "projects_not": { type: "string", description: "Comma-separated list of project IDs to exclude" }, "projects_all": { type: "string", description: "Comma-separated list of project IDs that must all match" }, "sections_any": { type: "string", description: "Comma-separated list of section IDs" }, "sections_not": { type: "string", description: "Comma-separated list of section IDs to exclude" }, "sections_all": { type: "string", description: "Comma-separated list of section IDs that must all match" }, "tags_any": { type: "string", description: "Comma-separated list of tag IDs" }, "tags_not": { type: "string", description: "Comma-separated list of tag IDs to exclude" }, "tags_all": { type: "string", description: "Comma-separated list of tag IDs that must all match" }, "teams_any": { type: "string", description: "Comma-separated list of team IDs" }, "followers_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "created_by_any": { type: "string", description: "Comma-separated list of user IDs" }, "created_by_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "assigned_by_any": { type: "string", description: "Comma-separated list of user IDs" }, "assigned_by_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "liked_by_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "commented_on_by_not": { type: "string", description: "Comma-separated list of user IDs to exclude" }, "due_on": { type: "string", description: "ISO 8601 date string or null" }, "due_on_before": { type: "string", description: "ISO 8601 date string" }, "due_on_after": { type: "string", description: "ISO 8601 date string" }, "due_at_before": { type: "string", description: "ISO 8601 datetime string" }, "due_at_after": { type: "string", description: "ISO 8601 datetime string" }, "start_on": { type: "string", description: "ISO 8601 date string or null" }, "start_on_before": { type: "string", description: "ISO 8601 date string" }, "start_on_after": { type: "string", description: "ISO 8601 date string" }, "created_on": { type: "string", description: "ISO 8601 date string or null" }, "created_on_before": { type: "string", description: "ISO 8601 date string" }, "created_on_after": { type: "string", description: "ISO 8601 date string" }, "created_at_before": { type: "string", description: "ISO 8601 datetime string" }, "created_at_after": { type: "string", description: "ISO 8601 datetime string" }, "completed_on": { type: "string", description: "ISO 8601 date string or null"}, "completed_on_before": { type: "string", description: "ISO 8601 date string" }, "completed_on_after": { type: "string", description: "ISO 8601 date string" }, "completed_at_before": { type: "string", description: "ISO 8601 datetime string" }, "completed_at_after": { type: "string", description: "ISO 8601 datetime string" }, "modified_on": { type: "string", description: "ISO 8601 date string or null" }, "modified_on_before": { type: "string", description: "ISO 8601 date string" }, "modified_on_after": { type: "string", description: "ISO 8601 date string" }, "modified_at_before": { type: "string", description: "ISO 8601 datetime string" }, "modified_at_after": { type: "string", description: "ISO 8601 datetime string" }, completed: { type: "boolean", description: "Filter for completed tasks" }, is_subtask: { type: "boolean", description: "Filter for subtasks" }, has_attachment: { type: "boolean", description: "Filter for tasks with attachments" }, is_blocked: { type: "boolean", description: "Filter for tasks with incomplete dependencies" }, is_blocking: { type: "boolean", description: "Filter for incomplete tasks with dependents" }, sort_by: { type: "string", description: "Sort by: due_date, created_at, completed_at, likes, modified_at", default: "modified_at" }, sort_ascending: { type: "boolean", description: "Sort in ascending order", default: false }, opt_fields: { type: "string", description: "Comma-separated list of optional fields to include" }, custom_fields: { type: "object", description: `Object containing custom field filters. Keys should be in the format "{gid}.{operation}" where operation can be: - {gid}.is_set: Boolean - For all custom field types, check if value is set - {gid}.value: String|Number|String(enum_option_gid) - Direct value match for Text, Number or Enum fields - {gid}.starts_with: String - For Text fields only, check if value starts with string - {gid}.ends_with: String - For Text fields only, check if value ends with string - {gid}.contains: String - For Text fields only, check if value contains string - {gid}.less_than: Number - For Number fields only, check if value is less than number - {gid}.greater_than: Number - For Number fields only, check if value is greater than number Example: { "12345.value": "high", "67890.contains": "urgent" }` } }, required: [] } };
- src/tool-handler.ts:61-102 (registration)Registration of the searchTasksTool in the main tools array exported for MCP protocol.export const tools: Tool[] = [ listWorkspacesTool, searchProjectsTool, getProjectTool, getProjectTaskCountsTool, getProjectSectionsTool, createSectionForProjectTool, createProjectForWorkspaceTool, updateProjectTool, reorderSectionsTool, getProjectStatusTool, getProjectStatusesForProjectTool, createProjectStatusTool, deleteProjectStatusTool, searchTasksTool, getTaskTool, createTaskTool, updateTaskTool, createSubtaskTool, getMultipleTasksByGidTool, addTaskToSectionTool, getTasksForSectionTool, getProjectHierarchyTool, getSubtasksForTaskTool, getTasksForProjectTool, getTasksForTagTool, getTagsForWorkspaceTool, addTagsToTaskTool, addTaskDependenciesTool, addTaskDependentsTool, setParentForTaskTool, addFollowersToTaskTool, getStoriesForTaskTool, createTaskStoryTool, getTeamsForUserTool, getTeamsForWorkspaceTool, addMembersForProjectTool, addFollowersForProjectTool, getUsersForWorkspaceTool, getAttachmentsForObjectTool, uploadAttachmentForObjectTool, downloadAttachmentTool
- src/tool-handler.ts:158-164 (handler)Dispatcher handler in tool_handler switch statement that extracts parameters and delegates to AsanaClientWrapper.searchTasks method.case "asana_search_tasks": { const { workspace, ...searchOpts } = args; const response = await asanaClient.searchTasks(workspace || undefined, searchOpts); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }
- src/asana-client-wrapper.ts:200-325 (handler)Core handler implementation in AsanaClientWrapper: processes all search options, handles custom fields, pagination via Asana TasksApi.searchTasksForWorkspace, transforms response with custom field display values.async searchTasks(workspace: string | undefined, searchOpts: any = {}) { try { // Use default workspace if not specified and available if (!workspace && this.defaultWorkspaceId) { workspace = this.defaultWorkspaceId; } if (!workspace) { throw new Error("No workspace specified and no default workspace ID set"); } // Extract pagination parameters const { auto_paginate = false, max_pages = 10, limit, offset, // Extract other known parameters text, resource_subtype, completed, is_subtask, has_attachment, is_blocked, is_blocking, sort_by, sort_ascending, opt_fields, ...otherOpts } = searchOpts; // Build search parameters const searchParams: any = { ...otherOpts // Include any additional filter parameters }; // Handle custom fields if provided if (searchOpts.custom_fields) { if (typeof searchOpts.custom_fields == "string") { try { searchOpts.custom_fields = JSON.parse(searchOpts.custom_fields); } catch (err) { if (err instanceof Error) { err.message = "custom_fields must be a JSON object : " + err.message; } throw err; } } Object.entries(searchOpts.custom_fields).forEach(([key, value]) => { searchParams[`custom_fields.${key}`] = value; }); delete searchParams.custom_fields; // Remove the custom_fields object since we've processed it } // Add optional parameters if provided if (text) searchParams.text = text; if (resource_subtype) searchParams.resource_subtype = resource_subtype; if (completed !== undefined) searchParams.completed = completed; if (is_subtask !== undefined) searchParams.is_subtask = is_subtask; if (has_attachment !== undefined) searchParams.has_attachment = has_attachment; if (is_blocked !== undefined) searchParams.is_blocked = is_blocked; if (is_blocking !== undefined) searchParams.is_blocking = is_blocking; if (sort_by) searchParams.sort_by = sort_by; if (sort_ascending !== undefined) searchParams.sort_ascending = sort_ascending; if (opt_fields) searchParams.opt_fields = opt_fields; // Add pagination parameters if (limit !== undefined) { // Ensure limit is between 1 and 100 searchParams.limit = Math.min(Math.max(1, Number(limit)), 100); } if (offset) searchParams.offset = offset; // Use the paginated results handler for more reliable pagination const results = await this.handlePaginatedResults( // Initial fetch function () => this.tasks.searchTasksForWorkspace(workspace, searchParams), // Next page fetch function (nextOffset) => this.tasks.searchTasksForWorkspace(workspace, { ...searchParams, offset: nextOffset }), // Pagination options { auto_paginate, max_pages } ); // Transform the response to simplify custom fields if present return results.map((task: any) => { if (!task.custom_fields) return task; return { ...task, custom_fields: task.custom_fields.reduce((acc: any, field: any) => { const key = `${field.name} (${field.gid})`; let value = field.display_value; // For enum fields with a value, include the enum option GID if (field.type === 'enum' && field.enum_value) { value = `${field.display_value} (${field.enum_value.gid})`; } acc[key] = value; return acc; }, {}) }; }); } catch (error: any) { console.error(`Error searching tasks: ${error.message}`); // Add more detailed error handling for common issues if (error.message?.includes('Bad Request')) { // Check for common causes of Bad Request if (searchOpts.projects_any) { throw new Error(`Error searching tasks with projects_any: ${error.message}. Try using 'projects.any' instead of 'projects_any', or use getTasksForProject directly.`); } if (searchOpts.limit && (searchOpts.limit < 1 || searchOpts.limit > 100)) { throw new Error(`Invalid limit parameter: ${searchOpts.limit}. Limit must be between 1 and 100.`); } if (searchOpts.offset && !searchOpts.offset.startsWith('eyJ')) { throw new Error(`Invalid offset parameter: ${searchOpts.offset}. Offset must be a valid pagination token from a previous response.`); } // Generic bad request error with suggestions throw new Error(`Bad Request error when searching tasks. Check that all parameters are valid. Common issues: invalid workspace ID, invalid project reference, or incompatible search filters. ${error.message}`); } throw error; } }