Can a small learning site (a go-to-market study lab) be its own database that agents can search and add to, on free Cloudflare?
A Study Site That Is Also an Agent-Searchable Database
Mostly yes. The whole site now lives in one Cloudflare D1 table of 1007 rows with full-text search. An MCP endpoint gives agents six tools to search, read and add. It sits behind a login, and agents get in with a service token. Two things broke on the way: the Git deploy and D1's statement size cap.
- Cloudflare Pages
- Cloudflare D1
- Cloudflare Access
- MCP
- GitHub Actions
Relevant services: Thrivbe AI
Hypothesis
A two-person study group is learning go-to-market together. Everything it reads sits in one repo: guides, skills, research notes, tools, a timeline. A search box helps a person. An agent needs more. If every page on the site is also a database row, an agent can search it, read it and add notes to it without scraping HTML. If that all runs on the free Cloudflare tier, it costs nothing to keep.
What we built
- A static site on Cloudflare Pages. Guides, skills, repos, tools and a timeline, with a search palette.
- One D1 table for everything. The table is
items, with a kind, title, description, tags and abodycolumn for the full text. A second table,items_fts, gives full-text search over all of it. On the first pass we indexed only titles and links. We then moved the full text in, so the database holds the whole site. - About 1007 rows. 885 are seeded from the repo on every deploy: 56 guides (text pulled from the PDFs), 415 skills, 65 repos, 336 tools, 77 pages, plus EU market and play records, timeline items and two lead-finder run summaries with numbers only. The rest are rows agents added.
- An MCP endpoint. One Pages Function speaks MCP over plain HTTP. It has
six tools:
search,get,list_kinds,add,updateandsql.searchreturns a snippet from where the text matched.sqlis read-only and capped at 200 rows. - A login in front of all of it. People get an email code. Agents send a service token with every request. Without it, every URL returns the login page, not JSON.
- A smoke test. A short script calls each tool and stops on the first failure. Each run adds one note row.
- Agent rows survive deploys. Seeded rows are refreshed on each deploy. Rows added through the endpoint keep their own ids and are left alone.
What broke
- Cloudflare's Git integration failed. The Pages Git connection returned
error 8000011 on our account. We stopped fighting it. A GitHub Action now
seeds the database and uploads the site directly on every merge to
main, with a token that can only write Pages and D1. - D1 refuses statements over 100 KB. Long guide texts and transcripts hit that cap. The seed script now splits any body into chunks of 40,000 characters.
- A shared password was the wrong gate. We built one, then removed it the same day. Cloudflare Access does the login with no password to share.
Learnings
- One table is enough. A single
itemstable with akindcolumn held guides, skills, tools and notes without any joins. - Index the body, not just the title. Search over titles alone misses most of what a guide says. Full text made the snippets useful.
- Plain HTTP beats a server. A stateless function with no packages and no config file was enough for MCP.
- Seed and agent writes need separate lanes. Marking agent rows by source lets a deploy rebuild the seeded rows without touching them.
- A login page looks like a bug. When the headers are wrong, an agent gets HTML and a confusing parse error. The README says so up front.
Result
The question is answered for this size of site. A 1007-row site, searchable by full text, runs on free Cloudflare services with an agent endpoint on top. We have not measured load, cost over time or search quality against a baseline, so we make no claim there.
What's next
- Wire the endpoint into our main agent setup. It is not connected there yet.
- Measure how often agents find the right page in the first few results.
- Keep an eye on the 40,000-character chunking if bodies grow.
Log
- 2026-11-04: Site moved to Cloudflare Pages with search and automatic deploys. D1 added and seeded on deploy. Shared password built, then replaced by Cloudflare Access. MCP endpoint went live with six tools. Connection notes written for three kinds of agent client. Full text of the whole site moved into the database (1007 rows). An optional re-rank by meaning was added to the search palette.
