agentic-rag
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@agentic-ragWhat replaced RFC 2616?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
agentic-rag
Cited, revision-aware retrieval over a real corpus drawn from the IETF RFC
ecosystem -- RFC full text, the RFC index's real Obsoletes/Obsoleted-by/Updates
supersession graph, real community-submitted RFC errata, and real IANA
protocol-parameter registries -- fetched over HTTPS (corpus_fetch/) and
ingested through ragpack into a searchable vector store
(321,124 real chunks), then routed and citation-gated through the
consilium spine.
Ask a real question about an IETF protocol spec, an RFC's authorship/status, a
real errata correction, or an IANA registry entry, and get back an answer built
entirely out of real cited chunks -- or an honest abstain. The one exception
is an obsoletion question ("what replaced RFC 2616?"): there is no "current
revision" of RFC 2616's own text to retrieve (it was entirely superseded by six
later documents, RFC 7230-7235 -- IETF's own famous multi-way obsoletion case),
so that is answered by SupersessionModule, a deterministic graph lookup over
the real Obsoletes/Obsoleted-by graph, not retrieval. No LLM anywhere in the
answer path.
Quickstart
git clone https://github.com/trentmilam/agentic-rag
cd agentic-rag
py -3.12 -m venv .venv
.venv\Scripts\python -m pip install -r requirements.txt
.venv\Scripts\python -m pip install -e .
.venv\Scripts\python scripts\verify.pyThat is the whole bootstrap. The editable install is what makes import consilium,
import ragpack, import linkgraph, import activerag and import chainrag resolve --
pyproject.toml's package-dir maps each name into packages/.
Answering a real question additionally needs the ingested corpus; see The corpus and Verify.
Related MCP server: DocuMind MCP
One repo, five merged tools
agentic-rag used to import consilium and linkgraph from sibling repositories by
inserting their roots on sys.path, and required RAGpack pip-installed editable from a
third. Cloning it meant cloning four repos at three commits pinned in three separate files
-- which had already drifted apart from each other. linkgraph also read this repo's data
file, so those two imported each other across a repository boundary.
They are one repo now. Each merged tool kept its whole tree under packages/<name>/, so
everything it resolves relative to its own root still resolves, and each kept its own
commit history rather than being squashed into an import commit:
package | what it is | tests |
the routing / citation-gating spine: Registry, Router, compose, integrity gate, ComputeModule | 5 eval suites | |
ingest, chunking, embedding, the Qdrant store wrapper | 20 | |
the cross-document relationship graph behind the MCP relationship tools | 50 | |
evidence-thinness detection and bounded hunt-and-retry | 54 | |
a second vertical over blockchain protocol docs, proving the spine is not corpus-specific | -- |
They are nested under packages/ rather than sitting at the repo root for a concrete
reason: a top-level directory named consilium shadows the consilium package as an
implicit namespace package, because the working directory precedes the editable install on
sys.path. Imports then resolve to an empty namespace and consilium.__file__ is None.
CI asserts every package resolves to a file inside this repo, so that class of silent
mis-binding fails the build instead of passing every test against the wrong copy.
rag-reliability is the one dependency still outside this repo. It supplies graphrx,
headroom, vecstamp, chunkledger, plumbline and legigate to three of the tools
above, and is resolved by path today; packaging it so it can be a declared dependency is
the outstanding follow-up. CI checks it out pinned and fails if those integration tests
skip, so the one remaining path dependency cannot rot unnoticed.
The corpus
source type | what it is | real chunks | current (non-obsoleted) |
| verbatim RFC full text | 306,939 | 225,809 |
| per-RFC index card (title/authors/date/status/obsoletes/updates) | 5,854 | 4,663 |
| real community-submitted RFC corrections | 7,295 | 7,295 (n/a -- no revision concept) |
| 7 real IANA protocol-parameter registries, rendered as markdown tables | 1,036 | 1,036 (n/a -- no revision concept) |
321,124 total real chunks, embedded with the real BAAI/bge-base-en-v1.5
model. rfc_text/rfc_index are the only source types with a revision
concept -- is_current there is a real structural fact (see the revision
guard), not guessed.
Five modules, one router
agenticrag/bootstrap.py::build_registry assembles a real 5-module consilium
Registry: the 4 retrieval modules above (each loaded straight from Qdrant,
current_only=True by default -- see agenticrag/registry_loader.py), plus
SupersessionModule (agenticrag/supersession.py), a ComputeModule that
parses data/entities/revisions.json -- the real Obsoletes/Obsoleted-by graph
for all 9,794 RFCs in the live index -- once at construction and answers
obsoletion questions with a deterministic, cycle-safe graph walk (bounded at 50
visited nodes -- a defensive cap, not an expected real limit; real IETF
obsoletion components are small).
build_registry also fails loud if the process's configured embedder does not
match the one that ingested the store (verify_embedder_marker, called first) --
otherwise cosine scores would be silently meaningless -- and closes any Qdrant
client it opened itself once the modules are loaded (retrieval is fully
in-memory afterward), so it does not hold the local-mode store's lock for the
caller's whole process lifetime.
errata's trust_tier (0.55, well below rfc_text/rfc_index/iana_registry's
0.9-0.95) is measured, not guessed: of 5,061 real errata records ingested,
only 2,400 (47.4%) are Verified by the RFC Editor -- 1,781 (35.2%) are
Held for Document Update, 679 (13.4%) are outright Rejected, and 201 (4.0%)
are still Reported. Fewer than half of real submitted corrections are
RFC-Editor-confirmed, so this module corrects the primary text without being
uniformly authoritative itself.
MCP server
agenticrag/mcp/server.py exposes the answer path as a
Model Context Protocol server over stdio
(mcp>=1.28.1, FastMCP). Four tools:
search(query)-- the full cited/abstain answer path (consilium.compute.answer_v3), passed through verbatim (an honest abstain stays an abstain);get_obsoletion_chain(rfc_id)/get_corrections(rfc_id)/get_related(entity_id)-- the relationship graph, via thelinkgraphsibling (agenticrag/relationships.py); each returns a documented{"ok": false, "fallback": ...}envelope if that sibling is absent.
Run it: .venv\Scripts\python -m agenticrag.mcp.server (stdio transport -- an
MCP client launches it and speaks the protocol over stdin/stdout). The tool
logic is import-light and has no mcp/Qdrant dependency, so it unit-tests
without either (agenticrag/mcp/test_server.py).
Verify
Quick verify (fast, corpus-free -- no ingested corpus needed):
verify.bat :: or: .venv\Scripts\python -m pytest -qRuns the MCP tool-wrapper tests and the supersession graph-walk cycle-safety suite. This is what CI runs on every push (see the badge above).
Full verify (needs the ingested 321k-chunk corpus from the Quickstart):
.venv\Scripts\python eval\eval_agenticrag.pyDeterministic given the already-ingested corpus; no re-ingestion. Uses the real
embedder -- the exact one that ingested the corpus -- so this proves genuine
semantic retrieval end-to-end, not wiring alone. Takes ~3.3 min on this
hardware (measured, full run: 196s): a one-time ~60s registry build (a single
scan of the corpus for the small poison-quarantine set -- not a load of all 321k
vectors), then the router/answer passes at ~12s each. Each pass runs routing and
retrieval as native Qdrant vector searches; Qdrant's embedded local mode is exact
brute-force (no ANN index), so a search still scans the filtered subset -- but in
native code, materializing only the top-k, ~16x faster than the old pure-Python
per-chunk scan. (Sub-second search would need Qdrant server mode's HNSW index;
local mode keeps the repo self-contained -- no server to run.) It
checks: one in-scope
query per source type (sensible module + >=1 real citation); the RFC 2616
obsoletion query (successor set is exactly {7230, 7231, 7232, 7233, 7234, 7235}); one out-of-scope query (honest abstain); the revision-guard structural
exclusion (below); a genuinely current RFC (791) resolving current; and an
absent RFC number (99999) resolving not_found, not a crash.
eval/prove_revision_guard.py is the same structural proof as a standalone,
narrated script. eval/smoke_ingest_real.py proves the fetch->ingest->Qdrant
wiring with the zero-cost HashEmbedder (needs corpus_fetch.fetch_all to have
run, but no GPU/embedding model).
The revision guard, proven
RFC 2616 (HTTP/1.1) is a real, single, whole document -- there is no "current revision" of it; it was entirely superseded by six different documents. The guard property here is two real, checkable facts, not one "corrected value":
Structural exclusion. RFC 2616's own
rfc_textchunks exist in Qdrant (loading therfc_textmodule a second time withcurrent_only=Falseproves they're there) but are absent from the defaultcurrent_only=Truemodule every query actually uses -- becausedata/entities/revisions.json["RFC2616"]["obsoleted_by"]is real and non-empty. The data exists; it's structurally filtered, not accidentally missing.The correct path to the answer.
SupersessionModuleis the explicit way to learn what happened to RFC 2616 -- a query naming it returns the real 6-way successor list (RFC 7230-7235).
Router calibration -- measured, not guessed
consilium.router.Router's stated library defaults (floor=0.11,
anchor_centroid=0.25, anchor_best_chunk=0.25) assume a near-zero baseline
cosine between unrelated text -- true for a bag-of-words HashEmbedder, not
necessarily true for a real dense embedder over a 321k-chunk corpus (the same
gap shows up even at a much smaller ~1,100-chunk scale). agenticrag/calibrate.py
measures this directly against the real corpus + real embedder rather than
assuming it; see agenticrag/bootstrap.py::ROUTER_KWARGS for the resulting
per-instance kwargs and the real numbers that justified the decision.
.venv\Scripts\python agenticrag\calibrate.pyGPU note (ingest only)
GPU matters for exactly one step: the corpus ingest (ingest/run_ingest.py),
which embeds ~321k chunks with BAAI/bge-base-en-v1.5 via onnxruntime. At
query time you only embed the (short) query string, so the launchers run fine
on CPU with no GPU setup -- which is why they no longer touch any GPU config.
Expected-and-harmless warning: if onnxruntime-gpu is installed but its matching
CUDA runtime DLLs aren't on the search path, you'll see an alarming red
CUDAExecutionProvider / Error loading ... cublasLt64_*.dll ... missing block --
on any run, ingest or query, not just ingest. It is not a failure: onnxruntime
falls back to CPU and continues (for a query the embed is one short string, so the
CPU fallback is instant). Ignore it, or install the DLLs below to silence it.
For a fast ingest, onnxruntime-gpu's CUDA execution provider needs those CUDA
runtime DLLs on the DLL search path. pip install onnxruntime-gpu alone does
not bundle them, and without them onnxruntime falls back to CPU (measured:
~6 chunks/sec -- computed: ≈14.9 hours for the full 321,124-chunk corpus) rather
than raising. To get real GPU execution (measured: ~650 chunks/sec on an RTX 5090,
i.e. ≈8 minutes for the full corpus), install the matching CUDA runtime wheels
into this repo's own venv, e.g.:
.venv\Scripts\python -m pip install nvidia-cublas-cu13 nvidia-cudnn-cu13(match the -cuNN suffix to your onnxruntime-gpu build's CUDA major version),
or put any CUDA-enabled PyTorch install's torch/lib directory on PATH before
running the ingest. Either way this is an optional acceleration of the one-time
ingest, never required to run the demo or serve queries.
Ingest re-runs (known limitation)
ingest/run_ingest.py supports a from-scratch --recreate rebuild and a fast
incremental path (only re-embeds raw files whose content hash changed). The
incremental path has two known limitations, deliberately not papered over: (1) it
keys "changed" purely on each raw file's byte hash, so if an RFC becomes newly
obsoleted in a later rfc-index.txt refresh without its own text file
changing, its is_current flag can go stale; and (2) it does not delete
orphaned Qdrant points for a document that re-ingests to fewer chunks. For a
guaranteed-consistent store, run ingest/run_ingest.py --recreate (a full
rebuild). Closing both limitations in the incremental path is future work.
Layout
agenticrag/
embed_config.py shared Settings (model/qdrant path) + embedder-consistency guard
registry_loader.py loads a consilium Module's chunks straight from Qdrant (current_only guard)
bootstrap.py build_registry(embedder, client=None) -> Registry; the 5 Descriptors; ROUTER_KWARGS
supersession.py SupersessionModule -- real Obsoletes/Obsoleted-by graph walk, cycle-safe
relationships.py thin bridge into linkgraph (get_related / _obsoletion_chain / _corrections)
calibrate.py real router-score measurement script
mcp/
server.py FastMCP server: search + the 3 relationship tools (stdio)
test_server.py fixture-only tests for the tool logic (no mcp package, no Qdrant)
corpus_fetch/ real HTTPS fetch of RFC full text / rfc-index.txt / errata / IANA registries
ingest/
connectors/ per-source-type extract() -> ExtractedDoc (+ the revisions-index builder)
run_ingest.py raw files -> chunk -> embed -> Qdrant, real is_current currency check
eval/
smoke_ingest_real.py corpus_fetch -> ingest -> Qdrant wiring smoke (HashEmbedder)
eval_agenticrag.py production eval (full verify; needs the ingested corpus)
prove_revision_guard.py standalone, narrated revision-guard proof
test_supersession_cycle_safety.py cycle-safety unit tests (synthetic graph; corpus-free)
tests/ unit tests for connectors / registry_loader / bootstrap (corpus-free)
packages/ the five merged tools, each keeping its own tree and history
consilium/ routing / citation-gating spine (+ its 5 eval suites)
ragpack/ ingest / chunk / embed / Qdrant store (src-layout)
linkgraph/ cross-document relationship graph
activerag/ evidence-thinness detection and bounded hunt-and-retry
chainrag/ the blockchain-docs vertical
app.py gr.ChatInterface chat UI
run_demo.py scripted 3-question narrated transcriptLicense
Code: MIT (c) 2026 Trent Milam.
The corpus is not included in this repo (data/ is gitignored); it is
fetched at build time from rfc-editor.org and iana.org. IETF RFC/errata text is
subject to the IETF Trust Legal Provisions
(the fetch preserves each document's own copyright/Trust notice intact); IANA
registry data is published by IANA. This project redistributes none of it -- it
fetches it, locally, on your machine.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides LLM-based access to IETF documents such as RFCs, Internet-Drafts, STD/BCP/FYI series, and errata through a Model Context Protocol server.MIT
- FlicenseNot gradedqualityBmaintenanceA citation-grounded RAG server for internal documentation that exposes retrieval tools and resources via the Model Context Protocol, enabling any MCP client to search and access organizational knowledge with structured citations.
- FlicenseNot gradedqualityCmaintenanceProvides read-only, citation-backed semantic search and retrieval-augmented generation over enterprise documents via standardized MCP tools, with local embeddings for privacy.
- AlicenseNot gradedqualityBmaintenanceEnables fully local retrieval over a personal document corpus via hybrid search, cross-encoder reranking, RAPTOR summaries, and knowledge graph queries, served to AI agents over MCP.MIT
Related MCP Connectors
Page-cited retrieval for embedded docs, datasheets, MISRA, CMSIS, and RTOS references.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/trentmilam/agentic-rag'
If you have feedback or need assistance with the MCP directory API, please join our Discord server