AI AgentsCase study

Greenlight Console: Every Write Goes Through a Human

Delivered scope

Every write operation pauses on an in-chat approval card and runs only via a single-use, argument-bound token minted by a human click

Conceptual artwork. Not a photograph or screenshot of the client's system.
Client
Open-source project
Category
AI Agents
Location
Remote
Completed
August 16, 2026

The problem

An agent that can call tools is an agent that can change data. The moment an agent gets access to write operations — refunds, order changes, customer updates — the real question is no longer “is the model smart enough” but “who approves its writes, and where is the record?”. Most chat consoles for agents answer that by not answering: tool calls hide behind the final text.

What we built

A streaming chat console for an MCP agent, the client-side counterpart to the mcp-guarded-tools server. The agent works through four guarded meta-tools — search_tools, describe_tool, invoke_tool, confirm_action — and every tool call renders as an inspectable card: the exact arguments, the raw result, the latency, and which guardrails ran.

When the agent attempts a write, the guardrail chain denies it with CONFIRMATION_REQUIRED and an approval card physically replaces the composer — the operator cannot type past it; Approve and Deny are the only exits. One click on Approve mints a single-use, argument-bound token via confirm_action, and the paused loop resumes. The /audit page shows the server’s append-only JSONL log, with PII-redaction chips on arguments that contained personal data.

Engineering decisions

Approval timeouts fail closed. An unanswered approval is treated as a denial; silence never executes a write.

Provenance is read off the surface color. Human messages white, agent text mint, tool plumbing backstage grey, blocked state amber — authorship is legible at a glance without reading a label, and every chromatic status is paired with a glyph or text.

The agent loop is provider-agnostic. The default provider is a deterministic scripted mock, so the whole console — including the refund scenario that triggers the gate — runs offline with zero API keys. A live provider (DeepSeek) is optional.

The measured results

Two offline benches run against a real spawned server. The token bench shows a mixed result and keeps it mixed: on the read scenario the four-meta-tool facade wins decisively (2,382 vs 6,360 cumulative prompt tokens); on the refund scenario it loses (7,179 vs 6,380) because discovery, the denial, and the confirm-and-retry add four extra rounds that get re-billed too. The TTFT bench shows single-digit-millisecond plumbing latency (p50 2.6–4.9 ms) — in live mode those milliseconds vanish under model latency; the point is the governance layer is not where the time goes. Both are demonstration numbers from the mock provider, not production measurements.

Running it

npm ci && npm run demo, open http://localhost:3000 — sixty seconds, no keys, no database. Click the refund scenario chip, watch the agent discover tools and then stop at the gate, then approve or deny it. Reproduce the benches with npm run bench:tokens and npm run bench:ttft.

From this study to your project

Does your team face a similar problem?

Tell us about the workflow and its constraints. We start with a scope we can describe and verify.

Next case study

Hybrid RAG Reference — Benchmarkable Hybrid Retrieval