# DocGraph

> Govern your documents like code. MCP server that indexes .md/.docx/.html/.pdf into a SQLite knowledge graph and runs drift audits — stale policies, conflicting research claims, superseded docs, undocumented code exports. 12 MCP tools incl. cross-reference graph, governance + provenance metadata, topic similarity. Single binary, zero runtime deps.

- **Type:** MCP server
- **Install:** `agentstack add mcp-detective-xh-docgraph`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Detective-XH](https://agentstack.voostack.com/s/detective-xh)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Detective-XH](https://github.com/Detective-XH)
- **Source:** https://github.com/Detective-XH/DocGraph

## Install

```sh
agentstack add mcp-detective-xh-docgraph
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# DocGraph

### Documentation knowledge graph MCP server for LLM agents

**MCP-native for LLM agents · CJK + Latin FTS5 · Multi-format graph**

[](LICENSE)
[](https://goreportcard.com/report/github.com/Detective-XH/docgraph)
[](https://go.dev)
[](#install)
[](#what-gets-indexed)

[](#install)
[](#install)
[](#install)

[](#claude-code)
[](#codex-openai)
[](#hermes-agent)
[](#opencode)

**Govern your documents like code.** DocGraph indexes `.md`, `.docx`, `.html`, and `.pdf` into a graph and runs **drift audits** on them — stale policies, conflicting research claims, superseded ADRs, undocumented code exports — so you can review your doc corpus the way you review a codebase. Most doc tools index and search. DocGraph also tells you what's broken.

### Drift audit on documents

```
docgraph_context format=drift_audit
```

Surfaces 14 finding codes across the corpus. A few:

- `policy.stale_review` — SOPs past their `review_due` date
- `policy.superseded_referenced` — docs citing a replaced policy
- `policy.conflicting` — same scope, contradicting rules
- `research.competing_interpretations` — claims that contradict
- `research.unverified_evidence` — assertions with no source
- `research.superseded_claim` — research overruled by a newer claim
- `doc.stale_by_git` — docs with no git commits in a long while
- `code.undocumented_export` — code surfaces with no doc anchor
- `code.unanchored_feature` — approved features with no code anchor

Three packs ship enabled (`governance`, `research_provenance`, `entity`); three are opt-in (`policy_process`, `assessment_drift`, `code_doc`). No code knowledge required for governance and research — they work on any document collection.

### Opt-in agent enrichment, with provenance

Your `.docx` / `.pdf` / `.html` archive has no frontmatter, so it can't be governed. DocGraph fixes that without compromising authority:

```
agent → docgraph_enrichment(action=pending)
        ↳ scope (N docs), per-model USD estimate, sensitive paths flagged, token
user  → "go"
agent → runs LLM with its own key, then action=process for each doc
        ↳ stored as source=agent_inferred (advisory, lowest authority)
        ↳ logged with model_id, agent_id, run_id, content_hash
```

The confirmation token is **batch-bound** — one user consent authorizes the docs the user saw, no more. Sensitive paths silently refuse to issue tokens. `agent_inferred` metadata never overrides human frontmatter or extracted document metadata. **Your governance survives the agent.** DocGraph itself never calls an LLM. Enable with `--enable-enrichment`.

### Other differentiators

- **CJK + Latin search that actually works** — FTS5 trigram, not English-only
- **CodeGraph-style graph traversal for docs** — `docgraph_graph operation=incoming|outgoing|impact|trace`
- **Workspace fan-out** — one MCP server, N projects, one query
- **Reviewable evidence packs** — `format=context_pack` returns indexed text, hashes, citations, impact (not a RAG black box)

### What it isn't

A RAG black box, an embedding shop, or a Notion replacement. It's the layer that makes your existing docs auditable, navigable, and safe to feed to LLMs.

The LLM-facing fit guide — when DocGraph helps a project and when to use your own tools instead — is in [`AGENTS.md`](AGENTS.md). Single binary, zero runtime dependencies, indexes hundreds of docs in seconds.

## At a Glance

| Metric | Value |
|--------|-------|
| Language | Go 1.25+ |
| Binary size | ~13 MB |
| Codebase | ~23,520 lines of Go (+ ~28,390 lines of tests) |
| Index speed | 70–700 files per project in 2–6s (full rebuild; `--force`) |
| Typical graph | ~950 nodes and ~670 edges per 100 indexed files |

## Install

```bash
go install github.com/Detective-XH/docgraph@latest
```

Or build from source with version embedded:

```bash
git clone https://github.com/Detective-XH/DocGraph.git
cd DocGraph
go build -ldflags "-X main.version=$(git describe --tags --always)" -o docgraph .
```

Requires Go 1.25 or later.

> `go install` does not support `-ldflags` injection, so `docgraph version` will output `dev` for binaries installed that way. Use the source build above to get a versioned binary.

## CLI

```
docgraph init [--dry-run] [--interactive] [--install-clients auto|all|LIST] [--workspace] [--scope user] [--with-skills] [--update-skills] [path] # Create local config; optionally install MCP clients and bundled skills
docgraph install [--dry-run] [--interactive] [--clients auto|all|LIST] [--workspace] [--scope user] [--update-skills] [path]      # Configure MCP clients without re-initializing
docgraph pack list [--workspace]                          # List domain packs and enabled state
docgraph pack enable [--workspace] [--no-sync]    # Enable a domain pack; code_doc syncs by default
docgraph pack disable [--workspace]               # Disable a domain pack; code_doc rows are removed
docgraph index [--force] [--threshold N] [--no-gitignore] [--no-history]   # Index a project
docgraph sync [--threshold N] [--no-gitignore] [--no-history]              # Incremental hash-based update
docgraph heal [--project ] [--fix] [--owner ] [--git-timeout ]  # Infer and patch missing status/owner frontmatter fields in .md files
docgraph status                        # Print index stats
docgraph serve [--threshold N] [--no-gitignore] [--no-history] [--max-watches N] [--enable-embeddings] [--enable-enrichment] --path      # MCP stdio server (single project)
docgraph serve [--threshold N] [--no-gitignore] [--no-history] [--max-watches N] [--enable-embeddings] [--enable-enrichment] --workspace  # MCP stdio server (auto-discover all child dirs)
docgraph version                             # Print build version
```

`LIST` is a comma-separated client list: `claude,codex,hermes,opencode`.
`auto` always writes project-local Claude Code config and also writes Codex,
Hermes, and OpenCode config when their config directories already exist.
`all` creates config files for every supported client.
Use `--dry-run` to print create/update/unchanged actions without writing files.
Use `--interactive` to print the same review and confirm before writes.

## Bundled Skills

When installing for Claude Code, DocGraph automatically installs companion skills
into `.claude/skills/` alongside the MCP config — no extra flag needed:

```bash
docgraph init --install-clients claude /path/to/project  # MCP config + skill
docgraph install --clients claude /path/to/project       # MCP config + skill
```

To install skills on a project that was already initialized without `--install-clients`:

```bash
docgraph init --with-skills /path/to/project
```

Skills are installed with skip-if-exists policy — safe to re-run. To update an
existing skill to the latest bundled version:

```bash
docgraph init --update-skills /path/to/project
docgraph install --clients claude --update-skills /path/to/project
```

The `docgraph-drift-audit` skill audits all indexed `.md` files for DocGraph
compatibility: missing frontmatter, isolated docs (no outgoing links), broken
wikilinks, headings, and similarity islands. Reports PASS/FAIL per category and
offers auto-fix via `docgraph_files` and `docgraph_similar`.

Available skills bundled in the binary:

| Skill | Purpose |
|-------|---------|
| `docgraph-drift-audit` | Audit `.md` files for DocGraph compatibility |
| `policy-drift-audit` | Display and triage policy/process drift findings from `docgraph_context format=drift_audit` |
| `assessment-drift-audit` | Display and triage research assessment drift findings from `docgraph_context format=drift_audit` |
| `code-doc-drift-audit` | Display and triage docs-code drift findings (`code.*`) when the `code_doc` pack is enabled |

## MCP Tools

`docgraph_graph` supports `operation=incoming|outgoing|impact|trace`. Use
`document` for incoming, outgoing, and impact; use `from` and `to` for trace.

### Tools

| # | Tool | Description |
|---|------|-------------|
| 1 | `docgraph_search` | FTS5 full-text search (CJK + Latin) with section-level results, field-weighted ranking, graph-aware and git-history-aware reranking, and governance/research/entity filters. Returns documentation only by default; pass `include_code=true` or `kind=code_file` to include `code_doc`-pack code files |
| 2 | `docgraph_context` | **Primary entry point** -- task context with related docs, structure, cross-refs, and bounded source content. Use `format=context_pack` for reviewable evidence packs; `format=drift_audit` for policy/process, research, and (when `code_doc` is enabled) docs-code drift audit reports |
| 3 | `docgraph_graph` | Graph traversal facade. `operation=incoming` (who references this doc), `operation=outgoing` (what this doc links to), `operation=impact` (blast radius, configurable depth), `operation=trace` (shortest path between two docs). Use `document=` for incoming/outgoing/impact; `from=` and `to=` for trace |
| 4 | `docgraph_node` | Single document details with metadata, structure, and edges |
| 5 | `docgraph_files` | Indexed file tree |
| 6 | `docgraph_similar` | Find topically similar documents (TF-IDF + shared refs + tags; `engine=auto/tfidf/neural`) |
| 7 | `docgraph_status` | Index health (files/nodes/edges/unresolved/DB size), per-project stats, neural embedding model totals, domain packs, metadata quality, enrichment coverage, LLM callout tool state (embeddings/enrichment enabled/disabled + required flags), and compact drift audit summary when policy/research findings exist |
| 8 | `docgraph_tags` | List all tags with doc counts, or filter documents by tag |
| 9 | `docgraph_enrichment` | **Opt-in** (`--enable-enrichment`). Pull or store inferred summaries and metadata for documents without frontmatter. Facade: `action=pending\|process` |
| 10 | `docgraph_embeddings` | **Opt-in** (`--enable-embeddings`). Neural embedding workflow facade. `action=pending` lists docs needing embeddings; `action=store` saves a vector and recomputes neural similarity; `action=clear` deletes all embeddings for a model |

Start with `docgraph_context` for any research question. It composes search,
structure, and cross-references into a single result. Use the other tools
to drill into specifics.

For the agent-facing decision of whether to install/use DocGraph at all, see [`AGENTS.md`](AGENTS.md). Once installed, tool-selection rules are in the MCP `serverInstructions` (injected each session) and the per-tool descriptions.

## Agent Metadata Enrichment

The full mechanics of the opt-in workflow summarized at the top of this README. DocGraph never calls an LLM itself — your agent does, with its own key, then writes results back with provenance.

1. `docgraph_enrichment(action=pending, limit, content_mode)` returns
   frontmatter-less documents without a current inferred summary, including
   `doc_id`, `content_hash`, and bounded content. The response includes a
   `CONFIRMATION_TOKEN` bound to the batch of doc_ids it lists.
2. The agent infers a concise summary and optional metadata JSON object.
3. `docgraph_enrichment(action=process, doc_id, content_hash, summary,
   metadata, confidence, model_id, provider, agent_id, confirmation_token)`
   stores the result. `model_id` is required, `content_hash` must match the
   pending response, and `confirmation_token` must be the one returned by
   `action=pending` for a doc_id in that batch.

Inferred metadata never overrides authored frontmatter or extracted document
metadata. Stored summaries appear in `docgraph_node`, `docgraph_context`, and
context packs. `docgraph_status` reports enrichment coverage and stale results.
Normal retrieval uses one current enrichment per document, while DocGraph keeps
an internal run ledger with model, provider, agent, and content-hash provenance.
Agent-inferred summaries and metadata are advisory context, not source of truth.

**Privacy**: `docgraph_enrichment action=pending` returns document content that your
agent may send to an external provider. Get user consent before proceeding.

## Semantic Similarity

DocGraph computes topic similarity between documents using three signals:

| Signal | Method | Weight |
|--------|--------|--------|
| Text overlap | TF-IDF cosine similarity | 50% |
| Shared references | Jaccard similarity of outgoing link targets | 30% |
| Tag overlap | Jaccard similarity of frontmatter tags | 20% |

Documents scoring above the threshold (default 0.25) are connected with
`similar_to` edges. This finds conceptually related documents even when
they don't explicitly link to each other — the key advantage over
grep-based search.

Similarity is computed automatically during indexing. Query with
`docgraph_similar`. Tune sensitivity with `--threshold N` on `index`, `sync`,
or `serve`; lower values create more `similar_to` edges.

### Neural Embeddings (agent-driven)

DocGraph never calls an LLM itself. Instead, your agent computes embeddings
with any provider and pushes the vectors back — a pull-then-push agentic
workflow that enables semantic search far beyond TF-IDF vocabulary matching.
1. `docgraph_embeddings(action=pending, model_id, limit, content_mode)` — returns docs without up-to-date embeddings, including content and `content_hash`. `content_mode=full` (default) reads the full section from disk; `content_mode=excerpt` uses the stored body excerpt. Different `model_id` values are partitioned separately and never compared with each other.
2. Your agent computes vectors with its own provider (OpenAI, Ollama, Nomic, etc.)
3. `docgraph_embeddings(action=store, doc_id, model_id, vector, content_hash)` per doc — stores the vector and recomputes neural `similar_to` edges. Pass `content_hash` exactly as returned by step 1.
4. `docgraph_similar` deduplicates TF-IDF and neural results for the same pair, preferring neural when both exist.

In workspace mode, both embedding workflows automatically locate the correct per-project store by `doc_id`.

**Privacy**: pending embedding actions return document content that your agent will send to an external provider. Get user consent before proceeding.

Use `docgraph_embeddings(action=clear, model_id)` to delete all vectors for a model and reclaim space. `docgraph_status` shows a Neural Embeddings table listing stored models, total vectors, and stale count.

## Node and Edge Kinds

**Nodes:** `document`, `heading`, `definition`, `tag`; optional `code_file`
nodes when the `code_doc` domain pack is enabled.

**Edges:**

| Kind | Meaning |
|------|---------|
| `contains` | Document contains heading/definition |
| `references` | `[text](path.md)` Markdown link |
| `wikilinks_to` | `[[target]]` wikilink |
| `related_to` | Frontmatter wikilink (e.g., `related_to: "[[target]]"`) |
| `similar_to` | Topic similarity (TF-IDF + shared refs + tags; or neural if embeddings stored) |
| `tagged` | Frontmatter tag association |
| `embeds` | `![[embed]]` transclusion |
| `links_external` | URL to external resource |

## What Gets Indexed

**Markdown (`.md`)** — up to 1 MB per file:
- YAML frontmatter parsed into metadata; headings and `**Term:** definition` lines produce structural nodes
- `[[wikilinks]]`, `[links](path.md)`, `![[embeds]]`, external URLs, and frontmatter tags produce typed edges

**Word documents (`.docx`)** — up to 10 MB per file:
- Heading paragraphs (Heading 1–6 styles) become `heading` nodes with containment edges
- Hyperlinks extracted as `docx_hyperlink` edges; Dublin Core metadata (`core.xml`) stored as key/value tuples
- Zip-slip protection, per-entry size limits, 50 MB total uncompressed budget

**HTML (`.html`, `.htm`)** — up to 5 MB per file:
- ``–`` tags (including `id` attributes) become `heading` nodes
- `` and `` stored as metadata tuples; `` become typed link edges
- `` and `` content excluded from body text and section chunks

**PDF (`.pdf`)** — up to 50 MB / 500 pages per file:
- Each page becomes a `heading` node and a section chunk
- Info-dict fields (Title, Author, Subject, Keywords, CreationDate) indexed as metadata tuples
- Image-only PDFs

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Detective-XH](https://github.com/Detective-XH)
- **Source:** [Detective-XH/DocGraph](https://github.com/Detective-XH/DocGraph)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-detective-xh-docgraph
- Seller: https://agentstack.voostack.com/s/detective-xh
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
