pyp6xer_slipping_activities
Find activities running late where forecast finish exceeds baseline finish. Filter by minimum slip days to pinpoint delays.
Instructions
Find activities that are running late (forecast finish > baseline finish).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| 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 | |
| min_days_slip | No | Only return activities slipping by at least this many days |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- server.py:995-1001 (registration)Tool registration via @mcp.tool decorator on pyp6xer_slipping_activities function
@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)) def pyp6xer_slipping_activities( 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, min_days_slip: Annotated[int, Field(description="Only return activities slipping by at least this many days", ge=0)] = 0, ctx: Context = None, ) -> str: - server.py:996-1033 (handler)Actual handler implementation: finds activities running late (forecast finish > baseline finish), filters by min_days_slip, sorts descending by slip
def pyp6xer_slipping_activities( 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, min_days_slip: Annotated[int, Field(description="Only return activities slipping by at least this many days", ge=0)] = 0, ctx: Context = None, ) -> str: """Find activities that are running late (forecast finish > baseline finish). Args: cache_key: Cache key of the loaded file. proj_id: Optional project filter. min_days_slip: Only return activities slipping by at least this many days (default 0). """ xer = _get_xer(ctx, cache_key) tasks = _get_tasks(xer, proj_id) slipping = [] for t in tasks: if t.status.is_completed: continue try: forecast = t.finish except Exception: continue baseline = t.target_end_date slip = (forecast - baseline).days if slip > min_days_slip: d = _task_to_dict(t) d["forecast_finish"] = _fmt_date(forecast) d["slip_days"] = slip slipping.append(d) slipping.sort(key=lambda x: -x["slip_days"]) return json.dumps({ "slipping_count": len(slipping), "min_days_slip_filter": min_days_slip, "activities": slipping, }, indent=2)