asana_search_projects
Search for Asana projects using name pattern matching to quickly locate specific projects across workspaces and teams.
Instructions
Search for projects in Asana using name pattern matching
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | No | The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set) | |
| team | No | The team to filter projects on | |
| name_pattern | Yes | Regular expression pattern to match project names | |
| archived | No | Only return archived projects | |
| limit | No | Results per page (1-100) | |
| offset | No | Pagination offset token | |
| opt_fields | No | Comma-separated list of optional fields to include |
Input Schema (JSON Schema)
{
"properties": {
"archived": {
"default": false,
"description": "Only return archived projects",
"type": "boolean"
},
"limit": {
"description": "Results per page (1-100)",
"maximum": 100,
"minimum": 1,
"type": "number"
},
"name_pattern": {
"description": "Regular expression pattern to match project names",
"type": "string"
},
"offset": {
"description": "Pagination offset token",
"type": "string"
},
"opt_fields": {
"description": "Comma-separated list of optional fields to include",
"type": "string"
},
"team": {
"description": "The team to filter projects on",
"type": "string"
},
"workspace": {
"description": "The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set)",
"type": "string"
}
},
"required": [
"name_pattern"
],
"type": "object"
}
Implementation Reference
- src/asana-client-wrapper.ts:115-198 (handler)Core handler logic: prepares search parameters for Asana ProjectsApi.getProjects, handles pagination via handlePaginatedResults, filters results client-side by name_pattern regex.async searchProjects(workspace: string | undefined, namePattern: string, archived: boolean = false, opts: any = {}) { try { // Extrage parametrii noi const { team, limit, offset, auto_paginate = false, max_pages = 10, opt_fields, ...otherOpts } = opts; // Pregătește obiectul de parametri pentru cerere const searchParams: any = { ...otherOpts, archived }; // Adaugă workspace dacă este furnizat sau folosește cel implicit if (workspace) { searchParams.workspace = workspace; } else if (this.defaultWorkspaceId) { searchParams.workspace = this.defaultWorkspaceId; } // Adaugă team dacă este furnizat if (team) { searchParams.team = team; } // Verifică dacă avem cel puțin un parametru de filtrare (workspace sau team) if (!searchParams.workspace && !searchParams.team) { throw new Error("No workspace or team specified and no default workspace ID set"); } // Adaugă câmpuri opționale dacă sunt furnizate if (opt_fields) { searchParams.opt_fields = opt_fields; } else { searchParams.opt_fields = 'name,archived,created_at,modified_at,public,current_status'; } // Adaugă parametri de paginare if (limit !== undefined) { // Asigură-te că limita este între 1 și 100 searchParams.limit = Math.min(Math.max(1, Number(limit)), 100); } if (offset) { searchParams.offset = offset; } // Folosește handlePaginatedResults pentru a gestiona paginarea const projects = await this.handlePaginatedResults( // Funcția de fetch inițială () => this.projects.getProjects(searchParams), // Funcția de fetch pentru pagina următoare (nextOffset) => this.projects.getProjects({ ...searchParams, offset: nextOffset }), // Opțiuni de paginare { auto_paginate, max_pages } ); // Filtrează proiectele pe baza pattern-ului de nume if (namePattern) { const pattern = new RegExp(namePattern, 'i'); return projects.filter((project: any) => pattern.test(project.name)); } return projects; } catch (error: any) { console.error(`Error searching projects: ${error.message}`); // Adaugă gestionare detaliată a erorilor pentru situații comune if (error.message?.includes('Bad Request')) { if (opts.limit && (opts.limit < 1 || opts.limit > 100)) { throw new Error(`Invalid limit parameter: ${opts.limit}. Limit must be between 1 and 100.`); } throw new Error(`Error searching projects: ${error.message}. Check that all parameters are valid.`); } throw error; } }
- src/tool-handler.ts:145-156 (handler)Tool dispatch handler: destructures input args and calls AsanaClientWrapper.searchProjects, returns JSON stringified response.case "asana_search_projects": { const { workspace, name_pattern, archived = false, ...opts } = args; const response = await asanaClient.searchProjects( workspace || undefined, name_pattern, archived, opts ); return { content: [{ type: "text", text: JSON.stringify(response) }], }; }
- src/tools/project-tools.ts:3-43 (schema)MCP Tool schema: defines name, description, and detailed inputSchema with properties, required fields, and defaults.export const searchProjectsTool: Tool = { name: "asana_search_projects", description: "Search for projects in Asana using name pattern matching", inputSchema: { type: "object", properties: { workspace: { type: "string", description: "The workspace to search in (optional if DEFAULT_WORKSPACE_ID is set)" }, team: { type: "string", description: "The team to filter projects on" }, name_pattern: { type: "string", description: "Regular expression pattern to match project names" }, archived: { type: "boolean", description: "Only return archived projects", default: false }, limit: { type: "number", description: "Results per page (1-100)", minimum: 1, maximum: 100 }, offset: { type: "string", description: "Pagination offset token" }, opt_fields: { type: "string", description: "Comma-separated list of optional fields to include" } }, required: ["name_pattern"] } };
- src/tool-handler.ts:61-103 (registration)Tool registration: searchProjectsTool imported and included in the exported tools array used for MCP tool registration.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/utils/validation.ts:272-283 (helper)Validation helper: in validateProjectParameters, checks workspace GID format and requires name_pattern.case 'asana_search_projects': // Workspace-ul este opțional dacă DEFAULT_WORKSPACE_ID este setat if (params.workspace) { result = validateGid(params.workspace, 'workspace'); if (!result.valid) errors.push(...result.errors); } // Verifică pattern-ul de căutare if (!params.name_pattern) { errors.push("name_pattern is required"); } break;