Skip to main content
Glama

RouteMind

An ontology you can see the agent reading. Split a domain into areas, let each area advertise itself in one line, and an agent picks from that list before reading anything else. The map draws that structure as a wiring diagram, and one click shows you the exact text an agent is handed.

The domain is not in this code. The vocabulary and the areas are data, and the data is your own git repository.

The RouteMind map: a backbone carrying five areas, two of them opened to show the nodes they hold,
with the routing table each one hands an agent one button away.

On 700 questions over one frozen corpus, asked in a person's words rather than in the codes the documents use, retrieval scores 0.028 and this scores 1.000 — and it costs 6.7 tool calls and 20–100× more per question, which is why 320 of those 700 are questions nothing here argues for walking. The study, the corpus and every run are in this repository.

./install.sh --name acme --port 9000   # then `claude` in the same directory

How it works

Each area summarizes itself into one advertised route; the backbone holds one row per area, and no
more. An agent reads that list at hop 0, picks every area the question belongs to — a client dinner on
the corporate card is expense and approval, not one of them — and only then reads
documents.

The shape is borrowed from dynamic routing on a network, and the borrowed part is the useful one: an area advertises where it is relevant, not everything it holds. So the cost of finding something does not grow with how much there is.

The thing easiest to get wrong is that use_when is the only text read before a choice is made — an area with a title and no reason is one nobody picks.

Back-Bone, AS, and the line between them

   BACK-BONE ─ the whole of this ontology. Hop 0: one row per AS, nothing else,
       │       and the only place absence may be claimed
       │
       ├── AS  expense    "what to do with a receipt · whether the corporate card
       │        │          may be used here · how much a business trip pays"
       │        ├── AS  corp-card   ← an AS holds AS's: the same thing one level
       │        │    └── card-limit   down, advertising itself the same way
       │        └── AS  evidence
       ├── AS  approval   "whom to put in the approval chain · whether a team
       │                   lead can sign this off"
       └── AS  payroll    "what this payslip line means · whether an allowance
                           is tax free"

An AS advertises; it does not expose. What is inside is invisible from hop 0 until something picks it — so hop 0 is the same size at 80 documents and at 8,000.

Absence belongs to the Back-Bone alone. An AS's table says what that AS holds, never what RouteMind lacks. Every table says which of the two it is, in its own footer.

Overlays

Some questions do not sit in one area: settling a trip is three at once. An overlay is that working set made as an object — the areas, why each is in it, and what was used to answer. docs/OVERLAY.md.

Related MCP server: corpus.333.eco

Measured

700 questions over one frozen corpus of 1,126 documents. Four arms, all of them a census — no sampling, one fresh agent per question.

plain RAG

+ reranker

RouteMind

a question in codes the rows use

0.991

1.000

1.000

a question in a person's words

0.028

0.069

1.000

a rule two revisions back

0.133

0.200

1.000

overall

0.516

0.541

0.999

The two bold rows are the point: retrieval does not degrade there, it fails outright, because every newer version of a subject outranks the one being asked for and they all look alike.

What it costs. A walk is 6.7 tool calls, 23–111 seconds and $0.12–$0.28 a question against one sub-second embedding call — and 320 of those 700 are questions retrieval already answers first time. Nothing here argues for walking those.

The one miss in 700 was a wrong sentence in the map, not a wrong document, and both routing arms obeyed it identically. An agent that trusts the map inherits the map's errors silently. Still unmeasured: whether a correct map has a size at which it stops working.

Check it rather than take it. The corpus is 865 documents in bench/corpus/, the gold sets are in eval/gold/, the generator that made the corpus is bench/spec.yaml + bench/generate.py, and every run — including the ones that failed — is in eval/runs/. Re-running needs an API key and ./bench/run.py eval/gold/<set>.yaml; bench/README.md has the order.

eval/report/report-en.html — the whole thing with figures · 한국어 · eval/PREREGISTRATION.md — written and frozen before any of it ran.

Quickstart

Docker, with docker compose. That is all it needs — the containers carry python and git.

git clone https://github.com/CSP911/routemind.git routemind && cd routemind
./install.sh --name acme --port 9000

→ http://localhost:9000

--name is what this domain is called: one word, lowercase, and it appears in every address a linked backbone prints (/v1/peers/acme/…). --port is where the map answers, 8080 by default. Run ./install.sh bare and it asks for both, then asks whether you have an LLM — Enter skips it, and --no-llm does not ask. An LLM changes one thing: a ✨ Suggest button that drafts a routing line for you to edit.

Safe to run again; an existing .env is kept and only what you pass is replaced.

