stats
View database statistics including total entries, category breakdown, and date range to understand memory store size and determine when to rebuild the index (threshold: 256 entries).
Instructions
Return database statistics: total entries, breakdown by category, and date range.
Useful for understanding the size and composition of the memory store, and for deciding when to call rebuild_index (threshold: 256+ entries).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/longmem/server.py:704-718 (handler)The MCP tool handler for 'stats'. Decorated with @mcp.tool(), it retrieves the store and calls get_stats(), returning the result as JSON.
# ── tool: stats ─────────────────────────────────────────────────────────────── @mcp.tool() async def stats() -> str: """ Return database statistics: total entries, breakdown by category, and date range. Useful for understanding the size and composition of the memory store, and for deciding when to call rebuild_index (threshold: 256+ entries). """ try: store, *_ = await _get_deps() data = await store.get_stats() return json.dumps(data, indent=2) except Exception as exc: return _db_error(exc) - src/longmem/store.py:735-777 (helper)The get_stats() method on SolutionStore that performs the actual statistics gathering: counts total rows, counts by category, and computes date range (with a 100k-row full scan limit).
async def get_stats(self) -> dict: """ Return summary statistics: total, by-category counts, date range. Total and per-category counts use count_rows() — efficient metadata reads that never load row data into RAM, regardless of DB size. Date range requires a full scan and is skipped for DBs > 100k entries. """ total = await self._table.count_rows() # Per-category counts — one lightweight count_rows(filter) per category. by_category: dict[str, int] = {} for cat in CATEGORIES: safe_cat = cat.replace("'", "''") n = await self._table.count_rows(f"category = '{safe_cat}'") if n > 0: by_category[cat] = n # Date range — full scan only for reasonably sized DBs. oldest = newest = None note: str | None = None if total <= self._STATS_FULL_SCAN_LIMIT: rows = await self._table.query().select(["created_at"]).to_list() dates = [r["created_at"] for r in rows if r.get("created_at")] oldest = min(dates) if dates else None newest = max(dates) if dates else None else: note = ( f"Date range skipped: DB has {total:,} entries. " "Run longmem-cursor rebuild-index to compact for faster scans." ) result: dict = { "total": total, "by_category": dict( sorted(by_category.items(), key=lambda kv: kv[1], reverse=True) ), "oldest_entry": oldest, "newest_entry": newest, } if note: result["note"] = note return result - src/longmem/store.py:62-74 (schema)The CATEGORIES list used by get_stats() to iterate over all possible categories for per-category counts.
CATEGORIES: list[str] = [ # infra & ops "ci_cd", "containers", "infrastructure", "cloud", "networking", "observability", "auth_security", # data & ML "data_pipeline", "ml_training", "model_serving", "experiment_tracking", # LLM / AI "llm_rag", "llm_api", "vector_db", "agents", # SWE "database", "api", "async_concurrency", "dependencies", "performance", "testing", "architecture", "other", ] - src/longmem/server.py:705-706 (registration)The @mcp.tool() decorator registers the stats function as a tool in the FastMCP server.
@mcp.tool() async def stats() -> str: