feat: use sublevel llms.txt per product for MCP resources#27
feat: use sublevel llms.txt per product for MCP resources#27mattpodwysocki wants to merge 8 commits intomainfrom
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs.mapbox.com restructured so that llms.txt now exists at every product level (e.g. /api/llms.txt, /help/llms.txt, /mapbox-gl-js/llms.txt) and llms-full.txt contains full page content. The root llms.txt is now a pure link index, so resources that filtered it by category keyword were returning empty content. - resource://mapbox-api-reference → docs.mapbox.com/api/llms.txt (structured index of all REST APIs by service category) - resource://mapbox-guides → docs.mapbox.com/help/llms.txt (39KB Help Center index with actual guide content) - resource://mapbox-sdk-docs → docs.mapbox.com/mapbox-gl-js/llms.txt (34KB GL JS documentation index with guides, API ref, examples) - resource://mapbox-reference → root llms.txt without filtering (complete product catalog for discovering available docs) - resource://mapbox-examples → continues filtering root for playground/demo sections Add fetchCachedText() shared helper to docFetcher to consolidate the repeated fetch+cache pattern across all resource implementations. Fix toMarkdownUrl() to return null for URLs already ending in .txt/.md/.json so get_document_tool fetches llms.txt files directly without a wasted .md rewrite attempt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cspell flagged capitalized 'Isochrone' as an unknown word in two resource description strings. Lowercased to fix CI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cspell doesn't know 'isochrone' by default. Adding both cases to the project word list so the CI spellcheck passes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New tool that fetches the llms.txt documentation index for any Mapbox product — model can autonomously pull the right index without the user manually attaching a resource. Supports 13 product keys, results cached via docCache. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The custom 'Accept: text/markdown, text/plain;q=0.9, */*;q=0.8' header was triggering a 403 Forbidden from the docs.mapbox.com CDN. Removing it (and the equivalent in fetchDocContent's fallback path) fixes the issue — the CDN serves the file correctly without an explicit Accept header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: add get_mapbox_docs_index_tool
zmofei
left a comment
There was a problem hiding this comment.
LGTM — clean adaptation to the upstream llms.txt restructure.
Two minor observations (neither blocking):
-
fetchDocContentAccept header removal (src/utils/docFetcher.ts:106) — theAccept: text/markdownheader was also removed from the generalget_document_toolfallback path, not just the newfetchCachedText. Low risk since the.mdvariant is tried first, but it's a slightly broader change than the PR scope suggests. -
toMarkdownUrlfix is a nice catch — preventing thellms.txt.md404 → fallback double-fetch is a real performance win for all.txt/.md/.jsonURLs going throughget_document_tool.
New GetDocsIndexTool is well-designed with proper annotations and typed product enum. Good test coverage across happy path, caching, errors, and invalid input.
Summary
docs.mapbox.com restructured its
llms.txt. Every product now has its ownllms.txt(page index) andllms-full.txt(full page content) at its own URL. The rootdocs.mapbox.com/llms.txtis now a pure link index pointing to these sublevel files — it no longer contains any documentation content itself.The previous resources all fetched the root
llms.txtand filtered its sections by category keyword. With the new structure, those filtered sections contain only link-lists (links to otherllms.txtfiles), not actual docs. The resources were effectively returning empty or useless content.What changed
resource://mapbox-api-referencellms.txt, filtered for "api" sectionsdocs.mapbox.com/api/llms.txt— structured index of all REST APIs by serviceresource://mapbox-guidesllms.txt, filtered for "guide/studio/design" sectionsdocs.mapbox.com/help/llms.txt— 39KB Help Center with actual guide contentresource://mapbox-sdk-docsllms.txt, filtered for "sdk/library" sectionsdocs.mapbox.com/mapbox-gl-js/llms.txt— 34KB GL JS index (guides, API ref, examples)resource://mapbox-referencellms.txt, filtered for "reference" sectionsllms.txtunfiltered — complete product catalog for discoveryresource://mapbox-examplesllms.txt, filtered for playground/demo sectionsAdditional improvements
fetchCachedText(url, httpRequest)— new shared helper indocFetcher.tsthat fetches and caches a URL. All five resource classes now use this instead of duplicating the fetch+cache pattern (~30 lines each).toMarkdownUrlfix — previously returned a.txt.mdURL forllms.txtURLs, causingget_document_toolto waste a request on a 404 before falling back. Now returnsnullfor URLs already ending in.txt,.md, or.json, so they're fetched directly.How to use
llms-full.txtFull page content for any product is available via
get_document_tool:https://docs.mapbox.com/style-spec/llms-full.txt— 466KB, full Style Spechttps://docs.mapbox.com/ios/navigation/llms-full.txt— 696KB, full Nav SDK iOShttps://docs.mapbox.com/mapbox-gl-js/llms-full.txt— 1.6MB, full GL JS docsThe root
resource://mapbox-referencenow surfaces the complete product catalog including allllms.txtURLs, so models can discover and request any product's full docs.Test plan
npm test— 62 tests passresource://mapbox-api-referencereturns actual API endpoint list (not a link-index)resource://mapbox-guidesreturns Help Center content (not empty)"Show me the Mapbox API Reference"

"What Mapbox APls are available for navigation?"

🤖 Generated with Claude Code