get_planning_history
Analyze backlog trend by retrieving deltas for top-10 RICE-ranked snapshots, surfacing churn and score changes to show improvement.
Instructions
Return trend deltas (current vs ~7 days ago / vs window_days ago) for the top-10 RICE-ranked backlog snapshots archived by rank_backlog. Surfaces churn (entries added/dropped) plus the average score of the current top-10. Use when a user asks 'are we improving' / 'show me the trend' / 'is the same idea always at the top'. Returns {snapshots_count, trend_7d, trend_30d, summary}.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| window_days | No |
Implementation Reference
- The core handler function get_planning_history_tool that reads snapshots and computes trend deltas (7d/window_days) for the top-10 RICE-ranked backlog.
def get_planning_history_tool(arguments: dict) -> dict[str, Any]: """Return trend deltas (current vs ~7 days ago / vs ~30 days ago) for the top-10 RICE-ranked backlog. Surfaces churn (entries added/dropped) plus the average score of the current top-10. Args: window_days: int, default 30 — outer trend window. The 7d window is always computed in addition to window_days regardless of the value. """ window_days = int(arguments.get("window_days", 30)) all_snapshots = _read_snapshots() if not all_snapshots: return { "snapshots_count": 0, "trend_7d": {"avg_top10_score": 0.0, "new_top10_entries": [], "churned_top10_entries": []}, "trend_30d": {"avg_top10_score": 0.0, "new_top10_entries": [], "churned_top10_entries": []}, "summary": "No snapshots yet — call rank_backlog to start tracking.", } snaps_7d = _read_snapshots(window_days=7) snaps_window = _read_snapshots(window_days=window_days) trend_7d = _trend_block(snaps_7d or all_snapshots[-1:]) trend_window = _trend_block(snaps_window or all_snapshots[-1:]) latest = all_snapshots[-1] churn = len(trend_7d.get("new_top10_entries") or []) + len(trend_7d.get("churned_top10_entries") or []) parts = [ f"{len(all_snapshots)} snapshot(s) archived; latest {latest.get('timestamp', '?')}.", f"Top-10 list churned by {churn} entries in last 7 days.", ] new_entries = trend_7d.get("new_top10_entries") or [] if new_entries: parts.append(f"New into top-10 (7d): {', '.join(new_entries[:3])}.") return { "snapshots_count": len(all_snapshots), "window_days": window_days, "trend_7d": trend_7d, "trend_30d": trend_window, "summary": " ".join(parts), } - src/mk_plan_master/server.py:346-351 (schema)Input schema for get_planning_history: accepts optional window_days (integer, default 30).
inputSchema={ "type": "object", "properties": { "window_days": {"type": "integer", "default": 30}, }, }, - src/mk_plan_master/server.py:49-49 (registration)Registration of 'get_planning_history' mapping to history_tools.get_planning_history_tool in the TOOL_HANDLERS dict.
"get_planning_history": history_tools.get_planning_history_tool, - src/mk_plan_master/server.py:336-352 (registration)Tool registration with description and inputSchema via the MCP Tool object.
Tool( name="get_planning_history", description=( "Return trend deltas (current vs ~7 days ago / vs window_days ago) " "for the top-10 RICE-ranked backlog snapshots archived by " "rank_backlog. Surfaces churn (entries added/dropped) plus the " "average score of the current top-10. Use when a user asks 'are we " "improving' / 'show me the trend' / 'is the same idea always at " "the top'. Returns {snapshots_count, trend_7d, trend_30d, summary}." ), inputSchema={ "type": "object", "properties": { "window_days": {"type": "integer", "default": 30}, }, }, ), - Helper _trend_block that computes avg_top10_score, new/churned top-10 entries from snapshots; also _read_snapshots, _top10_ids, _avg_top10_score helpers used by the handler.
def _trend_block(snapshots: list[dict]) -> dict: if not snapshots: return {"avg_top10_score": 0.0, "new_top10_entries": [], "churned_top10_entries": []} latest = snapshots[-1] earliest = snapshots[0] latest_ids = _top10_ids(latest) earliest_ids = _top10_ids(earliest) return { "avg_top10_score": _avg_top10_score(latest), "new_top10_entries": sorted(latest_ids - earliest_ids), "churned_top10_entries": sorted(earliest_ids - latest_ids), "snapshots_in_window": len(snapshots), }