Inspiration

Plenty of businesses still run on web software that has no API and no export button: clinic portals, vendor systems, internal admin tools. Their data is trapped behind screens, so people become the integration, retyping and copying records between systems by hand.

Replacing these systems is slow and risky, mostly because nobody knows exactly what's inside them. We wanted to solve that first step with nothing but a URL, and without touching the old system's code.

The name is a play on words: REST + restore. We give old systems a REST API and restore access to their data.

What it does

Paste in a URL, and RESTore's agents:

  1. Explore the site on their own, in read-only mode, and map every page type
  2. Extract its records into SpacetimeDB, using a typed data model
  3. Design a REST API based on the real data and the forms they found
  4. Serve that API, an MCP server so AI assistants can use the same operations, and generated docs

A web dashboard lets you watch each run live.

How we built it

  • Explorer agent: Playwright captures each page. Nemotron 3 Nano Omni reads the DOM and a screenshot to work out what the page is, and Nemotron Super picks the next safe action.
  • Extractor: the Explorer measures a "recipe" for each list, detail, and form page type, so plain code can do the extraction without calling a model.
  • Operator agent: code profiles the real field values, then Nemotron designs the endpoints. Code checks every field, path, and filter, and Nemotron gets one chance to fix any problems. Anything still invalid is dropped.
  • Backend: SpacetimeDB stores the records, schemas, jobs, and events. FastAPI serves the generated API and the MCP server.
  • Orchestration: NVIDIA NIM hosts the models, and the Explorer is also registered as a NeMo Agent Toolkit workflow.

The key design choice was Nemotron learns once, code runs fast. Calling a model for every record scales with the number of records $N$, while learning each page type once scales with the number of page types $T$:

$$ \text{calls}{\text{per record}} = O(N) \qquad \text{vs.} \qquad \text{calls}{\text{RESTore}} = O(T), \quad T \ll N $$

Challenges we ran into

  • Finding the right scope: we started with a modern UI overlay, moved to a migration tool with two-way sync, and finally landed on database + API + MCP. We also dropped Windows desktop capture along the way.
  • Exploring safely: an autonomous agent on a live system can't be allowed to change anything. A browser-level guard aborts every non-GET request except a single login submit, the Explorer never clicks buttons, and it never follows links that look destructive, like "delete" or "log out".
  • Trusting model output: model answers can be malformed or simply wrong, so we validate every Nemotron response and fall back to heuristics or code when one fails. Those fallbacks are logged and labelled rather than hidden.
  • Messy legacy pages: cells like "Smith, John", inconsistent date formats, pagination, and session timeouts all needed handling. Real sites were harder still: a run on a personal academic site produced entities with no records at all, which is why we added a URL fit check that runs before a full exploration.
  • Testing without real data: we couldn't practice on real patient records, so we built mock 2005-style sites from data files. Because the pipeline knows the right answers, it can check its output field by field and fail if any write reaches the site.
  • Building in parallel: four people were working on connected agents at once, so we agreed on shared JSON formats early and passed results through a common output folder.

Accomplishments that we're proud of

Starting from a single URL, the whole workflow runs from the dashboard: explore, design the API, publish, load into SpacetimeDB, and start the API and MCP server. One committed run against Hacker News holds 2,582 posts.

What we learned

  • Agents are most reliable when models make the decisions and code does the checking and the repetitive work.
  • Safety rules belong in the system itself, not in a prompt.
  • Being clear about limits builds trust. RESTore can only see what a site shows, so hidden logic like billing formulas stays out of reach.
  • Agreeing on data formats early is what made parallel work possible in a hackathon.

What's next

  • Live writes: write endpoints are already designed from the forms the agents find, but they return 501 for now. Next, we'll connect a worker that performs each write on the old system and verifies the result.
  • Better fit checks: use a real browser and a Nemotron call, so JavaScript-heavy sites are judged properly.
  • On-premises deployment: self-host the models so sensitive data never leaves the building.

Built With

Share this project:

Updates

Submission history