MCP server for Right Reasons structured business ontology on Dolt
Right Reasons MCP has 14 well-named tools with clear action verbs (dolt_*, create_*, propose_*, promote_*, generate_*, get_*, list_*, traverse_*). Descriptions are present and substantive (100-250 chars typical), explaining WHAT and WHEN. However, input schemas are incomplete: many parameters lack type definitions in the visible code (e.g., dolt_diff 'table' param shown as string but no validation; propose_object 'layer' and 'object_type_code' lack enum constraints despite being enumerated in docstrings). Output schemas are undocumented, tools return JSON strings but the structure is not formally declared. Error handling is minimal: tools catch exceptions and return JSON errors, but do not guide recovery or classify errors as retryable. Parameter descriptions are present but lack format/constraint details (e.g., 'confidence' accepts 0.0-1.0 but no min/max declared). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels. Composition is strong: tools chain well (create_session → propose_object/propose_relation → promote_candidate), and IDs flow correctly between calls.
Create a new EPICAL intake session. session_kind: 'interview', 'workshop', 'review', or 'auto_ingest'. Returns the session ID for use with propose_object and propose_relation.
Commit all current changes to Dolt with the given message. Creates a versioned checkpoint. Like 'git commit' for your data. First stages all changes, then commits.
Show differences between Dolt commits or working changes. This is the PR-style diff view that enables human validation. Without a table name, lists which tables have changes. With a table name, shows row-level diffs.
Show the current Dolt working set status. Shows modified tables and staged changes — like 'git status' for your data.
Generate an OPS Contract — a reasoning envelope that attaches institutional context to work executed in external systems. Given a work reference and description, this tool: 1. Finds relevant RULES-layer objects (policies, decision rules, etc.) 2. Traces upstream to VISION and LORE for foundational reasoning 3. Composes a contract with clauses, constraints, and success criteria The contract does NOT manage work execution — it provides the reasoning context that should guide how the work is done.
Input schemas lack enum constraints for enumerated parameters. 'layer' in propose_object accepts LORE|VISION|RULES|OPERATIONS but is declared as free-form string; 'session_kind' in create_session accepts interview|workshop|review|auto_ingest but no enum. Enums prevent hallucinated values and are self-documenting.
Output schemas are undocumented. Tools return JSON strings (e.g., dolt_status returns {working_changes, recent_commits}, propose_object returns {candidate_id, status, message}) but the structure is not formally declared. LLMs cannot plan downstream calls or extract fields reliably without documented output schemas.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Get full details of a single canonical object by its ID.
Retrieve an OPS Contract with all its details.
Get the full assertion history for a specific relation. Returns all assertion versions (the 'why' explanations) for a relation, ordered by version number descending (newest first).
List canonical objects in the ontology. Filter by layer (LORE, VISION, RULES, OPERATIONS), object type code (e.g. 'lore_item', 'strategic_goal'), free-text search in title/summary/body, or validation status (draft, validated, deprecated).
List relations between objects. Filter by object_id (from/to), relation type code (e.g. 'interpreted_into'), and direction ('from', 'to', or 'both'). Includes the current assertion explanation by default.
Promote an authenticated candidate to canonical status. candidate_type: 'object' or 'relation'. Reads from src_candidate_object/src_candidate_relation, creates the canonical entry in rr_object/rr_relation, and updates the candidate status.
Propose a new candidate object (staged in src_candidate_object). This does NOT create a canonical object directly — it stages a candidate that must go through authentication before promotion. The layer must be one of: LORE, VISION, RULES, OPERATIONS. The object_type_code must match an existing type (e.g. 'lore_item', 'strategic_goal', 'policy').
Propose a new candidate relation between two objects. Stages the relation in src_candidate_relation. The from/to IDs can reference either canonical objects (rr_object.id) or candidate objects (src_candidate_object.id). The relation_type_code must match an existing type (e.g. 'interpreted_into').
Navigate the ontology graph from a starting object, following relations across layers. This is the key tool for answering 'why?' questions — trace from OPERATIONS up through RULES, VISION, to LORE with assertion explanations at each edge. Direction: 'up' follows from→to for transition relations (OPS→RULES→VISION→LORE), 'down' follows to→from (LORE→VISION→RULES→OPS), 'both' follows all directions. relation_types: optional list of relation type codes to follow (e.g. ['interpreted_into', 'operationalized_into', 'applied_to']). If None, follows all relation types.
Error handling does not guide recovery. Tools catch exceptions and return {error: str(e)}, but do not classify errors as retryable, user-fixable, or fatal. No recovery hints (e.g., 'Unknown object type code: X. Valid codes: lore_item, strategic_goal, policy'). LLMs cannot self-correct without actionable error messages.
No tool annotations despite clear risk levels. dolt_commit, create_session, propose_object, propose_relation, promote_candidate, and generate_ops_contract are WRITE operations but lack destructiveHint or idempotentHint annotations. dolt_status, get_object, list_objects, traverse_graph are READ_ONLY but lack readOnlyHint. Annotations enable agents to reason about safety and retry logic.
Parameter descriptions lack format/constraint details. 'confidence' in propose_object and propose_relation states 'Optional confidence score (0.0-1.0)' but no min/max declared in schema. 'limit' in list_objects defaults to 50 but no bounds stated. 'max_depth' in traverse_graph defaults to 4 but no range specified. Formal constraints prevent LLM hallucination.