Repo-committed, project-scoped AI memory for coding agents — zero API keys, zero embeddings, zero external services. CLI + MCP server.
Bernard exposes 6 tools with clear naming (verb_noun pattern: search, add, list, invalidate, update, suggest) and reasonable descriptions (avg ~100 chars). All tools have input schemas using Zod with type definitions. However, parameter descriptions are minimal or missing context about constraints, valid values, and error recovery. Output schemas are not documented, responses are formatted as text blobs rather than structured objects. Error handling is basic (returns text messages but no recovery guidance). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles (WRITE, REVERSIBLE, READ_ONLY). Missing pagination for list/search despite potential for large result sets.
Add a new record to the memory store with type, title, content, and optional tags.
Mark a record as invalid, optionally indicating it was superseded by another record.
List all records in the memory store, optionally filtered by type or tag, sorted newest-first.
Search and retrieve records from the memory store using BM25 full-text search with optional type and tag filtering.
Fetch recent git commits and their diffs to suggest new records based on commit history.
Update an existing record with new type, title, content, or tags.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles. bernard_add and bernard_update are WRITE operations; bernard_invalidate is REVERSIBLE. LLMs cannot infer safety properties without explicit hints.
Output schemas not documented. All tools return text blobs via { content: [{ type: 'text', text: ... }] }. LLMs cannot parse structured results or chain tools (e.g., extract record IDs from search results for downstream update calls). Responses should return JSON objects with typed fields.
Parameter descriptions lack constraint details. 'type' param in bernard_add uses z.enum(TYPES) but description does not list valid values. 'n' in bernard_suggest has no min/max bounds. LLMs cannot validate inputs without explicit constraints in descriptions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 57 | 2026-07-28+ | v2 |
No pagination support. bernard_list and bernard_search can return unbounded results. Large result sets blow context windows. Missing limit/offset parameters and total count in responses.
Error responses lack recovery guidance. 'Record not found' or validation errors return plain text with no actionable next steps. Should include 'Try search_*() first' or list available options.