Three containers, no database. ontology is the API and the only thing that touches your git repository; web is the map and a proxy; exchange is where backbones meet, idle until you link one. On first boot an empty ontology is laid into data/repo and that becomes a git repository — every write commits, so undo is git revert.

Start from examples/back-office rather than an empty map: five areas, 79 entities, five levels deep. docs/INSTALL.md — that, the manual route, what to do when it does not come up, and the first two things to write.

Connecting an agent

Optional — the map works on its own. An agent reads this ontology the same way every time: fetch the list of areas, pick one, fetch that area, read what it points at. Two operations, never a third.

python3 mcp/knowledge_mcp.py --api http://localhost:8080/api/knowledge

One file, stdlib only: no install, nothing to build. For Claude Code there is nothing to do at all — install.sh writes .mcp.json at the root, pointed at the port you chose, so cd routemind && claude is the whole setup and /mcp shows the tools.

knowledge_table(path?) and knowledge_read(path) do the reading. The rest appear only where the install has what they need: knowledge_overlay where overlays are kept, knowledge_write where there is a workspace area, knowledge_circuit always. /circuit <url> <token> is the same thing from a person's side.

The area list travels in the server's instructions, so you do not have to name RouteMind in the question — what decides whether the agent comes here is the use_when line on each area. Without MCP, Copy for an agent on the map puts the same text on the clipboard; all of them hand over one formatter's output, because three descriptions of one ontology would drift.

docs/AGENTS.md — every client, the tools, and the prompts.

How old is this row

Material goes stale and gets replaced; the old record still has to exist. Both versions are in the map, both look valid, and an agent reads both as current — so it sometimes answers from the one that was replaced.

Every routing row carries two times:

  KIND   ADDRESS                        AGE          WHY YOU WOULD PICK THIS ROW
  table  /v1/nodes/card-limit           2y / today   Card limits — what the card may be used for …
  file   /v1/nodes/qualified-list/body  2y / 2y      What qualifies as evidence, and the ceiling …

         how long this path ─┘    └─ when what it points at last moved
         has been here

One number cannot say both. A two-year-old route over a document rewritten today is current — somebody is maintaining it. The same route over a document that has not moved is the one to ask about before quoting it. Both come from git, so there is nothing to keep in sync.

It is not a supersession record: old is not wrong, and an agent that prefers the newest row picks a draft over a rule that has held for a decade. The column supports asking, not deciding.

docs/AGE.md.

More than one backbone

An install is one backbone and an exchange. A domain is one exchange and the backbones on it — head office and a subsidiary are one domain; a company and its supplier are two.

An area crosses by somebody setting export: yes on it, and by nothing else. The line a peer reads is that area's own use_when — one sentence, the same one this backbone routes on. export_to narrows who sees it; a kind marked export: no in vocab.yaml never leaves whatever an area says.

  PEERING — standing, committed, everyone sees it
     your BB ── peers.yaml ──▶ EXCHANGE ◀── members.yaml ── their BB
     Their areas appear in YOUR hop 0. An agent never learns there is a link.

  CIRCUIT — this session only, nothing written on either side
     /circuit http://their-host:8100 <token>
     Their areas appear under /v1/circuits/<name>/… , beside yours, never in it.

Both halves of a peering are declarations, so nobody is enrolled by one side alone. A circuit is the opposite by design: one person, one session, one address and a token somebody handed them.

Three things worth knowing before relying on either. Nothing is copied — a document is relayed, held for one request and discarded, so the only record of a read is the one its owner writes. No transit — a room offers a neighbour its own backbones, never a third room's. Absence suspends itself — hop 0 may claim something is missing only while every link is up, and says so when one is not.

The credential is an enrolment key that buys a six-hour session; the key opens nothing else, and a session cannot mint another. It shortens how long a leak is worth something. It does not prove who is at the far end.

docs/PEERING.md — the contract, the circuit, the sessions, and the operator's screen at :8090.

A partner behind a firewall, an air-gapped site, an auditor who gets a copy and nothing else.

./transfer/export.py --api http://localhost:8100 --token "$TOK" --out partner.rmx
./transfer/import.py partner.rmx --graft data/repo --prefix partner

Export in the map's header downloads the same file. It is AES-256-GCM with an authenticated header, so it says what it claims to be before anyone types a passphrase at it.

It holds exactly what a peer would have been able to read — the areas somebody set export on, their documents, and the links between them where both ends are inside that set. That is read from the same surface a link reads, not filtered on the way out, so no bug in this code can serve an area nobody decided to share.

Grafting prefixes every id, and the receiving repository's own validator decides whether the result is coherent. Without --graft it unpacks to a directory and writes into no ontology at all.

