Browsing the Index
Browsing is how you reach an exact record and everything connected to it, with no loss and no ranking in the way. It is the deterministic half of lmmol — and, for LLM agents, often the more useful half. This chapter walks the index top-to-bottom.
The shape of the index
index.json the root: types, counts, where to go
└─ index/list/<type>/root.json a type's listing: count + shard list
└─ index/list/<type>/<n>.json one shard: up to 1000 {id, name}
└─ nodes/<type>/<id>.json the entity itself (+ forward edges)
└─ index/.../<id>.json backlinks: who points *at* it
Each level is a plain static JSON file. You can crawl the whole thing with nothing but an HTTP client and the rules below.
1. The root
curl https://lmmol.com/index.json
The root lists every entity type, its count, and the navigation into its listing. Use it to discover what exists and how big each set is before you crawl.
2. Listings (paged by shards)
A type can have hundreds of thousands of entries, so listings are sharded into files of up to 1000 entries each.
# How is the protein listing sharded?
curl https://lmmol.com/index/list/protein/root.json
root.json gives you the total count and the list of shards. Then fetch a shard:
# The first shard: up to 1000 {id, name} pairs
curl https://lmmol.com/index/list/protein/0.json
Each shard entry is a compact { "id": "...", "name": "..." }. That is enough to show
a list, pick an id, and drill in — without downloading full nodes. To enumerate an
entire type, iterate shard 0.json, 1.json, … up to the count.
3. Nodes (the entities)
Once you have an id, fetch the node:
curl https://lmmol.com/nodes/protein/P38398.json
A node carries its name, synonyms, attributes, outbound_source_links (URLs to
the authoritative records), and its forward edges — its own cross-references out to
other entities. See Concepts & Terms for the full field list and the
edge shape.
Forward edges answer "what does this entity point to?" For the reverse — "what points at it?" — use the backlink indexes.
4. Backlinks (the graph goes both ways)
Edges stored on a node are one-directional. The cross-reference indexes give you the inbound side, so the graph is fully navigable from any node, in any direction.
Disease → its proteins and trials
curl https://lmmol.com/index/disease/MONDO_0016419.json
# -> { "proteins": [...], "trials": [...] }
This is the join that the Mondo normalization makes possible: a protein's disease and a trial's condition resolve to the same Mondo id, so this one file gives you both sides at once.
Gene → its proteins
curl https://lmmol.com/index/gene/BRCA1.json
# -> { "proteins": [...] }
Clinical associations (ClinVar)
Gene ↔ disease links backed by clinically-significant variants, each carrying a
significance label (e.g. Pathogenic, Likely pathogenic):
# Diseases associated with a gene
curl https://lmmol.com/index/clinvar/gene/BRCA1.json
# -> { "diseases": [ { "id": "MONDO_...", "name": "...", "significance": "Pathogenic" }, ... ] }
# Genes associated with a disease
curl https://lmmol.com/index/clinvar/disease/MONDO_0016419.json
# -> { "genes": [ { "symbol": "BRCA1", "significance": "Pathogenic" }, ... ] }
Browsing as an alternative to vector RAG
Vector RAG embeds a query, fetches the nearest chunks, and hopes the right facts landed in the window. The browse index removes the guesswork: every fact is reachable by following ids and paths — no embeddings, no similarity threshold, no truncation, nothing hidden. For an LLM agent that already knows an entity (a gene symbol, an accession, a Mondo id), the most reliable retrieval is not a similarity search — it is:
nodes/<type>/<id>.json # the record, exactly
index/disease/<id>.json # everything linked to it, exactly
index/clinvar/gene/<symbol>.json # the clinical associations, exactly
No relevance score can lose a record this walk would find. Search (next chapter) is one optional entry point into this graph for when you only have a fuzzy description — not a replacement for it.
A complete walk
A worked example: start from a disease, collect its proteins, and read one.
# 1. The disease's neighborhood
curl https://lmmol.com/index/disease/MONDO_0016419.json
# 2. Pick a protein id from the "proteins" array, then read it
curl https://lmmol.com/nodes/protein/P38398.json
# 3. Follow that protein's gene, then the gene's clinical associations
curl https://lmmol.com/index/clinvar/gene/BRCA1.json
Three deterministic hops, no ranking, no loss. Recipes turns walks like this into reusable scripts.