Skip to content

Answer questions about Data Hub through the MCP server - #301

Merged
wasimxyz merged 8 commits into
stagingfrom
cursor/docs-over-mcp-97c4
Oct 9, 2026
Merged

wasimxyz merged 8 commits into
stagingfrom
cursor/docs-over-mcp-97c4

Conversation

@wasimxyz

@wasimxyz wasimxyz commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

What this does

An AI assistant connected to the Data Hub MCP server can now answer how-to questions about Data Hub itself, using the docs that ship with that deployment.

  • search_docs(query) returns up to five matching sections from the docs pages and the changelog. Each result has a short excerpt, a page ID, and a link to cite. When nothing matches, it returns the list of all docs pages and tells the agent to offer send_feedback for the gap.
  • read_doc(page, section?) returns one page or one section as Markdown. No tool returns all the docs at once, and the longest page is about 18,000 characters.
  • datahub://docs/{page} is a resource template that lists the 26 docs pages (not the changelog) and autocompletes page IDs, for clients where people attach context by hand.
  • Server instructions are rewritten from 2.2 KB to 1.6 KB. Claude Code keeps only the first 2 KB, so the old feedback guidance was cut off there. The text now says what Data Hub is and points how-to questions at search_docs. A unit test fails if it grows past 2,048 bytes. datahub://glossary stays, but the instructions no longer point to it, because most clients cannot read resources on their own.

Why tools and not only resources: in claude.ai, Claude Desktop, VS Code, and ChatGPT, the model cannot read a resource by itself, and the MCP specification says model-controlled access should use tools. The resource template is there for people who attach pages by hand.

How the docs get into the web app

Each deployment answers from its own docs, so the pages are bundled with the web app:

  • docs/site/scripts/generate-docs-corpus.ts writes web/lib/mcp/docs/docs-corpus.snapshot.json using the same Markdown the site serves at /docs/<page>.md.
  • make docs-catalogs runs it last. docs-lint.yml regenerates it and fails when the committed copy differs, like the other generated files.
  • It includes the hand-written pages, including cli-reference, mcp, and api (the overview). It leaves out the generated API endpoint pages, the MCP catalog pages, and docs/developer/.
  • The docs package becomes an ES module package ("type": "module") and gains tsx, because Fumadocs can only load the site's MDX outside Next.js that way. The docs site's typecheck, lint, link check, and production build all still pass.
  • Search uses minisearch (new dependency in web/), with no embeddings, extra service, or API key.

Analytics

mcp_docs_search records only a result-count bucket, and mcp_docs_read records only a page ID that resolved against the bundle. Query text is never recorded, per the rule in web/lib/analytics/track.ts. A rising share of empty searches shows where the docs have gaps.

Testing

  • 21 golden questions in web/tests/unit/mcp-docs-search.test.ts, each with the page that should answer it, which must be in the top three results. I checked they can fail: turning off stop-word removal broke four of them.
  • Unit tests for section splitting, plain-text conversion, excerpts, and page references. Protocol tests for both tools and the resource template. Analytics tests. A test that every page fits in one tool result under Claude Code's 25,000-token cap.
  • The MCP integration suite now calls both tools against a real next build and next start, which proves the bundle and the changelog files ship with the app. mcp.test.ts and mcp-oauth.test.ts pass (37 tests), the unit suite passes (550 tests), and make check passes.
  • A clean npm ci followed by make docs-catalogs leaves no changes, so CI's drift check will pass.
Excerpt from a recorded session over HTTP against the production build
== search_docs("how do I revoke a token") ==
- manage-tokens#revoke-a-token
    url: …/docs/manage-tokens#revoke-a-token
    Go to Settings → Access Tokens. Click the delete icon on the token’s row and confirm. The token stops working immediately. …
- manage-tokens
- security#token-hygiene
- security#how-tokens-act
- concepts#personal-access-token

