Inspiration
AI agents are getting better at remembering things across sessions, but persistent memory creates a new problem: who decides what the agent is allowed to remember as truth?
Most memory systems focus on retrieval—store information, search it later, and return the most relevant result. But project memory is not just a collection of facts. Decisions change. Requirements conflict. Old assumptions become invalid. And if an agent can silently rewrite its own memory, the same system is both suggesting and deciding what becomes authoritative.
I wanted a different model:
Agents can propose. Humans decide.
That became the core idea behind Waggle WebMCP: a shared project-memory workspace where ChatGPT and humans operate on the same governed memory, but humans retain control over what becomes authoritative.
Waggle already existed as a local-first persistent memory engine with graph-backed retrieval, provenance, SQLite storage, optional Neo4j support, and an MCP interface. For the WebMCP Challenge, we extended that foundation into a new browser-native human + agent collaboration experience.
What it does
Waggle WebMCP gives ChatGPT direct semantic access to the memory visible in the Waggle Workspace.
Instead of forcing the model to inspect cards, scrape the DOM, or navigate a dashboard, the page exposes four purpose-built WebMCP tools:
get_project_brief— gives ChatGPT a structured summary of the project's current authoritative state.recall_memory— retrieves current authoritative memories while excluding superseded or expired information.propose_memory_change— lets the agent suggest a correction without modifying authoritative memory.apply_approved_memory_change— applies only a proposal that has already been explicitly approved by a human.
The important part is the boundary between the last two operations.
An agent can say:
“This storage decision conflicts with the local-first requirement. I recommend changing it.”
But the change remains a proposal.
A human can then reject it, approve it, or edit the exact wording before approval.
Once approved, the content is frozen. When ChatGPT later calls apply_approved_memory_change, it provides only the proposal ID—it cannot substitute different text or bypass the review step.
The resulting flow is:
Agent recalls memory
↓
Agent proposes a correction
↓
Human edits / approves
↓
ChatGPT applies the approved proposal
↓
Previous memory is superseded
↓
New human-approved memory becomes authoritative
↓
ChatGPT immediately recalls the corrected truth
Every change preserves provenance and an updates relationship between the previous and new memory.
The user experience
The main Workspace is designed for humans rather than as a raw graph viewer.
It shows:
- Current Context
- Key Decisions
- Recent Memories
- Pending Human Review
- a live Memory Map
- an auditable Activity timeline
For deeper inspection, Graph Studio shows the actual underlying nodes and edges, including supersession lineage.
I also built a six-step Guided Demo specifically around real WebMCP events.
It does not use fake “Next” buttons.
The guide advances only when the matching action really occurs:
- ChatGPT calls
get_project_brief - ChatGPT calls
recall_memory - ChatGPT creates a proposal
- The human edits and approves it
- ChatGPT applies the approved proposal
- ChatGPT recalls the newly authoritative memory
At the end, the judge can open Graph Studio and inspect the exact lineage that was created.
How I built it
The challenge implementation keeps Waggle's existing memory engine as the source of truth rather than creating a second WebMCP-specific database.
The architecture is roughly:
Human ───────────────→ React Workspace
│
│ review / inspect
▼
ChatGPT ── WebMCP ──→ Waggle Web API
│
Workspace services
/ \
MemoryGraph Proposal state
│ │
└──── approved ────┘
│
▼
Authoritative memory + provenance
The frontend is built with React/Vite, while the existing Waggle backend runs as a Python ASGI application.
The WebMCP adapter registers page-level tools using document.modelContext.registerTool(...).
For authoritative recall, we reuse Waggle's scoped graph retrieval instead of implementing a parallel search system.
Proposal state is stored separately from normal knowledge so a pending agent suggestion cannot accidentally appear in ordinary memory retrieval.
Each proposal records a fingerprint of the memory version it targets. If that memory changes before review or application, the proposal becomes stale rather than overwriting newer information.
When an approved proposal is applied:
- a new authoritative memory is created;
- the previous memory becomes superseded;
- an
updatesedge links the two; - proposal and reviewer provenance are preserved;
- subsequent normal recall returns only the new authority.
Building a safe human approval boundary
One of the hardest parts was making human approval an actual system property, rather than just a UI convention.
A weaker implementation could have let the model call something like:
update_memory(memory_id, new_content)
and merely asked it to wait for permission.
We deliberately did not do that.
Instead:
propose_memory_change(...)
can create workflow state but cannot change authoritative memory.
And:
apply_approved_memory_change(proposal_id)
accepts only an already-approved proposal identifier.
There is no new_content parameter at application time.
That means the agent cannot alter the text after the human has reviewed it.
This separation between proposal authority and write authority became one of the most important lessons from the project.
Challenges we faced
1. Avoiding a second memory system
Waggle already had graph storage, retrieval, provenance, and validity semantics. It would have been easy to build a simplified WebMCP demo beside it.
Instead, we made the Workspace and WebMCP tools operate on the same underlying memory state so the demo represents the actual product architecture.
2. Handling stale proposals safely
A proposal may be correct when created but dangerous later if another actor has already changed its target memory.
We solved this with version fingerprints and fail-closed stale handling. A stale proposal cannot overwrite a newer authoritative state.
3. Hosting a zero-login judge experience
The core Waggle architecture is local-first, but a hackathon judge needs a public URL with no setup.
For the challenge deployment, each browser gets an isolated seeded workspace. Sessions are separated using an opaque secure cookie and separate project namespaces, so one judge cannot modify another judge's demo state.
The hosted instance uses ephemeral SQLite because it runs on a free deployment tier. It is explicitly a seeded challenge demonstration, not a claim that the hosted deployment itself is local-first.
4. Real ChatGPT browser integration
A normal browser test was not enough—we needed the actual ChatGPT Site-tool flow to work.
We added a Site-tools preflight to the Workspace and validated the complete sequence in native ChatGPT twice from clean seeded states.
All four WebMCP tools were discovered and invoked, the human-approved SQLite decision became authoritative, the previous Neo4j decision was excluded from normal recall, and Graph Studio showed the resulting real updates lineage.
5. Responsive human review
The ChatGPT browser has a narrower usable viewport than a normal desktop browser. During testing, the Guided Demo could overlap the human approval controls.
We changed the guide layout specifically for the human-review step and added browser regression coverage at the smaller viewport so Edit & Approve remains accessible.
What I learned
The biggest lesson was that human control should be represented as a capability boundary, not just a prompt instruction.
Telling an agent “please ask before changing memory” is weaker than designing the API so it physically cannot apply arbitrary content.
We also learned that provenance is much easier to understand when presented at two levels:
- the Workspace explains what the human needs to decide;
- Graph Studio explains what actually happened to the underlying memory.
And WebMCP turned out to be especially well suited to this kind of interaction because the human and the model can collaborate around the same visible web application while each side has different capabilities.
The agent does not need to imitate a human clicking through the interface. It can call semantic tools directly, while the human retains the parts of the workflow that should remain human-controlled.
What I'm proud of
The final challenge flow is not simulated.
A judge can:
- open Waggle with no account;
- ask ChatGPT for project context;
- retrieve the current authoritative decision;
- ask the agent to propose a correction;
- personally edit and approve the exact replacement;
- ask ChatGPT to apply it;
- ask the original question again;
- receive the new human-approved answer;
- inspect the complete provenance and supersession chain in Graph Studio.
That single interaction demonstrates the idea behind the entire project:
Waggle — humans govern what agents remember.
What's next
The challenge version is intentionally focused on the governed-memory loop.
Future work could include richer evidence inspection, personal durable workspaces, local Waggle synchronization, multi-project collaboration, and additional ways for participating agents to share context without sacrificing human authority.
But the core principle will remain the same:
persistent agent memory should not mean invisible agent authority.
Built With
- javascript
- mcp
- python
- react
- vite
- webmcp
Log in or sign up for Devpost to join the conversation.