Files
koios/docs/tools/periplus.md
Robert Helewka db59266527 feat(personal): Sophia replaces Bourdain and Cousteau
Adds Sophia Petrillo (The Golden Girls) to the personal team and retires
Bourdain and Cousteau — a 2:1 merge, net -1 agent (10 -> 9 personal,
18 -> 17 total).

Why: the personal team casts fictional characters. Bourdain and Cousteau
are real people, one with significant baggage and one who died by suicide,
and neither had a dedicated MCP server or capability. Sophia is fictional,
plausibly owns both domains (an Italian grandmother knows food; tending
plants and the tank is housekeeping), and is the first personal agent to
actuate the house via the new Hecate MCP server.

Graph: Sophia inherits all 11 node types unchanged (Recipe, Restaurant,
Ingredient, Meal, Technique + Species, Plant, Tank, Garden, Ecosystem,
Observation). Uniqueness constraints are keyed on node label, not agent,
so there is no schema or data migration. Historical Note tags
(from:bourdain, to:cousteau) are deliberately left intact as an accurate
record. Schema bumped to 2.5.0.

Also:
- New docs/tools/hecate.md + prompts/tools/hecate.md, documenting the
  physical-actuation discipline (never guess a room or device slug) and
  stating plainly what Hecate cannot do yet: no sensor readings (Demeter
  is REST-only), no weather, and set_timer is routine-bound with no
  cancel — the conversational timer is coming to Daedalus.
- Shawn gains Periplus in the docs. The server was already wired in
  iolaus but never described in any prompt, so the model was handed a
  tool it was never told about — including the never-estimate-coordinates
  rule.
- Corrected stale counts (15/16/18 assistants -> 17) and the stale
  "Bowie's Domain" schema heading missed when David replaced Bowie.
- Removed utils/neo4j-schema-init.py.bak, a pre-Watson artifact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:24:16 -04:00

6.6 KiB

Periplus

Maps, bookmarks, collections, and directions — Robert's canonical store for geographic places.

What It Is

Periplus is the canonical store for places in Robert's life: addresses and points of interest, their actual coordinates, organized into collections (often one collection per trip or per category), with multi-hop directions between them. Backed by OpenStreetMap's Nominatim for place search and OSRM for routing.

Named for the ancient Greek periplus — the sailing manual that listed coastal landmarks in order. Same idea: the catalogue of places that matter, with the routes between them.

Periplus sits in the same relation to Neo4j that Kairos does for calendar and contacts: Periplus holds the canonical geographic record (the lat/lng, the bookmark, the collection); Neo4j holds the interpretation and cross-domain linking (what Robert did at the place, what restaurant Sophia recommended, what species she observed there).

⚠️ Critical Discipline: Never Estimate Coordinates

Models reliably misplace estimated coordinates — bookmarks for restaurants end up in the ocean.

When you need a place's coordinates, call search_places to look them up. Do not estimate or guess from memory. The typical workflow is:

  1. search_places("place name") to resolve the place via Nominatim
  2. Use the returned lat and lng to create_bookmark or other coordinate-consuming operations

This rule has no exceptions. Even for "obvious" landmarks where you think you know the coordinates, look them up.

MCP Tools

Tool Purpose
search_places Search OSM/Nominatim for addresses and places. Returns lat/lng + metadata. The first step for any place not already bookmarked.
search_bookmarks Search saved bookmarks by name / tag / source / collection. Returns existing bookmarks before you re-create them.
get_bookmark Fetch a single bookmark by UUID.

Bookmarks (creation)

Tool Purpose
create_bookmark Create a bookmark from coordinates (name, lat, lng, optional description/address/source/tags).
import_bookmarks Import a KML/KMZ/GPX/GeoJSON file from the server filesystem.

Geographic queries

