Skip to main content
Glama
cristip73
by cristip73

asana_search_projects

Find Asana projects by name pattern matching across workspaces or teams, with options to filter archived projects and control result details.

Instructions

Search for projects in Asana using name pattern matching

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
workspaceNoThe workspace to search in (optional if DEFAULT_WORKSPACE_ID is set)
teamNoThe team to filter projects on
name_patternYesRegular expression pattern to match project names
archivedNoOnly return archived projects
limitNoResults per page (1-100)
offsetNoPagination offset token
opt_fieldsNoComma-separated list of optional fields to include

Implementation Reference

  • MCP tool handler switch case that destructures input arguments and calls the AsanaClientWrapper.searchProjects method to execute the tool logic.
    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) }], }; }
  • Tool schema definition with input schema for parameters like workspace, name_pattern, team, archived, pagination options.
    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"] } };
  • Registration of the tool in the exported tools array used by MCP, imported from project-tools.ts.
    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 ];
  • Core helper method in AsanaClientWrapper that implements the search logic: prepares params for Asana.ProjectsApi.getProjects, handles pagination, applies name pattern regex filter, and error handling.
    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; } }
  • Input parameter validation specific to asana_search_projects in validateProjectParameters.
    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;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cristip73/mcp-server-asana'

If you have feedback or need assistance with the MCP directory API, please join our Discord server