Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Recipes

Copy-paste tasks that combine the browse and search layers. Each is self-contained; swap in your own ids and queries. They assume curl, jq, and Python 3 with sentence-transformers for the search examples.

BASE=https://lmmol.com
SEARCH=https://rtxz9xxyz7.execute-api.us-east-1.amazonaws.com/search

1. Look up one entity

curl -s $BASE/nodes/protein/P38398.json | jq '{id, name, synonyms}'

2. Everything connected to a disease

# Proteins and trials for hereditary breast carcinoma
curl -s $BASE/index/disease/MONDO_0016419.json \
  | jq '{proteins: (.proteins|length), trials: (.trials|length)}'

3. Disease → proteins → read each one

BASE=https://lmmol.com
for id in $(curl -s $BASE/index/disease/MONDO_0016419.json | jq -r '.proteins[].id'); do
  curl -s $BASE/nodes/protein/$id.json | jq -r '"\(.id)\t\(.name)"'
done

4. Clinical (ClinVar) associations for a gene

curl -s $BASE/index/clinvar/gene/BRCA1.json \
  | jq -r '.diseases[] | "\(.significance)\t\(.id)\t\(.name)"'

5. Enumerate an entire type

# Walk every shard of the disease listing, printing id and name
BASE=https://lmmol.com
root=$(curl -s $BASE/index/list/disease/root.json)
shards=$(echo "$root" | jq -r '.shards | length')   # or derive from count
for n in $(seq 0 $((shards - 1))); do
  curl -s $BASE/index/list/disease/$n.json | jq -r '.[] | "\(.id)\t\(.name)"'
done

Be polite when crawling at scale: the files are CDN-cached, so cache locally and avoid re-fetching what you already have. Re-fetch index.json to learn when counts have changed.

6. Semantic search, end to end (Python)

import requests
from sentence_transformers import SentenceTransformer

SEARCH = "https://rtxz9xxyz7.execute-api.us-east-1.amazonaws.com/search"
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")

def search(text, indexes=("proteins", "trials"), top_k=10, filters=None):
    qv = model.encode(text, normalize_embeddings=True).tolist()
    body = {"queryVector": qv, "topK": top_k, "indexes": list(indexes)}
    if filters:
        body["filters"] = filters
    r = requests.post(SEARCH, json=body, timeout=30)
    r.raise_for_status()
    return r.json()["results"]            # sorted by distance, ascending

for hit in search("BRCA1 DNA repair and breast cancer risk"):
    print(f'{hit["distance"]:.3f}  {hit["type"]:8}  {hit["id"]}')

7. Filtered search: recruiting Phase 3 trials

results = search(
    "immunotherapy for advanced melanoma",
    indexes=("trials",),
    filters={"trials": {"phase": "Phase 3", "overall_status": "Recruiting"}},
)

8. Search to discover, browse to complete

The robust pattern: one search for entry points, then deterministic browsing to pull every connected fact without loss.

import requests
BASE = "https://lmmol.com"

# 1. Discover candidate proteins by concept
hits = search("tumor suppressor involved in homologous recombination",
              indexes=("proteins",), top_k=5)

# 2. For each, browse its gene's clinical associations — exact, no ranking
for h in hits:
    node = requests.get(f'{BASE}/nodes/protein/{h["id"]}.json').json()
    for syn in node.get("synonyms", []):
        cv = requests.get(f'{BASE}/index/clinvar/gene/{syn}.json')
        if cv.ok:
            for d in cv.json().get("diseases", []):
                print(node["id"], syn, d["significance"], d["name"])
            break

9. For an LLM agent: bootstrap from llms.txt

curl -s https://lmmol.com/llms.txt

Read it once, then navigate index.jsonindex/list/<type>nodes/<type>/<id> → backlink indexes with no further instructions. The walk is deterministic, so the agent never has to guess whether a relevant record was left out of a similarity window — see Browsing the Index.