A local, offline tool for reviewing AI-authored design docs: renders Markdown to polished HTML, lets humans leave inline anchored comments, and exposes those comments via CLI and MCP so agents can revise and resolve them.
margin has 5 tools with clear verb-noun naming (list_docs, open_comments, resolve_thread, reply_thread, reopen_thread). Descriptions are present and moderately detailed (avg ~150 chars), explaining what each tool does and when to use it. However, parameter descriptions are sparse or missing entirely. open_comments has 3 parameters but only 'slug' has a description; 'all' and 'full' lack guidance on their purpose. resolve_thread and reply_thread parameters lack descriptions. Input schemas are present but minimal, most parameters are untyped strings with no constraints (enums, patterns, ranges). No output schemas are documented, forcing LLMs to infer response structure. Error handling is not visible in the tool definitions. The server is STDIO-only, which caps protocol readiness but does not directly penalize definition quality.
List the project's Markdown docs and how many open review comments each has.
Get a doc's review comment threads as compact JSON (t=thread id, b=block id, q=quoted text, ctx=[prefix,suffix], c=latest comment, s=status, relocated/orphaned flags). Locate q in docs/<slug>.md to find what each comment refers to.
Reopen a previously resolved review thread.
Reply to a review thread WITHOUT resolving it — to answer a question or push back. Posted as an AI reply; the thread stays open.
Mark a review thread resolved after you have edited the doc to address it. Optionally include a one-line note of what changed (posted as an AI reply).
Parameter descriptions missing or incomplete. open_comments has 'all' and 'full' boolean params with no descriptions; resolve_thread and reply_thread lack descriptions for 'note' and 'thread_id'. LLMs cannot infer parameter semantics from names alone.
No output schemas documented. Tool descriptions do not specify what fields are returned or their types. LLMs must guess response structure, risking misuse of returned data.
Input parameters lack type constraints. 'slug' is a free-form string with no pattern or validation guidance. 'thread_id' is an integer but no range is specified. No enums, patterns, or min/max constraints visible.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 50 | 2026-07-28+ | v2 |
No error handling guidance in tool definitions. If a thread_id is invalid or a slug does not exist, the tool description does not explain what error the LLM should expect or how to recover.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). resolve_thread, reply_thread, and reopen_thread are write operations but lack destructiveHint or idempotentHint annotations to signal to the LLM that they modify state.