Tool Purpose
find_bookmarks_nearby Find bookmarks near a point, sorted by distance. Includes distance_m.
find_bookmarks_in_area Find bookmarks within a bounding box (sw_lat/lng → ne_lat/lng).
get_directions Multi-hop directions between waypoints (semicolon-separated lat,lng pairs). Returns distance, duration, GeoJSON geometry, step-by-step instructions. Modes: car, bike, foot.

Collections

Tool Purpose
list_collections List all collections with bookmark and track counts.
get_collection Get a collection with its full bookmark list.
create_collection Create a new collection (name, optional description and tags).
add_bookmarks_to_collection Add bookmarks to a collection (comma-separated bookmark UUIDs).
remove_bookmark_from_collection Remove a bookmark from a collection (does not delete the bookmark).

Canonical Workflow — Find and Save a Place

1. search_places("Rideau Canal Ottawa")
   → [{lat: 45.4274, lng: -75.6919, name: "Rideau Canal", ...}]

2. create_collection("Ottawa Landmarks")
   → {id: "coll-uuid", ...}

3. create_bookmark(
       name="Rideau Canal",
       lat=45.4274, lng=-75.6919,
       address="Rideau Canal, Ottawa, Ontario",
       source="nominatim"
   )
   → {id: "bm-uuid", ...}

4. add_bookmarks_to_collection(
       collection_id="coll-uuid",
       bookmark_ids="bm-uuid"
   )

Steps 1 and 3 enforce the no-estimate rule: the coordinates passed to create_bookmark came from search_places, not from the model's head.

Who Uses Periplus

  • Nate — heavy, primary. One collection per trip, with the destinations, lodging, day-trip points of interest. Used alongside get_directions for itinerary logistics.
  • Sophia — restaurants, markets, butchers, nurseries, garden suppliers. Collections organized by city or by type. Sophia's Neo4j Restaurant and Ingredient nodes cross-link to Periplus bookmarks.
  • David — stores, theatres, studios, apothecaries — the places where culture and good taste live. Collections by city or by type.
  • Shawn — venues and addresses behind calendar events and contacts; the general-assistant catch-all for places that aren't anyone else's domain.
  • Other agents read Periplus when their work involves a place; the four above do the writing.

What It's Good For

  • Resolving "where is X" with real coordinates
  • Building a per-trip collection of places worth knowing about
  • Multi-hop routing for actual itinerary planning
  • Finding bookmarks near a point or in an area ("what's near the hotel")
  • Importing GPS tracks, KML waypoints, or other geo data

What It's Not Good For

  • Estimating coordinates without lookup. (Documented above; restating because it's the single most important rule.)
  • Cross-domain interpretation — Periplus holds the place; what Robert did or thought about the place belongs in Neo4j (Activity, Restaurant, Observation, etc.)
  • Real-time location tracking — Periplus is for places, not for "where is Robert right now"
  • Indoor navigation, building floor plans — Periplus is map-scale

Known Gotchas

  • Never estimate coordinates. Bears repeating because the failure mode is silent: a bookmark created with estimated lat/lng looks fine until someone tries to navigate to it and ends up at the wrong location. Always search_places first.
  • Nominatim's display_name is verbose. Use it for verification but pass cleaner names to create_bookmark (name field).
  • tags is a JSON string, not a dict. When passing tags to create_bookmark or create_collection, serialize the dict to a JSON string: '{"category": "restaurant"}', not {"category": "restaurant"} directly.
  • waypoints format is specific. get_directions expects semicolon-separated lat,lng pairs: "45.42,-75.70;45.50,-73.57". Get this wrong and routing fails silently.
  • Search before create. Before create_bookmark for a known place, run search_bookmarks to avoid duplicates. Bookmarks aren't deduplicated by coordinates automatically.
  • Collections are organizational, not exclusive. A bookmark can belong to multiple collections. Adding to one doesn't remove from another.
  • import_bookmarks reads server filesystem paths. The path must be absolute and accessible to the Periplus server, not the client.