Recipe 05 — Index-first agent over MCP
Goal
Let an agent orient itself on a hub-hosted family the way spec v2 says an agent should:
read the index, follow at most two links. hub_docset_index(docset) returns the exported
llms.txt and, for a split family, a sections list; passing file="<slug>/llms.txt"
returns the section index; the page is then a read. No embedding, no keyword index — just
the files the exporter wrote.
When not to use it
- You need a specific fact rather than the right page. The facts layer with keyword or hybrid (recipe-03, recipe-04) is one call and lands on the unit.
- The family is not on the hub. For a public site, recipe-01 and recipe-02 do the same hops over HTTP.
- You want whole-corpus reasoning within a budget. Ask for
file="llms-small.txt"and read once (~50k tokens) instead of hopping.
Steps
hub_docset_index("codeclaudecom__codeclaudecom")— the root index.docsetis the store key (<host-slug>__<mirror-stem-slug>); a host name returns{"docset": …, "error": "no such docset"}. The reply’ssectionsfield lists every section file the export wrote, including thepart-Nfiles a large section is chopped into.- Choose a section from the counts on its line (pages, tokens) and the titles it quotes.
hub_docset_index("codeclaudecom__codeclaudecom", file="agent-sdk/llms.txt")— the section index, which links pages.- Open the page with
hub_llms_full_read(key, page=<url>), or fetch its.mdtwin from the served URL in the reply.
hub_docset_index(docset="codeclaudecom__codeclaudecom")
The reply is a JSON envelope around the file. Verbatim, run against this hub on 2026-08-31 —
the whole text field, nothing elided:
{
"docset": "codeclaudecom__codeclaudecom",
"file": "llms.txt",
"served_at": "http://127.0.0.1:8788/d/code.claude.com/llms.txt",
"llms_full_url": "http://127.0.0.1:8788/d/code.claude.com/llms-full.txt",
"chars": 1121,
"truncated": false,
"text": "# code.claude.com documentation\n\n> A decision map for administrators deploying Claude Code, covering API providers, managed settings, policy enforcement, usage monitoring, and data handling.\n\nGenerated from a mirror of code.claude.com by docset_refine on the hub; 191 pages. Companion files: llms-full.txt (all pages), llms-small.txt (reference pages within ~50k tokens), llms-facts.txt (extracted units).\n\n## Sections\n\n- [Overview](overview/llms.txt): 137 pages, ~7,460 tokens — Set up Claude Code for your organization, Orchestrate teams of Claude Code sessions, Manage multiple agents with agent view and 134 more\n- [Agent Sdk](agent-sdk/llms.txt): 31 pages, ~1,615 tokens — How the agent loop works, Use Claude Code features in the SDK, Track cost and usage and 28 more\n- [Whats New](whats-new/llms.txt): 22 pages, ~1,388 tokens — Week 13 · March 23–27, 2026, Week 14 · March 30 – April 3, 2026, Week 15 · April 6–10, 2026 and 19 more\n\n## Optional\n\n- [Claude Code changelog](https://code.claude.com/docs/en/changelog.md): Release notes for Claude Code, including new features, improvements, and bug fixes by version.",
"sections": [
"agent-sdk/llms.txt",
"overview/llms.txt",
"overview/part-1/llms.txt",
"overview/part-121/llms.txt",
"overview/part-61/llms.txt",
"whats-new/llms.txt"
]
}
chars is 1,121, and so is len(text) — it counts the characters you were handed, not the
file’s size. manifest.json calls the same file 1,136 bytes, and the 15-byte gap is
arithmetic, not drift: the section lines contain three — (3 bytes each), three – (3) and
three · (2), so 3×2 + 3×2 + 3×1 = 15 bytes that are not characters. Budget against
tokens in manifest.json; read chars only as “how much of the file did this reply
contain”, which is why it is paired with truncated.
sections has six entries against three lines in the index: overview is 137 pages, so the
exporter split it further into part-1, part-61 and part-121, and overview/llms.txt is
itself an index over those three. That is the hop the ## Sections list does not show, and the
reason to read sections rather than parse the links.
hub_docset_index(docset="codeclaudecom__codeclaudecom", file="agent-sdk/llms.txt")
Same envelope, same sections list, a different file — real fields from that call, with
text cut after its first link:
{
"docset": "codeclaudecom__codeclaudecom",
"file": "agent-sdk/llms.txt",
"served_at": "http://127.0.0.1:8788/d/code.claude.com/agent-sdk/llms.txt",
"llms_full_url": "http://127.0.0.1:8788/d/code.claude.com/llms-full.txt",
"chars": 6461,
"truncated": false,
"text": "# code.claude.com documentation — Agent Sdk\n\n> 31 page(s) of code.claude.com documentation under Agent Sdk. Part of the index one level up (../llms.txt).\n\n## Agent Sdk\n\n- [How the agent loop works](https://code.claude.com/docs/en/agent-sdk/agent-loop.md): Understand the message lifecycle, tool execution, context window, and architecture that power your SDK agents.\n … 30 more link lines truncated for this page …"
}
sections comes back unchanged on every call — it describes the family, not the file you
asked for — so an agent can hop without re-reading the root.
Other values file accepts: llms-small.txt, llms-facts.txt, manifest.json (byte and
token counts per file — the cheapest way to plan a budget), and any <section>/llms.txt the
reply listed. llms-full.txt is never returned inline; it can be millions of tokens, and the
reply gives its served URL instead.
Expected output
Three replies: the root (280 tokens), the section index (1,615 tokens, 31 page links with
extractive descriptions), and the page. The agent has read about 2k tokens of navigation to
land on a 3k-token page, which is the whole point of the ladder — and the manifest.json
read, if you make it, tells you in advance that the alternative (llms-full.txt) would have
been 2,097,403 tokens. Picking overview instead costs one extra hop: its index is 167 tokens
and points at the three part-N files.
Cost
Measured from manifest.json: root 280 tokens, agent-sdk/llms.txt 1,615 tokens,
overview/llms.txt 167 tokens (it is itself split into part-N files of 3,311 / 2,950 /
1,032 tokens). Three tool calls, zero embeddings, zero model tokens spent on retrieval; the
model spends only what it reads.
Runnable in step 4 (playground).