== search_docs("zxqv plorgnak"): nothing matches ==
results: 0, pages listed: 26
hint: Nothing matched. Pick a page from `pages` and call read_doc, or try different words. If the docs do not cover the question, say so and offer to report the gap with send_feedback.

== read_doc(page="manage-token"): a wrong page ID ==
isError: true
Page 'manage-token' not found. Closest: manage-tokens. Docs pages: overview, self-hosting, …

Notes for reviewers

  • The plan said 29 docs pages. The site has 29, but three are the generated MCP catalogs, which are left out, so the bundle and the resource list have 26.
  • Changelog entries have no page of their own in the app (the changelog is a dialog), so their link is the entry's own docs link, or none.
  • Docs-only changes now also change a file under web/, so the web app's Vercel project rebuilds for them. That is intended: the deployed MCP server has to carry the new text.
  • Postgres and uv were missing on the VM I used, so I installed them to run the integration tests and make check.
Open in Web Open in Cursor 

cursoragent and others added 3 commits October 9, 2026 06:09
A script in the docs site writes every hand-written docs page as Markdown
into web/lib/mcp/docs/, using the same text the site serves at /docs/<page>.md.
make docs-catalogs runs it last, and docs-lint.yml fails when the committed
copy is stale.

The docs package becomes an ES module package so Node can load the Fumadocs
output, and gains tsx to run the script.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
Adds two MCP tools and a datahub://docs/{page} resource template that serve
the bundled docs pages and the changelog. search_docs returns up to five
matching sections with excerpts and links, and lists every page when nothing
matches. read_doc returns one page or one section, so no call loads all the
docs. Analytics record result counts and page IDs, never the query text.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
The old text was 2.2 KB, so Claude Code cut off the feedback guidance. The
new text says what Data Hub is, points how-to questions at search_docs, and
no longer sends agents to the glossary resource, which most clients cannot
read on their own.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
data-hub Ready Ready Preview Oct 9, 2026 6:22pm UTC
data-hub-docs Ready Ready Preview Oct 9, 2026 6:22pm UTC

Request Review

Adds 21 golden questions that each name the page that should answer them,
tests for the Markdown helpers and page references, protocol tests for the
two tools and the resource template, analytics tests, and a test that keeps
the server instructions under 2 KB. The integration test also calls both
tools against the production build, which proves the bundled docs and the
changelog ship with the app.

A test found that a card description ending in a period got a second one in
search excerpts, so that is fixed too.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
Adds a section to the MCP overview page, a changelog entry, a developer page
on how the docs bundle and search work, and notes in AGENTS.md and
docs/site/AGENTS.md that docs changes need make docs-catalogs. The bundled
docs are regenerated to include the new MCP section.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
Excerpts lost the closing > of text such as <token_id> and showed rows of
table dashes. Docs resource names now add a page suffix only to the second
and later pages that share a title, so the first stays plain.

Co-authored-by: Wasim Amiri <wasimxyz@users.noreply.github.com>
@wasimxyz
wasimxyz marked this pull request as ready for review October 9, 2026 06:32
@wasimxyz wasimxyz self-assigned this Oct 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
search_docs now counts a section as an answer only when it holds two thirds of the question's words and every word appears in the docs. Otherwise it adds a hint that names missing words and offers send_feedback, and analytics counts it in the 0 bucket. Watcher bump instructions now regenerate the docs bundle, the code uses 'bundle' instead of 'corpus', and the MCP catalog carries the tool group labels the docs site reads.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wasimxyz
wasimxyz merged commit 57d95b6 into staging Oct 9, 2026
9 checks passed
@wasimxyz
wasimxyz deleted the cursor/docs-over-mcp-97c4 branch October 9, 2026 18:27

This branch was successfully deployed

2 active deployments
Preview – data-hub — 07e1bea1 Deployed Oct 9, 2026 by vercel[bot]
Preview – data-hub-docs — 07e1bea1 Deployed Oct 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants