pyp6xer_search_activities
Search for activities in a Primavera P6 XER file by name or activity ID using case-insensitive substring matching. Filter by project and limit results.
Instructions
Search activities by name or activity ID (case-insensitive substring match).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Text to search in activity codes and names | |
| cache_key | No | Cache key identifying the loaded XER file (set when calling pyp6xer_load_file) | default |
| proj_id | No | Project ID or short name; uses first project if omitted | |
| limit | No | Maximum number of results to return | |
| fields | No | Subset of field names to return; call pyp6xer_get_activity_schema to see available names |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- server.py:598-629 (handler)The pyp6xer_search_activities function is the handler/tool implementation. It searches activities by name or activity ID using case-insensitive substring matching. It retrieves tasks from the loaded XER cache, filters by query, and returns matching activities (up to limit).
@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)) def pyp6xer_search_activities( query: Annotated[str, Field(description="Text to search in activity codes and names")], cache_key: Annotated[str, Field(description="Cache key identifying the loaded XER file (set when calling pyp6xer_load_file)")] = "default", proj_id: Annotated[str | None, Field(description="Project ID or short name; uses first project if omitted")] = None, limit: Annotated[int, Field(description="Maximum number of results to return", ge=1, le=200)] = 20, fields: Annotated[list[str] | None, Field(description="Subset of field names to return; call pyp6xer_get_activity_schema to see available names")] = None, ctx: Context = None, ) -> str: """Search activities by name or activity ID (case-insensitive substring match). Args: query: Search string matched against task_code and name. cache_key: Cache key of the loaded file. proj_id: Optional project filter. limit: Maximum results to return (default 20). fields: Subset of fields to return per activity. Call pyp6xer_get_activity_schema for available names. Omit to return all fields. """ xer = _get_xer(ctx, cache_key) tasks = _get_tasks(xer, proj_id) q = query.lower() matches = [ t for t in tasks if q in t.task_code.lower() or q in t.name.lower() ][:limit] return json.dumps({ "query": query, "count": len(matches), "activities": [_task_to_dict(t, fields) for t in matches], }, indent=2) - server.py:598-606 (registration)The tool is registered as an MCP tool via the @mcp.tool decorator on line 598, with annotations marking it as read-only, non-destructive, idempotent, and not open-world.
@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)) def pyp6xer_search_activities( query: Annotated[str, Field(description="Text to search in activity codes and names")], cache_key: Annotated[str, Field(description="Cache key identifying the loaded XER file (set when calling pyp6xer_load_file)")] = "default", proj_id: Annotated[str | None, Field(description="Project ID or short name; uses first project if omitted")] = None, limit: Annotated[int, Field(description="Maximum number of results to return", ge=1, le=200)] = 20, fields: Annotated[list[str] | None, Field(description="Subset of field names to return; call pyp6xer_get_activity_schema to see available names")] = None, ctx: Context = None, ) -> str: - server.py:296-314 (schema)The pyp6xer_get_activity_schema tool documents the available field names (summary_fields and detail_fields) used by pyp6xer_search_activities. The ACTIVITY_SUMMARY_FIELDS list (lines 110-118) defines which fields are available for the search tool.
# ── SCHEMA DISCOVERY ───────────────────────────────────────────────────────── # --------------------------------------------------------------------------- @mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)) def pyp6xer_get_activity_schema() -> str: """Return the available field names for activity read tools. Use the returned field names with the `fields` parameter of pyp6xer_list_activities, pyp6xer_get_activity, and pyp6xer_search_activities to limit response size to only the columns you need. summary_fields are available on list_activities and search_activities. detail_fields are only available on get_activity (they require fetching relationships and resources which are not on the list view). """ return json.dumps({ "summary_fields": ACTIVITY_SUMMARY_FIELDS, "detail_fields": ACTIVITY_DETAIL_FIELDS, "note": ( - server.py:175-175 (helper)The _task_to_dict helper function converts a task object to a dictionary, used by pyp6xer_search_activities to format results.
def _task_to_dict(task, fields: list[str] | None = None) -> dict: - server.py:168-173 (helper)The _get_tasks helper retrieves tasks for a project (or all tasks), used by pyp6xer_search_activities to get the task list.
def _get_tasks(xer: Xer, proj_id: str | None): """Return tasks for a project (or all tasks if proj_id is None).""" if proj_id: return _get_project(xer, proj_id).tasks return list(xer.tasks.values())