transfer/README.md.

Layout

ontology/     the ontology API — python + pyyaml + git. Knows nothing about any domain
exchange/     where backbones meet. No repository, no areas, no hop 0
web/          the map and a proxy — one FastAPI file. Knows nothing about any domain
admin/        the operator's screen for an exchange. Off unless EXCHANGE_ADMIN_TOKEN is set
mcp/          the MCP server, so any MCP-capable agent can read the ontology
transfer/     export, import and graft — one encrypted file, for where a link cannot reach
static/       the map screen
seed/         an empty ontology, copied into data/repo on first boot
examples/     one worked ontology, and seed-demo.sh — six backbones across two rooms
check/        every check. docs/CHECKS.md
docs/         everything below

data/repo     ← your ontology. A git repository, and the only thing to back up
data/*        publish, overlays, harness, exchange, access — all derived or local.
              docs/DATA-REPO.md

Everything else

ROUTING.html

the whole structure, in a browser

INSTALL.md

installing by hand, what to do when it does not come up, the first two things to write

PEERING.md

links between backbones, circuits, six-hour sessions, the operator's screen

AGE.md

the two times on a routing row, and what they deliberately do not say

transfer/README.md

carrying a backbone somewhere a link cannot reach

OVERLAY.md

the working set for one question

AGENTS.md

connecting an agent — every client, and the tools

LLM.md

the optional ✨ Suggest buttons, and the three provider wires

AUTH.md

who may write, and whose name goes on the change

DATA-REPO.md

your ontology as a git repository, and the one derived file in it

CHECKS.md

every check, what it proves, and where it can run

PLATFORMS.md

macOS, Linux, Windows — and what differs on each

I18N.md

English, 한국어, 日本語, 简体中文 — and adding one

SCENARIOS.md

the routing table over a whole lifetime

DOMAIN-NEUTRALITY.md

which rules still belong to the domain this came from

PROVENANCE.md · DELTA-FROM-IRIS.md

where this came from, and what changed

TODO.md

known gaps, written down rather than glossed over

eval/

the study — pre-registered before it is run


Contact

Business inquiries, collaboration, or just curious: qct8377@gmail.com LinkedIn → linkedin.com/in/cspark911 Bug reports and questions → GitHub Issues

License

MIT — see LICENSE.

Available Tools

3 tools
knowledge_circuitB

Read another RouteMind for the length of this connection. Give it the address and token somebody handed you, and their shared areas appear alongside this backbone's — you walk them the same way, with the addresses their tables print.

It is read-only, and it holds only what its owner chose to let cross. The line on each row is the one that backbone routes on itself — one sentence per area, written by its owner about their own map rather than about yours.

Nothing is written on either side and nothing outlives this connection. This is not the same as linking two backbones, which is a standing arrangement somebody configures and commits; this is you borrowing a reader's view of theirs.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes
urlNoopen: the remote RouteMind's address, e.g. https://kb.example.com
nameNoopen: a short name to address it by (ascii kebab-case; defaults to the host). close: which one to close
tokenNoopen: the read token its owner gave you

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it declares read-only operation, states that only owner-shared areas are exposed, and emphasizes that nothing is written and nothing outlives the connection (session-scoped lifetime). It stops short of disclosing error behavior, token failure handling, or rate limits, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key action is front-loaded, which is good, but substantial space is spent on atmospheric phrasing ('the line on each row', 'walk them the same way') that adds tone rather than usable instruction. The read-only and ephemerality points earn their place; the metaphorical padding does not.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter tool with no annotations and no output schema, the description covers the essentials an agent needs: it is read-only, session-scoped, exposes only shared areas, and describes what appears on each row. It lacks any note on failure modes or the difference between the list and open operations, but overall it is sufficient to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, so the schema already documents url, name, and token. The description only loosely implies the open/list/close lifecycle in prose ('for the length of this connection') and adds no operation-specific syntax or defaults beyond what the schema states, so it lands at the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource ('Read another RouteMind for the length of this connection'), so the core action is discoverable. However, the purpose is buried under extended metaphor ('borrowing a reader's view', 'walk them the same way'), and it never distinguishes itself from the sibling tools knowledge_read or knowledge_table it explicitly alludes to.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives real usage context: supply the address and token someone handed you to view a remote backbone, and it contrasts this with 'linking two backbones' (a standing committed arrangement). That contrast is against a feature, not against the sibling tools, so an agent still has no explicit rule for choosing knowledge_circuit over knowledge_read or knowledge_table.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

knowledge_readA

Read one document from Knowledge, by the address a table printed for it. Returns the document as written.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesThe address a table printed for this document.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. 'Read' implies a non-mutating operation and 'as written' signals the content is returned unmodified, which is useful. However, nothing is said about missing/invalid path behavior, permissions, or size/rate constraints, leaving notable gaps for a no-annotation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero filler; the action and the key's origin are front-loaded. Nothing could be removed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema and no annotations, the description covers what it does and roughly what comes back ('as written'), but the return shape and error behavior are underspecified. It is minimally sufficient rather than complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single 'path' parameter is already documented, so baseline is 3. The description adds only provenance context ('the address a table printed'), essentially restating the schema's own wording without adding format, validation, or failure semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read one document from Knowledge') and clarifies the lookup key is an address a table printed. It distinguishes the operation from sibling tools implicitly by tying the key to knowledge_table output, though it never explicitly rules out knowledge_table or knowledge_circuit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the agent must have a path already produced by a table, which suggests a read-after-list workflow, but there is no explicit when-to-use, when-not-to-use, or alternative named. Adequate but leaves the routing inference to the reader.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

knowledge_tableA

Fetch a routing table from Knowledge: a list of what is there and where to go next. Call it with no arguments to get the list of areas — that is where every search starts. Each row prints the exact address that fetches it; use those verbatim and never construct one.

(The area list could not be fetched: HTTP 404 from /v1/regions)

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoAn address a table printed: /v1/regions (the areas), /v1/regions/<area>, /v1/nodes/<id> or /v1/services/<id>. Omit for the list of areas.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses the no-arg behavior, that rows contain fetchable addresses, and the hard rule to use them verbatim rather than constructing paths. However, it says nothing about error handling for bad paths, and the appended '(The area list could not be fetched: HTTP 404 from /v1/regions)' is a leaked runtime failure rather than behavioral disclosure, which muddies rather than clarifies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core is front-loaded and efficient, but the trailing parenthetical HTTP 404 error is extraneous noise that does not belong in a tool definition and makes the description read as half-broken.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations and no output schema, the description does a reasonable job explaining the routing/address model and the entry-point workflow. It is nonetheless incomplete on failure behavior for invalid paths, and the embedded 404 leaves the agent unsure whether the tool currently works.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already enumerates the accepted path forms and states 'Omit for the list of areas'. The description reinforces the 'use addresses verbatim, never construct one' constraint, which is valuable, but adds no new syntax or format detail beyond the schema. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (fetch a routing table from Knowledge) and explains what the payload is: a list of what is there and where to go next. It implicitly differentiates from knowledge_read/knowledge_circuit by framing itself as the routing/entry-point layer, though it never names the siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to call it with no arguments first and that 'that is where every search starts', which tells the agent when to reach for it. It stops short of naming knowledge_read/knowledge_circuit or stating when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedknowledge_circuit
    • First observedknowledge_read
    • First observedknowledge_table

TDQS

A3.5/5.0

Scored across 3 tools

Disambiguation4/5

knowledge_table discovers areas and prints addresses, knowledge_read fetches a specific document, and knowledge_circuit federates to a peer's view. The three are mostly separable, though table and circuit both return browsable lists and could be momentarily confused by an agent unfamiliar with the peering concept.

Naming Consistency4/5

All three share the 'knowledge_' prefix, giving a predictable namespace. However, the suffixes mix a noun (table), a noun-as-metaphor (circuit), and a verb (read), so the verb_noun pattern isn't strictly uniform.

Tool Count4/5

Three tools is thin but defensible for a read-only routing/exploration server with a narrow purpose. Each tool maps to a distinct step (discover, fetch, federate), so nothing feels redundant, though it sits near the low end.

Completeness3/5

Read-only is intentional, so no write operations are expected. But the primary entry point is broken (HTTP 404 fetching the area list) and there is no search tool, leaving a real dead end for agents trying to orient themselves.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Routes coding agents to the most relevant project documentation (decisions, intent, constraints) with provenance and freshness, providing tools for task routing, knowledge search, and document context.
    39 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables agents to search, retrieve, and list open-licensed documents with verifiable provenance, attaching sha256, DOI, and OpenTimestamps proof to every response.
    3,570 npm
    Creative Commons Zero v1.0 Universal
  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes a version-controlled knowledge base as MCP tools so agents can read merged identity/state summaries and next recommended actions at runtime, plus run deterministic schema validation and cross-reference link checks. This lets agents fetch live state and verify integrity via self-describing calls instead of re-reading raw files.
    -
  • F
    license
    A
    quality
    B
    maintenance
    Enables AI agents to access a markdown wiki or knowledge base through per-topic tools that expose available domains and retrieve tables of contents, matching lines, or full pages on demand.
    3
    -