pyp6xer_list_projects
Retrieve a list of all projects from a loaded Primavera P6 XER file with summary statistics including project IDs, names, dates, activity counts, cost and schedule metrics.
Instructions
List all projects in the loaded XER file with summary statistics.
Returns project IDs, names, data date, finish date, activity counts, and high-level cost and schedule metrics.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cache_key | No | Cache key identifying the loaded XER file (set when calling pyp6xer_load_file) | default |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- server.py:411-449 (handler)The tool handler function pyp6xer_list_projects - lists all projects in the loaded XER file with summary statistics such as project IDs, names, dates, activity counts, and cost/schedule metrics. It retrieves the Xer object from the cache, iterates over projects, computes status breakdowns (not_started, in_progress, completed, critical), and returns JSON with proj_id, short_name, name, plan_start, data_date, finish_date, must_finish, total_activities, status counts, critical_activities, costs, and duration percents.
@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)) def pyp6xer_list_projects( cache_key: Annotated[str, Field(description="Cache key identifying the loaded XER file (set when calling pyp6xer_load_file)")] = "default", ctx: Context = None, ) -> str: """List all projects in the loaded XER file with summary statistics. Returns project IDs, names, data date, finish date, activity counts, and high-level cost and schedule metrics. """ xer = _get_xer(ctx, cache_key) result = [] for proj in xer.projects.values(): not_started = sum(1 for t in proj.tasks if t.status.is_not_started) in_progress = sum(1 for t in proj.tasks if t.status.is_in_progress) completed = sum(1 for t in proj.tasks if t.status.is_completed) critical = sum(1 for t in proj.tasks if t.is_critical) result.append({ "proj_id": proj.uid, "short_name": proj.short_name, "name": proj.name, "plan_start": _fmt_date(proj.plan_start_date), "data_date": _fmt_date(proj.data_date), "finish_date": _fmt_date(proj.finish_date), "must_finish": _fmt_date(proj.must_finish_date), "total_activities": len(proj.tasks), "not_started": not_started, "in_progress": in_progress, "completed": completed, "critical_activities": critical, "budgeted_cost": proj.budgeted_cost, "actual_cost": proj.actual_cost, "remaining_cost": proj.remaining_cost, "duration_percent": _fmt_pct(proj.duration_percent), "task_percent": _fmt_pct(proj.task_percent), "original_duration_days": proj.original_duration, "remaining_duration_days": proj.remaining_duration, }) return json.dumps(result, indent=2) - server.py:299-318 (registration)The @mcp.tool decorator registers pyp6xer_list_projects as an MCP tool with FastMCP, with annotations indicating it is read-only, non-destructive, idempotent, and not open-world. The function is defined at line 411 but the registration decorator pattern is the same as other tools like pyp6xer_get_activity_schema at line 299.
@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": ( "summary_fields: available on list_activities and search_activities. " "detail_fields: available on get_activity only." ), }, indent=2) - server.py:139-151 (helper)The _get_xer helper function is used by pyp6xer_list_projects to retrieve the Xer object from the shared in-memory cache using the provided cache_key.
def _get_cache(ctx: Context, cache_key: str) -> dict: cache = ctx.lifespan_context["cache"] if cache_key not in cache: raise ValueError( f"No file loaded with key '{cache_key}'. " "Call pyp6xer_load_file first." ) return cache[cache_key] def _get_xer(ctx: Context, cache_key: str) -> Xer: return _get_cache(ctx, cache_key)["xer"] - server.py:139-147 (helper)The _get_cache helper function retrieves the cached entry for a given cache_key from the lifespan context, raising a ValueError with instructions to call pyp6xer_load_file if the key is not found.
def _get_cache(ctx: Context, cache_key: str) -> dict: cache = ctx.lifespan_context["cache"] if cache_key not in cache: raise ValueError( f"No file loaded with key '{cache_key}'. " "Call pyp6xer_load_file first." ) return cache[cache_key]