How we exposed our docs as a grounded MCP server (Cloudflare AI Search + a stateless Worker)
LLMs hallucinate most confidently about exactly the domain we publish on — Chinese licenses, store policies, cloud partitions. I run chinaready.co, an editorial site about China market entry for Western software teams (full disclosure: it's my site; the server below is free and MIT-licensed, no acc

LLMs hallucinate most confidently about exactly the domain we publish on — Chinese licenses, store policies, cloud partitions. I run chinaready.co, an editorial site about China market entry for Western software teams (full disclosure: it's my site; the server below is free and MIT-licensed, no account needed). This post documents how we turned that corpus into a public MCP server anyone can add to their AI client — and the protocol and platform quirks we hit along the way.
An endpoint your MCP client can use right now:
https://mcp.chinaready.co/mcp Enter fullscreen mode Exit fullscreen mode Three read-only tools:
I verified the flow end-to-end in Cursor and opencode: exact terms like "B25" (the ICP license threshold) land on the right article, answers carry full chinaready.co URLs to cite.
Install snippets are on our docs page (Cursor and VS Code have working one-click links): https://chinaready.co/docs/api/
The corpus is ~2,700 chunks extracted at build time from published guides (legal pages and forms excluded). Retrieval runs on Cloudflare AI Search ( https://developers.cloudflare.com/ai-search/ ).
We started vector-only. That misses exact terms — a query for "B25" (a specific license threshold) returned semantically-near-but-wrong articles. Switching the index to hybrid (BM25 keyword + vector, RRF fusion) made exact-term queries land first try. If your corpus has codes, product names, or policy numbers, hybrid is not optional.
Cloudflare AI Search hosts an MCP endpoint itself, but it couldn't give us two things some clients and directories expect: tool annotations ( readOnlyHint, title ) and a branded serverInfo.name (it reports "Cloudflare AI Search").
So the public endpoint is a thin wrapper — a stateless Cloudflare Worker implementing Streamable HTTP JSON-RPC directly (initialize / tools/list / tools/call), about 300 lines, no SDK and no session state:
https://github.com/chinaready/mcp Enter fullscreen mode Exit fullscreen mode Stateless JSON responses (no SSE stream) turned out to be fine for every client we tested; the MCP spec allows both.
The rule we settled on: every machine-readable result carries a human-checkable absolute URL. search dedupes chunks to article level and prints title + URL + relevance + snippet; get_article returns Markdown negotiated via Accept: text/markdown (with an HTML-stripping fallback for subrequests that skip the converter).
The wrapper is MIT and makes a decent template if you want to expose your own docs the same way. Questions and PRs welcome.