Inspiration

You tell one site you want dark interfaces, compact layouts, and TypeScript. Then you open the next tool and type all of it again. And again.

Agents were supposed to remove that friction, but each one starts cold at the tab boundary, so the person ends up carrying context from site to site by hand. Being the integration layer is the last unautomated job on the web, and nobody was treating it as a problem.

WebMCP changes what a website can hand an agent: real capabilities the page declares, instead of a DOM that was never built to be driven. That made one question worth answering. If every site can expose genuine tools, what is the single shared capability that would make all of them better at once?

Memory. Not an assistant's private chat history sealed in a vendor cloud, but structured context that any participating site can read and write, with the person holding the delete key.

What it does

Tether is a shared memory layer for the agent-native web, plus two working sites that prove context survives the jump between them.

DesignLab is the producer, a small design studio. Ask the agent to remember your preferences and its save_preference tool applies them to the canvas and writes them to Tether in the same call.

DevForge is the consumer, a project scaffolder whose form has a project-name field and nothing else. Its create_project tool asks Tether what you prefer, then configures six things it never asked about: language, theme, layout density, framework, package manager, and styling, down to the lock file and the install command.

The Tether control plane shows every memory with its source site, the tool that wrote it, tags, a confidence score, and a timestamp. Inspect, search, edit, add, or permanently delete any of it.

Try it in 30 seconds

  1. Open DesignLab and ask the agent: "Remember that I prefer dark interfaces, compact layouts, and TypeScript." The studio turns dark and compact, and three structured memories land in Tether.
  2. Open the dashboard. They are already there, each carrying its full lineage.
  3. Open DevForge and ask for a starter project. It comes back TypeScript, dark, compact, with every value tracing back to the memory that produced it.
  4. Now delete the TypeScript memory and scaffold again. The language falls back to JavaScript. The others hold.

Step 4 is the whole project. A cross-site demo can be faked with a hardcoded path, and a judge should assume it was until shown otherwise. So deletion is part of the demo: pull one row out of the layer, and a different site's output changes in front of you.

None of this is limited to a fixed set of toggles. Both DesignLab and the control plane accept context in your own words through the same validated path. Say "I prefer pnpm over npm" or "I prefer Tailwind CSS for styling", and the next scaffold picks it up, install command included.

How we built it

Next.js 15 App Router and TypeScript. Tailwind for a dark, high-density developer-tool surface. Zod on every boundary. Supabase Postgres for persistence, behind a pluggable store: with no environment variables at all, a fresh clone runs immediately on an in-process driver.

Memories are structured rather than free text: content, category, tags, source, confidence, scope, timestamps. That schema is what makes the whole thing work. A pile of chat transcripts cannot be filtered, ranked, explained, or selectively deleted.

Security got real attention for a hackathon MVP. The service-role key lives only in server-only modules, so an accidental client import fails the build instead of leaking a credential. Row-level security is enabled on both tables with no permissive policies. Memory content is rendered as text by React and never injected as HTML. Sessions are opaque random ids in an httpOnly first-party cookie, with no accounts and no PII.

Challenges we ran into

Making the memory falsifiable. The cross-site moment only convinces if it can visibly fail. Building deletion into the demo, and making the fallback path genuinely fall back rather than run a second hardcoded branch, is what turned a nice animation into evidence.

Refusing to simulate. It would have been easy to fake tool calls when no agent is present and let the video imply otherwise. Detecting the absence and labelling every manual invocation cost a day and made the architecture clearer, because you can now see that the agent path and the button path run the same handler.

Keeping retrieval interpretable end to end. Carrying matchedOn reasons from the matcher through the API into the UI constrained the entire pipeline. It ruled out the easy embedding approach, and it is the reason the product can show its work.

Serverless state. The in-process store is perfect locally and wrong in production, because serverless functions do not share memory between invocations. The /api/health endpoint reports which driver is live specifically so a misconfigured deploy looks like a misconfiguration instead of a broken app.

Accomplishments that we're proud of

The delete-and-rescaffold moment. It is the rare demo that proves itself by breaking on purpose.

You can verify our claims in ninety seconds. The test suite runs against the live deployment:

curl https://tether-swart.vercel.app/api/health
# {"status":"online","driver":"supabase"}

git clone https://github.com/Dotman-Bei/Tether && cd Tether && npm install
BASE_URL=https://tether-swart.vercel.app npm test

It scopes itself to its own session cookie and cleans up after itself, so it is safe to point at production. It covers every route handler and, through them, the configured store driver: creation and defaults, numeric coercion, tag round-tripping, the duplicate guard, list ordering and filters, ranked retrieval with match reasons, update persistence, input validation, 404s, activity logging, session isolation, delete, and reset. No test framework and no dependencies.

**A fresh clone runs with zero environment variables.** `npm install && npm run dev` and the whole demo works.

**We did not overclaim the protocol.** WebMCP does not carry memory between unrelated sites on its own. It is the tool interface on each page, and Tether is the shared backplane those tools read from and write to. Saying otherwise would have been an easier pitch and a false one.

## What we learned

**Structure is what makes memory shareable.** Category, tags, source, and confidence are what let a second site retrieve something specific, apply it, show its work, and let a person govern the result. Unstructured recall cannot do any of those four things.

**Trust surfaces are product features, not compliance overhead.** The lineage drawer and the labelled telemetry stream are what make people believe the rest of it, and they were among the cheapest things in the build.

**Explainability is a design constraint, not a feature you add later.** Choosing lexical matching over embeddings looked like a downgrade until we tried to render *why* a memory was applied. The interpretable pipeline turned out to be the product.

## What's next for Tether

**Per-site scoped consent and real accounts.** The cross-origin story above, which is the difference between a demo and infrastructure.
- **A small client library** so a site joins in a few lines instead of reimplementing the contract.
- **Memory decay and conflict resolution.** Preferences change, and the layer should notice when a new statement contradicts an old one instead of accumulating both.
- **Richer context types past preferences:** working conventions, project constraints, domain vocabulary.

The two demo sites are an illustration. The direction is a shared memory layer that any experience can build on, where the person keeps the keys.

Built With

Share this project:

Updates

Submission history