Edge-hosted second brain for capturing, enriching, searching, and managing markdown notes with semantic embeddings and AI-powered tagging
Five tools with clear verb-noun naming and documented schemas. Descriptions are present and actionable (avg 95 chars), explaining WHAT and WHEN. Input schemas use proper JSON Schema with types and descriptions. However, output schemas are not documented in the source, LLMs cannot predict return structure. Error handling is minimal; no recovery guidance or categorization. Missing tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles. capture_thought lacks idempotent guarantee documentation despite claiming idempotency in description.
Ingest a markdown note into the second brain. Idempotent on content hash.
Remove a document, its chunks, and all associated vectors.
Fetch a single document and its chunks by ID.
Return recent documents ordered by created_at DESC. Pass `since` to instead walk the change feed: documents with seq > since, ascending, for gap-free delivery.
Embed a query and retrieve semantically nearest chunks, hydrated from D1.
Output schemas not documented. LLMs cannot predict return structure (fields, types, pagination). capture_thought returns {id, deduped, summary?, tags?} but this is inferred from handlers.ts, not declared in tool schema.
Tool annotations missing. delete_thought is destructive (removes document + vectors), semantic_search is read-only, capture_thought is idempotent, but no destructiveHint, readOnlyHint, or idempotentHint in schema.
Error handling lacks recovery guidance. No error responses shown in tool definitions. If semantic_search fails or delete_thought fails, LLM has no guidance on retry strategy or alternatives.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 79 | 2026-07-28+ | v2 |
capture_thought description claims 'Idempotent on content hash' but no explicit guarantee in schema or error handling. If hash collision occurs or deduplication fails, LLM has no fallback.
list_recent 'since' parameter uses opaque seq cursor. No guidance on how to obtain initial seq value or handle gaps. Agents cannot discover the change-feed API without trial-and-error.