Content
# open-mind-mcp-server
**The MCP integration layer for [Open Mind](https://github.com/HelloThisWorld/open-mind): it loads Open Mind's verification-first codebase artifacts and exposes them to AI agents as tools — every answer backed by `file:line` evidence, and claims the sources can't back are rejected, not improvised.**





```
Agent: validate_claim_against_sources
{ "claim": "The PaymentGateway writes cardholder data to Postgres." }
Server: { "status": "unsupported",
"matchedTerms": ["PaymentGateway"],
"evidence": [],
"reason": "The artifacts describe PaymentGateway but never mention:
writes, cardholder, data, Postgres. ..." }
```
No API keys. No network. `npm install && npm run demo` and you'll see all five tools answer — and refuse to answer — from bundled sample artifacts.
---
Related projects:
- [Open Mind](https://github.com/HelloThisWorld/open-mind): generates source-traceable codebase artifacts
- [open-mind-mcp-server](https://github.com/HelloThisWorld/open-mind-mcp-server): exposes those artifacts as MCP tools for agents
- [agent-skill-verification-template](https://github.com/HelloThisWorld/agent-skill-verification-template): tests agent skills/tools with evals, metrics, traces, and replay artifacts
## What this is (and is not)
This project is an **optional integration layer** for Open Mind:
- It does **not** replace Open Mind, and it does **not** analyze repositories itself.
- It loads the `.openmind` artifact directory that Open Mind generates and exposes it as five MCP tools.
- Open Mind runs independently and never requires this server.
- This server runs independently too: it ships with sample artifacts (real Open Mind output, checked in) so the demo and tests work standalone.
The integration boundary between the two projects is deliberately narrow: **`manifest.json` plus the versioned artifact schema** (currently `1.0.0`). This server never imports Open Mind's internals.
```
Source Code Repository
│
▼
Open Mind ────────────── verification-first analysis (Python, standalone)
│
▼
.openmind artifacts ────── manifest.json + glossary / architecture /
│ flows / source-index (file:line evidence)
▼
open-mind-mcp-server ───── this repository (TypeScript, standalone)
│
▼
Claude / Cursor / AI Agent five MCP tools over stdio, structured JSON
```
## Why agents need this
LLM agents working on codebases fail in a predictable way: they answer fluently whether or not they actually know. An agent that "remembers" a retry policy that doesn't exist will confidently build on it, and the error surfaces three steps later as broken code or a wrong architectural decision.
Open Mind attacks this at the source: it generates **deterministic artifacts** from repositories — a verbatim glossary, architecture components, entry-point flows, a source symbol index — where every statement carries `file:line` evidence with a verbatim snippet and a confidence level. This server enforces the same discipline at the tool boundary:
- **Evidence over fluency.** Every factual output cites `file:line` evidence. Explanations are served verbatim from artifacts, never generated.
- **Refusal is a feature.** Unknown symbols, unknown components, and unbackable claims return `insufficient_evidence` or `unsupported` — with the missing terms named, so the agent knows *what* it couldn't verify.
- **Machine-readable everything.** All tool outputs are structured JSON with declared MCP output schemas.
- **Deterministic.** The same artifact set and the same input produce the same output, byte for byte. There's a test for it.
## Tools
| Tool | Input | Output |
|---|---|---|
| `list_available_artifacts` | `{}` | Loaded artifact types, backing files, entry counts, repository name + commit |
| `search_codebase_context` | `query`, `limit?` | Ranked glossary/architecture/flow/source entries with `file:line` evidence, or `no_results` |
| `get_symbol_evidence` | `symbol` | `supported` with evidence records, or `insufficient_evidence` with empty evidence |
| `explain_architecture_component` | `component` | `supported` with the verbatim description, responsibilities, evidence — or `insufficient_evidence` naming the components that ARE described |
| `validate_claim_against_sources` | `claim` | `supported` \| `unsupported` \| `insufficient_evidence`, with matched terms, citations, and a reason |
## Example tool outputs
Real output from `npm run demo` (trimmed). More in [examples/demo-queries.md](examples/demo-queries.md).
**`list_available_artifacts {}`**:
```json
{
"status": "ok",
"artifacts": [
{ "type": "glossary", "file": "glossary.json", "entryCount": 10 },
{ "type": "architecture", "file": "architecture.json", "entryCount": 4 },
{ "type": "flows", "file": "flows.json", "entryCount": 2 },
{ "type": "source-index", "file": "source-index.json", "entryCount": 12 }
],
"repository": { "name": "sample-repo", "commit": null }
}
```
**`get_symbol_evidence { "symbol": "RetryPolicy" }`**:
```json
{
"status": "supported",
"symbol": "RetryPolicy",
"evidence": [
{
"file": "docs/GLOSSARY.md",
"line": 11,
"snippet": "- **RetryPolicy**: The exponential backoff schedule for failed event deliveries: attempts wait 1s, 4s, 16s, 64s, then 256s before the event is parked in the dead letter queue (DLQ)."
}
],
"confidence": "high"
}
```
**`validate_claim_against_sources`** — a claim the sources support:
```json
{
"status": "supported",
"claim": "The EventPublisher retries failed deliveries and parks exhausted events in the dead letter queue.",
"matchedTerms": ["EventPublisher", "retries", "failed", "deliveries", "parks", "exhausted", "events", "dead", "letter", "queue"],
"evidence": [
{ "file": "docs/GLOSSARY.md", "line": 8, "snippet": "- **EventPublisher**: Delivers domain events to subscribers with at-least-once semantics; ..." }
],
"reason": "10 of 10 claim terms appear in artifacts describing EventPublisher, RetryPolicy, parkInDeadLetterQueue. See the cited file:line evidence.",
"confidence": "high"
}
```
— and one they don't:
```json
{
"status": "unsupported",
"claim": "The PaymentGateway writes cardholder data to Postgres.",
"matchedTerms": ["PaymentGateway"],
"evidence": [],
"reason": "The artifacts describe PaymentGateway but never mention: writes, cardholder, data, Postgres. The loaded sources do not support this claim.",
"confidence": "medium"
}
```
A claim outside the sources entirely returns `"status": "insufficient_evidence"` — the server distinguishes *"the sources describe this subject but not this behavior"* from *"the sources don't cover this subject at all."*
## Quickstart
### Option 1: Use bundled sample artifacts
```bash
npm install
npm run build
npm test
npm run demo
```
The bundled samples in [examples/sample-open-mind-artifacts/](examples/sample-open-mind-artifacts/) are real Open Mind output, generated from Open Mind's fixture repository (a tiny order-processing service).
### Option 2: Use real Open Mind artifacts
```bash
cd ../open-mind
npm install # optional; the npm scripts just wrap Python
npm run analyze -- --repo ./fixtures/sample-repo --output ./.openmind
# equivalently: python -m openmind.artifacts --repo ./fixtures/sample-repo --output ./.openmind
cd ../open-mind-mcp-server
npm install
npm run demo -- --artifacts ../open-mind/.openmind
# or the shortcut, which prints setup instructions if the artifacts are missing:
npm run demo:openmind
```
Point `--repo` at any local repository to serve artifacts for your own codebase.
### Use it from Claude Code
```bash
claude mcp add open-mind -- node /absolute/path/to/open-mind-mcp-server/dist/server.js
```
### Use it from Claude Desktop (or any MCP client)
```json
{
"mcpServers": {
"open-mind": {
"command": "node",
"args": ["/absolute/path/to/open-mind-mcp-server/dist/server.js"],
"env": {
"OPEN_MIND_ARTIFACTS_DIR": "/absolute/path/to/your/.openmind"
}
}
}
}
```
### Inspect it interactively
```bash
npx @modelcontextprotocol/inspector node dist/server.js
```
## Configuration
| Environment variable | Default | Meaning |
|---|---|---|
| `OPEN_MIND_ARTIFACTS_DIR` | bundled samples | `.openmind` directory to load (must contain `manifest.json`) |
| `OPEN_MIND_SOURCE_ROOT` | unset | Root of the analyzed source tree; when set, citations are verified against the real files at load time (warnings only) |
| `OPEN_MIND_MAX_RESULTS` | `5` | Default result cap for `search_codebase_context` |
| `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` (JSON logs on stderr) |
If the configured directory can't be loaded, the server logs a structured warning and falls back to the bundled samples, so zero-config startup always works. A wrong schema version fails loudly instead: artifacts written under a `2.x` schema are rejected with a clear error.
## The artifact contract
The server reads a `.openmind` directory in **schema version 1.x**:
```
.openmind/
manifest.json generator, timestamp, repository { name, root, commit }, artifact file map
metadata.json summary counts
glossary.json [{ term, kind, description, evidence[], confidence }]
architecture.json [{ name, kind, description, responsibilities[], evidence[], confidence }]
flows.json [{ name, description, steps[{ order, description, component, evidence[] }], confidence }]
source-index.json [{ path, language, symbols[{ name, kind, line, snippet }] }]
```
Every `evidence` record is `{ file, line, snippet }` with a repository-relative path; every entry carries a `confidence` of `high` / `medium` / `low`. Validation happens at load time in three layers: zod structural schemas, a schema-version gate (`1.x` accepted, other majors rejected), and a citation policy (relative traversal-free paths; optional verification against the real source tree via `OPEN_MIND_SOURCE_ROOT`).
## Telemetry
Structured JSON logs go to stderr (stdout belongs to the MCP transport). Every tool call logs:
```json
{"time":"...","level":"info","event":"tool_call","tool_name":"validate_claim_against_sources","artifacts_dir":"...","repository_name":"sample-repo","status":"unsupported"}
```
Failures add `failure_reason`. Artifact loading logs `artifacts_loaded` / `artifact_citation_warning` / `artifacts_fallback_to_samples` events with the same fields.
## Project structure
```
src/
├── server.ts # MCP wiring (stdio transport, tool registration, sample fallback)
├── config.ts # env-driven config, offline defaults
├── demo.ts # offline demo runner (--artifacts <dir>, --openmind)
├── artifacts/
│ ├── artifact-types.ts # zod schemas for the 1.x artifact contract + the search index types
│ └── artifact-loader.ts # manifest-driven loading, version gate, index building
├── tools/ # one file per MCP tool (pure logic + registration + telemetry)
├── validation/
│ ├── citation-validator.ts # citation policy + optional verification against local sources
│ └── claim-validator.ts # deterministic supported/unsupported/insufficient logic
└── telemetry/logger.ts # JSON logs to stderr (stdout belongs to MCP)
examples/
├── sample-open-mind-artifacts/ # real Open Mind output from its fixture repo (the offline demo data)
└── demo-queries.md # copy-paste tool calls with expected outputs
tests/ # vitest: loader, citation policy, tools, determinism, MCP round-trip
```
## Limitations (MVP scope)
- **Reads pre-generated artifacts.** It does not run Open Mind analysis itself; regenerate artifacts with Open Mind when the code changes.
- **Read-only by default.** It does not execute shell commands and does not access files outside the configured artifact directory (plus, optionally, read-only citation checks under `OPEN_MIND_SOURCE_ROOT`).
- **Claim validation is lexical, not semantic.** Verdicts come from deterministic term-coverage scoring. It cannot detect negation — the sample glossary says the PaymentGateway "*never* stores raw card numbers", and a claim that it "stores raw card numbers" would still match those words. A real deployment would layer NLI/entailment checking behind the same tool contract.
- **Search is keyword scoring, not embeddings.** Deliberate for the demo: deterministic, offline, zero heavy dependencies.
- **Citations are verified only when sources are present.** Without `OPEN_MIND_SOURCE_ROOT`, citation checks are shape-only (the analyzed repo usually isn't present at serve time).
## Roadmap
- [ ] Real MCP stdio server registration examples for more clients (Cursor config example)
- [ ] A published artifact-schema package shared by generator and consumer
- [ ] Richer semantic claim validation (entailment behind the same tool contract)
- [ ] Optional `refresh_artifacts` tool that shells out to Open Mind on demand
- [ ] Integration with [agent-skill-verification-template](https://github.com/HelloThisWorld/agent-skill-verification-template) to eval the tool surface
- [ ] OpenTelemetry metrics/traces behind the existing structured-log fields
## Development
```bash
npm run dev # run the server from source (tsx, stdio)
npm test # vitest (loader, validators, tools, MCP round-trip, determinism)
npm run build # tsc → dist/
npm run clean # remove dist/
```
CI runs install → build → test → demo on Node 20 and 22 using only the bundled sample artifacts — no Open Mind checkout required ([.github/workflows/ci.yml](.github/workflows/ci.yml)).
## License
[MIT](LICENSE)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available