About — what's in there & how it works
What: A small Cloudflare Worker that wraps
masterthemesh.com/solo/search-index.json — the same search
index the site's own filter bar uses — and exposes it as an MCP server
over streamable-HTTP. Two tools:
search(query, limit?)
Full-text search across every lab/article title, summary, tags and body. Returns ranked hits with slugs.
get_doc(slug)
Fetches the full text of one lab/article so the model can reason over it instead of guessing from the title.
Why: Asking "which lab covers RFC 8693 token exchange?" in a chat is faster than scanning the card grid. Once the model has the slug it can pull the whole article and answer follow- ups grounded in the actual content.
How it's hosted: Cloudflare Worker (free tier),
stateless — it fetches a fresh copy of search-index.json
on each call with a 5-minute edge cache. Content updates flow through
automatically when the index is rebuilt and pushed; no worker redeploy
needed.
Add it to your client
One command — claude mcp add
From any terminal:
claude mcp add --transport http solo-demos https://solo-demos-mcp.tom-ed6.workers.dev/mcp
Then in a Claude Code session, run /mcp to confirm
solo-demos is connected. The tools search and
get_doc become available immediately — no restart.
To remove it later: claude mcp remove solo-demos.
--scope project and
Claude will write it into the repo's .mcp.json instead of
your user config — handy when you only want this knowledge base in the
solo-demos repo, not everywhere.
Settings → Connectors → Add custom connector
On claude.ai (Pro / Team / Enterprise), open Settings → Connectors → Add custom connector and paste:
Name: Master the Mesh
URL: https://solo-demos-mcp.tom-ed6.workers.dev/mcp
Leave authentication off — the endpoint is public. Save, then enable the connector in any chat via the Tools menu (bottom-left of the composer).
Edit ~/.cursor/mcp.json
Cursor reads MCP servers from a JSON file. Add this entry:
{
"mcpServers": {
"solo-demos": {
"url": "https://solo-demos-mcp.tom-ed6.workers.dev/mcp"
}
}
}
Restart Cursor. The MCP indicator (bottom-right of the chat panel)
should show solo-demos with two tools loaded.
Generic MCP — streamable-HTTP transport
Anything that speaks MCP over streamable-HTTP can connect. The endpoint is the URL above; no headers, no auth, no SSE fallback needed.
# Smoke-test from the command line (no client required):
curl -s -X POST https://solo-demos-mcp.tom-ed6.workers.dev/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
You should see search and get_doc in the
response.
Try it
Once it's wired in, prompts like these should work end-to-end:
- "Which lab on masterthemesh covers MCP rug-pull / PII exfil at the gateway?"
- "Summarise the JWT token exchange field guide."
- "Find every lab that uses
enterprise-agentgateway-waypoint." - "How does the agentic-budgets-kind lab enforce rate limits — show me the policy yaml."
index.html rendered to
masterthemesh.com/solo) it won't show up in
search — that's by design, the index is built from the
published pages.
How I built and deployed this
The whole MCP server is one TypeScript file under mcp/ —
~200 lines, no database, no state. Here's the deploy story end-to-end in
case you want to spin up the same pattern for your own KB.
Reuse the existing search index — don't rebuild
The site already publishes search-index.json on every push
(built by scripts/build-search-index.py from each lab's
rendered index.html). The MCP server doesn't index anything
itself — it just fetches that same file:
// mcp/src/index.ts — the loader in full
async function loadIndex(env: Env): Promise<Index> {
const res = await fetch(env.INDEX_URL, {
cf: { cacheTtl: 300, cacheEverything: true },
});
return (await res.json()) as Index;
}
cf.cacheTtl: 300 tells Cloudflare's edge to keep the JSON
cached for 5 minutes. Push new content → it's searchable within 5 min,
with no worker redeploy.
Cloudflare's deploy CLI
Wrangler is an npm-installable CLI that bundles, uploads and routes your Worker. The whole config is one file:
# mcp/wrangler.toml
name = "solo-demos-mcp"
main = "src/index.ts"
compatibility_date = "2025-05-01"
[vars]
INDEX_URL = "https://www.masterthemesh.com/solo/search-index.json"
SITE_BASE = "https://www.masterthemesh.com/solo/"
name becomes the first segment of the public URL.
[vars] values are injected at runtime as
env.INDEX_URL / env.SITE_BASE — handy for
swapping the index source without touching code.
Three commands
cd mcp
npm install # one-time
./node_modules/.bin/wrangler login # OAuth in browser — one click
./node_modules/.bin/wrangler deploy
On a fresh Cloudflare account, the first deploy also asks you to pick
a workers.dev subdomain (becomes part of every worker URL
on your account — e.g. tom-ed6.workers.dev). End-to-end
from git clone to public endpoint: about three minutes.
workers.dev subdomain takes 1–5 min to
provision TLS globally. curl will fail with a TLS
handshake error until it's ready — wait a couple of minutes and try
again.
How Cloudflare actually runs it
Workers don't run in containers or VMs. The code runs inside a V8 isolate — the same sandbox Chrome uses for browser tabs — on every Cloudflare PoP (330+ cities). A request hits the nearest PoP, the isolate spins up in under 5 ms (no cold-start tax), and serves the response from that edge location.
For this server, the first request after the 5-minute cache expires takes one extra hop to GitHub Pages (~50 ms). Everything inside that window is served from edge memory — typically sub-20 ms end-to-end.
Source
The worker code lives under mcp/ in the
solo-demos repo.
TypeScript, ~200 LOC, no state. Redeploy after any code change with
cd mcp && ./node_modules/.bin/wrangler deploy.