Axiom Meridian
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| KNOWLEDGE_BASE_PATH | No | Optional — Meridian auto-creates the knowledge base directory if it isn't set (~/.local/share/meridian on Linux, ~/Library/Application Support/meridian on macOS, %APPDATA%/meridian on Windows). |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| index_rules_from_markdownA | Index rules from a markdown file directly into SQLite.
Access level: write. Returns: JSON with indexed/created/updated counts, a per-scope breakdown, and any parser warnings or errors. |
| index_lessons_from_markdownA | Index lessons from a markdown file directly into SQLite. Same logic as Access level: write. Returns: JSON with indexed/created/updated counts, a per-scope breakdown, and any parser warnings or errors. |
| convert_to_atomic_formatA | Convert a legacy markdown file into atomic-format pending_proposals,
one per legacy block, with best-effort scope inference from each block's
text. Never writes .md files directly — always stages for human review
via Access level: write. Returns: JSON with the number of proposals created and their id/type/ scope_id/suggested_file. |
| list_pending_proposalsA | List pending proposals for human review, optionally filtered by project, type, or status. Access level: read. Returns: JSON array of matching pending_proposals rows. |
| approve_proposalA | Approve a pending proposal. For type='rule'/'lesson' this assigns a new RN-/LL- code, appends the atomic block to the scope's .md file, and inserts the corresponding row; for type='update' it splices the target's existing block in place instead. This is the single choke point that writes proposal content into both the .md file and SQLite together. Access level: write. Returns: JSON with the resulting code, scope_id, and file location (file_path/file_offset/byte_length). |
| edit_proposalA | Update the proposed_text and/or metadata of a still-pending proposal; its status stays 'pending'. Access level: write. Returns: JSON with the proposal_id and its status. |
| reject_proposalA | Reject a pending proposal. No side effects besides updating the record. Access level: write. Returns: JSON with the proposal_id and its status. |
| promote_ruleA | Promote a rule to a more general scope: marks the original as deprecated (in both SQLite and its source .md file) and records a PROMOTED rule_history entry. Does not create the rule in the new scope — that requires a separate proposal. Access level: write. Returns: JSON with the rule_id, new_scope_id, and resulting status. |
| deprecate_ruleA | Create a proposal to deprecate a rule or lesson on its own, without changing its scope (unlike promote_rule). Accepts both RN-* and LL-* ids. Only creates a pending_proposals row (type='deprecate') — no immediate effect; approve_proposal performs the actual deprecation after human review. Access level: analyze. Returns: the new proposal's id, as a plain string. |
| create_projectA | Create a new project scope and its knowledge base directories: a 'project-' scope under parent_scope, plus knowledge-base/projects/ and lessons/projects/ directories with a placeholder rules .md file. Access level: write. Returns: JSON with the new scope_id, name, parent_scope, and created file_path. |
| generate_embeddingsA | Generate or update ChromaDB embeddings for active rules/lessons whose embedding_id is still NULL — an incremental backfill, not a full re-embed. Access level: write.
Returns: JSON with processed/skipped/errors counts and duration_seconds,
or {"error": "RAG_NOT_INSTALLED", ...} when the |
| generate_project_skillsA | Generate a Claude Code skill for a project from its resolved rules: writes .claude/skills/meridian/<project_id>/SKILL.md and references/rules.md under project_path, and updates its AGENTS.md. Access level: write. Returns: JSON mapping "skill_md"/"rules_md"/"agents_md" to their written file paths. |
| query_rulesA | Query active rules visible to a project across its full scope hierarchy (most-specific scope first), via plain SQL filtering or — when query_text is set and embeddings exist — semantic search. Access level: read. Returns: a JSON or TOON array of matching rules. |
| query_lessonsA | Query active lessons visible to a project across its full scope hierarchy (most-specific scope first), via plain SQL filtering or — when query_text is set and embeddings exist — semantic search. Access level: read. Returns: a JSON or TOON array of matching lessons. |
| get_rule_contextB | Return a rule's full text, its complete rule_history, and any lessons linked to it. Access level: read.
Returns: JSON with |
| get_rule_timelineA | Return a rule's chronological history and linked-lesson summary without loading full text — lighter than get_rule_context. Access level: read. Returns: JSON with rule_code, scope, severity, category, history_events, and linked_lessons_summary. |
| get_project_scope_resolutionB | Resolve and cache a project's effective scope chain (most-specific first) with each scope's dynamic attributes (ADR-002). Access level: read.
Returns: JSON with project_id and the resolved |
| get_server_infoA | Report this running server process's version/commit, and whether
the code on disk has changed since this process started — Python
doesn't hot-reload, so an editable install that was Access level: read.
Returns: JSON with version, the commit captured at server startup,
a freshly-read commit as of this call, and a |
| get_rule_audit_logB | Return the chronology of rule_history changes for a project or scope, plus any rules currently deprecated in that scope. Access level: read.
Returns: JSON with |
| audit_prA | Audit a PR diff against a project's active rules and lessons (detail="full"): persists an audit record (SHA-256 diff hash + a snapshot of the rule versions evaluated) and returns the diff plus rules/lessons for the calling LLM to classify. Access level: analyze. Returns: JSON with audit_id, pr_diff, rules, lessons, and an instruction_for_client. |
| analyze_pr_feedbackB | Link PR review feedback to the most recent audit_pr record for the same pr_ref/project_id, returning the rules that applied at that time for the calling LLM to classify each feedback point. Access level: analyze. Returns: JSON with feedback_text, rules_that_applied, pr_audit_record, and an instruction_for_client. |
| check_feature_against_rulesA | Check a planned feature description against a project's active rules and lessons (detail="full"); persists a planning_checks record and returns the context for the calling LLM to flag conflicts. Access level: analyze. Returns: JSON with feature_description, rules, lessons, check_id, and an instruction_for_client. |
| extract_rules_from_transcriptA | Return everything the calling LLM needs to extract candidate rules from a transcript: the clean text, the project's scope chain with attributes, existing rules for duplicate detection, and the canonical rule template. Does not itself create any proposal — call create_pending_proposal per candidate. Access level: analyze. Returns: JSON with clean_text, scopes, existing_rules, template, and an instruction_for_client. |
| extract_lessons_from_transcriptA | Return everything the calling LLM needs to extract candidate lessons from a transcript: the clean text, the project's scope chain with attributes, existing lessons for duplicate detection, and the canonical lesson template. Does not itself create any proposal — call create_pending_proposal per candidate. Access level: analyze. Returns: JSON with clean_text, scopes, existing_lessons, template, and an instruction_for_client. |
| create_pending_proposalA | Validate and persist a pending proposal of type 'rule', 'lesson', or 'update' (private tags stripped from proposed_text and metadata). The body goes in proposed_text and the other block fields in metadata; a full rendered atomic block in proposed_text is split into the two. For type='update', target_id must reference an existing RN-/LL- id and the proposal inherits that target's scope_id. Does not write to rules/lessons or any .md file — approve_proposal does that after human review. Access level: analyze. Returns: the new proposal's id, as a plain string. |
| get_rule_templateB | Return the canonical Access level: read. Returns: JSON with template, fields, usage, and (if project_id given) scope_suggestions. |
| get_lesson_templateB | Return the canonical Access level: read. Returns: JSON with template, fields, usage, and (if project_id given) scope_suggestions. |
| get_transcription_templateA | Return the combined rule+lesson template guide and workflow instructions for turning a transcript into pending proposals. Access level: read. Returns: JSON with template, fields, usage, and (if project_id given) scope_suggestions. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 28 tools
Many tools are paired (rules vs lessons) and clearly distinct, but several overlap semantically: deprecate_rule creates a proposal while promote_rule acts immediately, and get_rule_context/get_rule_timeline/get_rule_audit_log all return rule history with varying detail. Descriptions help, but an agent could still misselect among related operations.
All tool names use consistent snake_case with a verb_noun structure (e.g., get_rule_template, create_pending_proposal, query_rules). There is no mixing of conventions, making the naming highly predictable.
With 28 tools, the server exceeds the 25+ threshold and feels heavy. While the domain is complex, many operations could be consolidated (e.g., generic rule/lesson tools instead of extensive pairs), reducing the surface.
The surface covers CRUD via proposals, auditing, templates, indexing, embeddings, and scope resolution, which is strong for the domain. Minor gaps exist, such as no get_lesson_context and no project listing/deletion.