Inspiration

Every "AI cleans your data" demo we'd seen had the same shape: a chat box, a spinner, and a table that changed. You never saw what the model was about to do, you couldn't check its arithmetic, and if it was wrong you started over.

WebMCP changes what's possible there. If a page can publish real tools on document.modelContext, an agent doesn't need to guess at your UI — it calls the same functions your buttons call. That reframes the problem. The interesting question stops being "can a model clean a spreadsheet" and becomes "what has to be true before you'd let one write to your data?"

Our answer: it has to show you what it measured, ask before it writes, record who did it, and let you undo it. So we built the execution environment for that, rather than another chat wrapper.

What it does

DataSweep Pro is a data cleaning studio where an agent and a person work on the same messy spreadsheet through the same 15 WebMCP tools.

Load a CSV. Eight analyzers run concurrently and find what's actually wrong — mixed date formats, duplicates, currency strings that won't sum, whitespace that breaks joins, outliers, and rows the parser silently dropped. Each finding carries the measurement behind it and a suggested fix.

An agent can do the same thing through the same tools. The load-bearing property:

There is no separate "agent path" that could behave differently from the buttons.

One tool surface, four callers

Everything runs locally. Your file is parsed and queried by DuckDB compiled to WebAssembly, in the tab. External communication — a model API, a desktop MCP client, a GitHub pull request — is opt-in and separately gated.

How we built it

Four layers, each testable without the one above it. Arrows point one way only: the domain layer knows nothing about tools, and the engine knows nothing about MCP.

Four layers

The WebMCP surface. 15 tools registered via @mcp-b/global. Each is one ToolDefinition — name, description, JSON Schema, annotations, execute — and that single object serves three consumers: WebMCP registration, the in-app Tool Inspector, and the agent loop. That's what guarantees the schema a reviewer inspects is the schema an agent is offered. Bridgeable to Claude Desktop with @mcp-b/webmcp-local-relay.

The approval gate. A mutating tool called without a confirmation_token runs the transformation against scratch tables, measures exactly what changed, drops the scratch tables, and returns a token. Your data hasn't moved.

The two-phase approval gate

The token is bound to a fingerprint of the exact arguments, single-use, and expiring — so an agent can't preview something harmless and reuse the token for something else. Enforced once in middleware, not per tool. A mutating tool declared without a preview() throws at construction rather than silently skipping the gate.

Prompt injection. A spreadsheet cell is attacker-controlled text. Cell content leaves every tool inside a fence carrying a per-call random nonce, so injected text can't forge the closing tag and escape into the instruction region. Pattern detection also runs, but it's treated as advisory — the structural defence is what holds for payloads no rule matches.

Testing. 380 tests. The integration and security-eval suites run real DuckDB-Wasm through its Node bindings, not a mock, because the interesting bugs live in the SQL.

Built With

  • anthropic-claude
  • dbt
  • duckdb
  • github-api
  • great-expectations
  • mcp
  • model-context-protocol
  • node.js
  • openai
  • radix-ui
  • react
  • tailwindcss
  • typescript
  • vite
  • vitest
  • webassembly
  • webmcp
  • zod
Share this project:

Updates

Submission history