Inspiration
Every AI agent shipping today can search the web. None of them can read Thailand's research output.
Thailand's National Convention on Civil Engineering has run for decades. The proceedings exist as PDFs. Mixed encodings, no text layer on older scans, no cross-volume search, no API. To an agent, this archive does not exist.
So a graduate student surveying prior work does it the 2005 way: download a volume, Ctrl-F, guess Thai keyword variants, repeat. Then their advisor asks "has anyone already done this?" and nobody can answer with confidence.
Point a general-purpose agent at it and you get the worst possible failure mode: a citation that looks right. A fake page number inside a real volume survives review. It gets published.
That's the wedge. Not "search is bad." The archive has no interface an agent can hold onto, and the substitute agents invent is dangerous.
Three things made now the moment to build it:
- Agents got good enough to be trusted with research tasks — and therefore dangerous enough that unverifiable citations became a liability, not a quirk.
- WebMCP made the browser a distribution channel for tools. Before this, an agent-facing corpus meant getting into someone's MCP config. Now it means shipping a URL you can send to a professor.
- Retrieval got cheap enough to run at national scale. Our full stack runs under \$10/month. Archives held by underfunded institutions only get digitized if the running cost rounds to zero. ## What it does Seedy Research is a research workspace over an indexed Thai corpus — CE Project archives and NCCE Proceedings vol. 25, 26, and 29 — that exposes itself to any agent in the page.
| Surface | What it does | Agent-callable |
|---|---|---|
| Explore | Thai-first discovery; local = page-cited evidence, global = links only | ✅ |
| Chat | Cited answers, paragraph-level retrieval | ✅ |
| Workspace | Shared state: saved passages, comparisons, candidate gap | ✅ read + write |
| Research Path | Evidence → connection → gap → testable next study | ✅ |
| Share & export | Session URL, JSON export of the full evidence trail | ✅ |
Every surface is agent-callable. That's deliberate. A workspace the agent can't write to is a workspace the human maintains alone.
What people and agents can now do together that was hard or impossible before:
- Ask across 941 Thai PDFs and get a page you can open. The agent calls a tool, the passage renders with volume and page, and the human clicks through to the Thai original.
- Cross-language research without losing the source. The corpus is Thai. The agent reasons and answers in English while every citation still points at the Thai page.
- Co-author a gap statement. Human sets direction, agent fills evidence into the shared workspace, human prunes. Every line traceable.
- Hand off a session, not a transcript. JSON export or session URL — the next person, or the next agent, resumes with the same evidence set. ## How we built it We built the server-side MCP version first. It was the wrong product.
A server-side MCP server hands an agent a database. It returns a string: "NCCE vol. 26, p. 412 reports a 14% reduction." The researcher then has two options — trust it, or go find volume 26 themselves. Neither one is research.
WebMCP hands the agent the application. The agent calls our tool, the passage renders in the human's Evidence panel at that page in the original Thai, and then the tool returns to the agent. Verification stops being a task and becomes a glance. Same retrieval engine, completely different product.
The tool layer. Next.js 15 on Vercel. Tools register client-side from a provider that mounts on session init.
document.modelContext.registerTool({
name: "search_evidence",
description:
"Search the indexed Thai research corpus and return paragraph-level passages " +
"with exact volume and page citations. Use for any claim that needs citing. " +
"Do NOT use to find papers outside the indexed corpus — use " +
"discover_related_research for that.",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
collection: { enum: ["all", "ce_project", "ncce"] },
max_passages: { type: "integer", minimum: 1, maximum: 20 }
},
required: ["query"]
},
execute: async ({ query, collection = "all", max_passages = 6 }) => {
const passages = await retrieve({ query, collection, max_passages });
setEvidencePanel(passages); // the human sees it first
return { content: [{ type: "text", text: formatWithCitations(passages) }] };
}
});
Two contracts hold the design together:
Render before return. execute writes app state, then returns to the agent.
One line of ordering separates a shared session from a remote control.
We did not wrap our API. We shipped the verbs a researcher uses. Closed domains are enums, so agents produce a valid call on the first attempt instead of probing.
| Tool | What it does for the agent |
|---|---|
search_evidence |
Page-cited paragraph retrieval over the local corpus |
answer_with_citations |
Cited answer through the bounded-context planner |
open_source_page |
Opens a document at a specific page for the human |
discover_related_research |
Metadata-only global discovery — no quotable field |
save_to_workspace |
Writes a passage into shared state |
list_workspace |
Reads back current shared state |
build_research_path |
Evidence → connection → gap → next study |
set_collection_filter |
Scopes the session to a collection |
export_session |
Full evidence trail as JSON |
Under the tool boundary.
ChatGPT / Chrome agent
│ document.modelContext.registerTool()
▼
Next.js 15 (Vercel) ── WebMCP tool layer ──► app state (Evidence, Workspace)
│
▼
FastAPI ── Bounded Agentic Context ──► planner → dedup → context budget
│ → citation formatting
▼
Supabase pgvector — 49,965 chunks, page provenance preserved end to end
The Bounded Agentic Context layer is our real engineering asset. A planner decides retrieval depth, deduplicates overlapping chunks, manages a context budget, and formats citations before anything reaches a model. The agent makes one call and gets clean, budgeted, citation-formatted results. All the expensive judgment lives inside the tool where we can guarantee it, instead of hoping the calling agent gets it right — and every future agent client inherits that for free.
| Collection | PDFs | Chunks |
|---|---|---|
| CE Project Database | 67 | 4,520 |
| NCCE Database | 874 | 45,445 |
| Total | 941 | 49,965 |
Auth, rate limiting, timeout control. Under \$10/month.
Trust boundary and user control. Exposing tools means letting something else act inside a logged-in session, so we treated that as a product decision:
- Reads are free; writes are visible. Retrieval is frictionless. Anything that mutates shared state renders immediately and is reversible in one click. Nobody has to audit a log to learn what happened.
- No tool escalates scope. No generic
fetch, norun_query, no arbitrary endpoint. Closed argument spaces, enums where the domain is closed. The surface an agent sees is exactly the surface we intend. - Tools register with the session, not the origin. They mount after session init and unmount with the surfaces backing them.
- Nothing destructive is exposed. The worst outcome of a confused agent is a workspace with extra passages in it.
- Export is explicit.
export_sessionreturns to the human's session; it transmits nowhere.
That posture is the precondition for institutional adoption. A university will not put its archive behind an agent that can delete things.
When things go wrong. A demo that only shows the happy path isn't a product:
- Ambiguous requests get a question, not a guess. Scope-ambiguous queries return zero passages with an explicit note instead of weak matches. Agents route correctly on retry.
- Empty results are a real answer. "Nothing in the indexed corpus supports this" is returned as such. For a gap-finding tool, absence is the product.
- Budget overruns degrade rather than fail. Cap and deduplicate, never truncate mid-passage. Fewer complete citations, not more broken ones.
- Timeouts return partial evidence with a flag, so slow retrieval still yields something citable rather than an error the agent narrates as fact. ## Challenges we ran into Thai PDFs are hostile. Mixed encodings, no text layer on older scans, heading structure that shifts between NCCE volumes. Keeping page numbers alive through chunking, so a citation is actually clickable, was harder than retrieval itself.
Page fidelity across the tool boundary. Volume and page must survive pgvector → planner → JSON tool result → UI panel. Any layer that drops that metadata breaks the only promise we make. Most retrieval systems lose citability here, and we had to rebuild our chunker to stop doing the same.
Context budget versus completeness. Twenty passages makes an agent confident and wrong. We cap, deduplicate, and let it ask again.
Drawing the legal line without blurring the epistemic one. We can surface far more research than we can legally index. Encoding that distinction in the schema rather than in prose meant rebuilding the discovery surface from scratch. It was worth it, because the guarantee became enforceable instead of aspirational.
Choosing the right product twice. Shipping the server-side MCP version and then admitting it didn't solve the actual problem cost us time, but it's why we understand exactly what WebMCP adds.
Accomplishments that we're proud of
We put the guarantee in the type system. This is the one we'd build a company on.
We can discover far more global research than we can legally index. The lazy build blends both into answers and hopes the model hedges appropriately. It won't. So we split the tool surface instead:
search_evidencereturns passages carrying volume and page. It can only return indexed content. It is the sole source of citable claims.discover_related_researchreturns titles, authors, and links. Its output schema has no passage field and no page field. There is nothing in it to quote.
An agent cannot cite a paper we never indexed, because the tool that knows about that paper structurally cannot hand it a quotable passage. Not a prompt instruction a model discards under pressure. A type.
WebMCP tool schemas are where you encode epistemic guarantees, not just function signatures. Trust in AI research tooling is currently sold as a promise. We made it a compile-time property.
Also proud of:
- 941 documents, 49,965 chunks, fully indexed with page provenance intact — and running in production, not a notebook.
- Under \$10/month for the whole stack, including auth and rate limiting. That's what makes onboarding the next archive a weekend instead of a grant application.
- Every surface is agent-callable, including export and session sharing. We didn't leave a human-only escape hatch and call it collaboration.
What we learned
Agentic RAG and WebMCP solve different halves of the same problem. Phase one made retrieval trustworthy: top-k similarity out, a planner that budgets context and formats citations in. That killed hallucinated citations in our answers. It did nothing to make the corpus usable by an agent. WebMCP was the missing half. The corpus became a set of verbs.
Tool descriptions are the API surface, not documentation. Our first pass used
generic descriptions and agents reached for search_evidence when they wanted
discover_related_research. Rewriting descriptions to state what each tool is
not for fixed nearly all misrouting, with zero logic changes. Highest-leverage
change in the project.
Shared state changes how people prompt. Once a human watches the agent's
writes land in a panel they own, they stop writing long over-specified prompts and
start giving short corrections. Commissioning becomes editing. That shift is what
makes an agent feel like a collaborator, and it came out of one ordering decision
inside execute.
What's next for Seedy Research
Next 90 days
- More NCCE volumes; Thai university thesis archives.
- OCR over pre-2015 scanned volumes.
verify_claim: pass a claim, get supporting or contradicting passages with pages. Agent-callable fact-checking against Thai research.
Where this goes
- Beachhead: graduate students and thesis advisors in Thai engineering faculties. Every thesis needs a defensible prior-work survey. Every survey currently happens by hand.
- Expansion within Thailand: every institution holding its own un-agentable thesis and proceedings archive.
- The same playbook elsewhere: every country with a national research corpus in a non-English language has this identical problem. The pipeline is language-agnostic, and the hard part is already solved — keeping page provenance alive through chunking.
The bet
Every research archive becomes agent-callable, or it becomes invisible. Agents are the new readership. An archive with no tool surface will be cited less every year regardless of what's inside it.
We want to be the layer that makes those archives readable — starting with the one in our own country that nobody else was going to do.
Built With
- chatgpt
- embeddings
- fastapi
- json-schema
- model-context-protocol
- next.js
- openai
- pdf-parsing
- pgvector
- postgresql
- python
- rag
- react
- sse
- supabase
- tailwindcss
- thai-nlp
- typescript
- vector-search
- vercel
- webmcp
Log in or sign up for Devpost to join the conversation.