Files
mop-skills/skills/datastore/SKILL.md
T

7.9 KiB

name, description
name description
datastore Structured personal data layer for OpenClaw powered by in-memory DuckDB and JSONL in git. Provides deterministic math, macro calculations, baby sleep interval tracking, and spatial radius search. Use whenever logging food, baby sleep, checking daily caloric balances, or querying places.

📦 Datastore: Structured Personal Data Layer

The datastore skill is the source of truth for all structured, repetitive, and mathematical data in OpenClaw. It stores data in git-versioned JSONL files in the Knowledge Wiki (knowledge-wiki/data/) and executes all calculations, aggregations, validations, and geospatial queries via in-memory DuckDB.


🎯 When to Use

  1. Personal Nutrition (nutrition.intake):
    • Logging meals, snacks, drinks, and ingredients.
    • Computes macros and calories deterministically (zero LLM math).
    • If a food_id from the food catalog is provided, macros are multiplied automatically from packaging reference values (per_100 * qty / 100).
  2. Baby Sleep (sleep.session):
    • Starting open sleep sessions when Mila falls asleep (end=None).
    • Closing sleep sessions when Mila wakes up (datastore_stop_event).
    • Logging completed nap or night intervals retroactively.
    • Querying average night durations, wake windows, and daily sleep totals.
  3. Daily Caloric Balances:
    • Summarizing daily protein, carbs, calories, and deficit against Garmin expenditures.
  4. Points of Interest (places):
    • Searching for beer gardens, playgrounds, stores, or farm stands within a given radius (e.g. 500m or 1km around Grabengasse 7) using native DuckDB spatial distance.
  5. Catalogs & Entities (foods, recipes, places, people):
    • Upserting and reading reference data.
  6. Baby Growth & WHO Curves (growth.measurement):
    • Logging weight (weight_kg) and height/length (height_cm).
    • Deterministic WHO child growth standards evaluation (P3, P50 Median, P97) based on exact age in months.

⛔ Core Guardrails & Protocol (MANDATORY)

  • NEVER compute arithmetic sums by hand: Always let DuckDB calculate daily totals, durations, and macronutrient sums via datastore_add_event, datastore_stop_event, or datastore_get_summary.
  • NEVER write structured log tables directly into Markdown files: Data goes into the datastore. Markdown view pages in knowledge-wiki/entities/ are read-only views generated from the datastore.
  • Always provide feedback from the datastore response: When logging an item, echo the DuckDB-calculated running day total (e.g. "Tag bisher: 85.5 g Eiweiß · 970 kcal") provided in the tool response.

🛠️ MCP Tools

1. datastore_add_event

Logs a point or interval event.

  • Parameters:
    • kind (string, required): e.g. 'nutrition.intake', 'sleep.session', 'feeding.bottle'.
    • subject (string, required): 'moritz', 'mila', or 'amelie'.
    • actor (string, required): e.g. 'agent:koch', 'agent:hebamme', 'moritz'.
    • payload (object, required):
      • For nutrition.intake: {"item": "...", "qty": 200, "unit": "g"|"ml", "protein_g": ..., "kcal": ...} (or {"food_id": "oatly-haferdrink", "qty": 200, "unit": "ml"}).
      • For sleep.session: {"type": "nap"|"night", "location": "bett"|"auto"|"kinderwagen"}.
    • start (string, optional): ISO 8601 timestamp (defaults to current time).
    • since (string, optional): Relative start offset backwards from now (e.g. '5m', '15m', '1h'). Use for "schläft seit X Min" to avoid LLM mental math!
    • end (string, optional): ISO 8601 timestamp. Leave empty for open sleep intervals!
    • meal (string, optional): e.g. 'Frühstück', 'Mittagessen', 'Snack'.
    • estimated (boolean, optional): Set to true if portions or nutrients are estimated.
    • note (string, optional): Context or notes.

2. datastore_stop_event

Closes the currently active open interval event (e.g. when Mila wakes up).

  • Parameters:
    • kind (string, required): 'sleep.session'.
    • subject (string, required): 'mila'.
    • end_time (string, optional): ISO timestamp (e.g. '2026-10-11T11:40:00+02:00'). Defaults to current time if omitted.
    • since (string, optional): Relative wake time offset backwards from now (e.g. '10m', '15m').
    • event_id (string, optional): Specific open event ID to close.

3. datastore_get_summary

Retrieves daily nutrition, sleep, and active status totals computed by DuckDB.

  • Parameters:
    • subject (string, required): 'moritz' or 'mila'.
    • date (string, optional): YYYY-MM-DD (defaults to today).

4. datastore_query

Executes a read-only DuckDB SQL query for custom analysis.

  • Parameters:
    • sql (string, required): e.g. "SELECT * FROM v_sleep_daily WHERE subject = 'mila' LIMIT 14".

5. datastore_find_places_near

Searches for points of interest within a radius in meters.

  • Parameters:
    • lat (number, required): e.g. 49.0205 (Grabengasse 7).
    • lon (number, required): e.g. 12.0975.
    • radius_m (number, optional, default: 1000).
    • category (string, optional): e.g. 'biergarten', 'spielplatz'.

6. datastore_put_entity

Upserts a reference entity into foods, recipes, places, or people.

  • Parameters:
    • collection (string, required): 'foods', 'recipes', 'places', or 'people'.
    • record (object, required): Full entity record with an 'id' field.

💻 CLI Usage

From the shell or scripts:

# Add food
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py add nutrition.intake \
  --subject moritz \
  --actor agent:koch \
  --meal Frühstück \
  --payload '{"item": "Haferflocken mit Skyr", "qty": 250, "unit": "g", "protein_g": 30.0, "kcal": 350.0}'

# Start Mila's nap (open interval)
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py add sleep.session \
  --subject mila \
  --actor agent:hebamme \
  --payload '{"type": "nap", "location": "kinderwagen"}'

# Start Mila's nap with relative time offset (e.g. asleep since 15 minutes)
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py add sleep.session \
  --subject mila \
  --actor agent:hebamme \
  --since "15m" \
  --payload '{"type": "nap", "location": "bett"}'

# Stop Mila's nap (closes open interval at current time)
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py stop sleep.session \
  --subject mila

# Stop Mila's nap retroactively with specific wake time
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py stop sleep.session \
  --subject mila \
  --end "2026-10-11T11:40:00+02:00"

# Stop Mila's nap retroactively with relative wake time (e.g. woke up 15 min ago)
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py stop sleep.session \
  --subject mila \
  --since "15m"

# Query daily summary
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py summary --subject moritz

# Radius search for beer gardens within 500m of Grabengasse 7
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py places \
  --lat 49.0205 --lon 12.0975 --radius 500 --category biergarten

# Nightly Garmin mirror sync
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/garmin_sync.py --days 2

# Log Mila's weight and height measurement
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py add growth.measurement \
  --subject mila \
  --actor agent:hebamme \
  --payload '{"weight_kg": 7.4, "height_cm": 67.5}'

# Retroactively log measurement with date
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/datastore.py add growth.measurement \
  --subject mila \
  --date 2026-06-15 \
  --payload '{"weight_kg": 5.8, "height_cm": 60.0}'

# Render Markdown views & HTML dashboards
PYTHONPATH=/home/node/mop-skills/mop-skills/skills/datastore/scripts \
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/render_views.py