The provenance-first personal graph engine behind Wend — the relationship memory layer for AI agents. People, organizations, and events with a source on every fact, human-confirmed AI writes, and an MCP server so any agent can plug in.
Strong domain-specific design with clear governance model (propose-then-confirm). Tool names use action verbs (propose*, find*, get*, flag*). Descriptions are detailed and context-aware (194 - 250 chars avg, well above baseline 194). All 11 tools have descriptions. Input schemas are complete with proper JSON Schema structure. However, parameter descriptions are inconsistent: some params lack descriptions (e.g., 'edits' array in proposeEditNode has no description; 'detail_name' in proposeAddDetail lacks guidance on valid values). Output schemas are not documented, LLMs cannot predict response structure. Error handling is mentioned in descriptions but not formalized. No tool annotations (readOnlyHint/destructiveHint) despite clear read/write distinction. Two meta-tools (search, execute) are indirect and add indirection vs. direct tool exposure.
Run one capability by exact name (discover names via `search`). Reads return graph data with provenance. Writes NEVER commit directly: they create proposals the user reviews and confirms — say so after proposing.
Look up existing nodes by (partial) name before proposing anything. Returns candidates with a match_quality tier (exact | strong | weak_partial). A weak_partial is a mid-word substring hit and is almost never the same entity — never treat it as an identity.
Propose a tracked commitment ('I owe them an intro', 'they'll send the deck'). Direction is user_to_other, other_to_user, or mutual; optional ISO due date.
Full profile of one node: attributes (with provenance source ids), links with their typed details, and tags.
Propose one attribute value on an EXISTING node. Every detail field is multi-value: adding never conflicts; replacing is proposeEditNode's job.
Output schemas not documented. LLMs cannot predict response structure (node objects, link details, match_quality tiers, similarity scores). Forces agents to guess field names and types.
Parameter descriptions incomplete. 'edits' array in proposeEditNode has no description of structure. 'detail_name' in proposeAddDetail lacks guidance on valid attribute names. 'query' in search lacks examples of semantic queries.
No tool annotations (readOnlyHint/destructiveHint/idempotentHint). Server clearly distinguishes read (find*, get*, recall*) vs. write (propose*, flag*) tools, but LLMs cannot see this distinction in the schema.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | 2026-07-28+ | v2 |
Propose a detail on an existing link (e.g. update the title on an employment link). Replaces the current value at confirm time.
Propose a typed relationship between two nodes (works_at, met_at, advisor, …). Unknown link types are minted per-user at confirm time, flagged created_by_ai. Optional details ride the link (role, dates, notes).
Propose a NEW person/organization/event/location node (plus initial attributes). Lands in the review queue; commit-time dedup absorbs typos and duplicates.
Propose explicit edits to an existing node: rename (old name preserved as an alias) or replace a detail value. This is the deliberate REPLACE path; additive facts belong in proposeAddDetail.
Semantic recall across the whole graph ('who do I know in fintech in SF?'). Requires an embedding provider. Returns the closest nodes with similarity scores.
Discover capabilities of this relationship-memory graph (people, organizations, events; every fact carries a source). Call with no arguments to list everything, or pass a query to filter. Returns names, descriptions, and JSON parameter schemas for use with `execute`.
Meta-tools (search, execute) add indirection. Agents must call search() to discover tool names, then execute() to run them. Direct tool exposure would be clearer and reduce round-trips.
Error handling not formalized. Descriptions mention 'review queue' and 'commit-time dedup' but no error responses documented. What happens if a node_id is invalid? If a link_type is unknown? If embedding fails?