Skip to main content
Glama

Rosetta

Turn the traffic of an undocumented web system into a verified, safety-gated MCP server, and get an honest report of what could not be automated.

Web systems without API documentation are difficult to automate. Browser requests depend on hidden CSRF tokens, rotating nonces, and record-version headers that have to be traced and handled by hand. Rosetta turns a HAR capture of that traffic into MCP tools, tests them against a sandbox, repairs supported failures, and reports the actions that still need human work.

HAR capture ──▶ data-flow graph ──▶ MCP tools ──▶ verify ⇄ repair loop ──▶ deployable server + report
 (what the        (which value       (plumbing     (tested against a         (and a list of what
  browser did)     came from where)   hidden)       sandbox, regression-       needs a human)
                                                    gated)

What it does on the demo system

The demo target (demo/portal.py) is a deliberately awkward "treasury ops" portal with seven real-world quirks: a login CSRF field hidden in HTML, a session CSRF header, an ETag precondition, single-use rotating nonces, a strict decimal-string format, rate limiting, and a request signature computed by front-end JavaScript.

Requests in the capture

9

Raw endpoints found

9

Tools the agent sees

5 (plus 1 quarantined)

Token bindings hidden from the agent

7 (CSRF, ETag, nonce)

Verification, first generation

5 / 12 cases pass

Verification, after the repair loop

10 / 10 cases pass (2 iterations, ~4.5 s, 97 upstream calls)

Repairs applied automatically

3: retry on 429, "latest value" tracking for single-use nonces, decimal-string coercion

Escalated to a human

1: create_payout, whose X-Sig header is not derivable from traffic

10/10 is over the tools that remain enabled. The quarantined tool is counted as unresolved, not as a pass. Three consecutive runs gave identical numbers. The first-pass figure depends on timing (rate limiting), so expect it to vary a little on other machines; the loop's outcome does not.

The agent-facing result, from a real MCP client:

agent sees 5 tools: list_payouts, get_payout, approve_payout, get_ledger, cancel_payout
approve_payout (no confirm)          -> POST /api/payouts/P-1002/approve [preview only]
approve_payout(P-1001, 1250, confirm=true)   -> approved     # a number, coerced to "1250.00"
approve_payout(P-1002, 3400.0, confirm=true) -> approved     # nonce rotated correctly between calls
create_payout -> tool create_payout is quarantined: header 'x-sig' is high-entropy, has no source ...

Related MCP server: Clarity MCP Server

How it works

flowchart TD
  s0("ingest") --> s1("analyze") --> s2["synthesize"]
  s2 -->|verify| s3["verify_repair"] --> s4["emit"]
  s2 -->|skip| s4

1. Data-flow graph. For every value in every request, Rosetta looks for the earlier response it was copied from. Those links form a graph between endpoints (below for the demo). Echoes (a response repeating the id you just sent) are ignored. Business fields such as amounts are never auto-linked, only plumbing-shaped values are.

flowchart LR
  login("GET /login") -->|"_csrf"| post_login{{"POST /login"}}
  session("GET /api/session") -->|"csrf, x-nonce"| approve["POST …/approve"]
  list["GET /api/payouts"] -.->|"choose an id"| detail["GET …/{payout_id}"]
  detail -->|"etag → if-match"| approve
  approve -->|"x-nonce"| create["POST /api/payouts (needs human)"]
  create -->|"x-nonce"| cancel["POST …/cancel"]

2. Tools, not endpoints. The graph collapses plumbing: approve_payout(payout_id, approved_amount) fetches the CSRF token, the record's current ETag and the nonce itself. One tool per business action rather than one per HTTP call, which Speakeasy's lessons from 50 production servers flag as a problem. A planner rule keeps this safe: a state-changing endpoint is never run automatically as a prerequisite.

3. Verify and repair, with a contract. The first generation is deliberately optimistic. It is then tested against a sandbox with cases from the capture (replay), from live data (the same tool on a different record), and agent-style inputs (numbers where the capture had numeric strings). Failures are diagnosed from evidence, and a proposer suggests a typed patch:

Role

Who

Authority

Evaluator

plain code (verify.py)

defines "pass"; cannot be overridden

Proposer

heuristics, or Claude for what the rules cannot classify

proposes patches from a fixed, validated schema

Gate

loop.regression_gate

keeps a patch only if nothing that passed now fails and the pass count rises

Stop

converged · no proposals · no progress · budget · iteration cap

whatever is still failing is escalated to a human, with evidence

4. Ship. ir.json (secret-free), a stdio MCP server.py, a Dockerfile, an MCP client config snippet, the data-flow graph, the loop trace, and REPORT.md.

One finding worth stating plainly: replaying the captured create_payout request passes, because the capture's exact bytes carry a valid signature. Only a request with different content exposes that the signature cannot be reproduced. A replay-only test suite would have shipped a tool that fails on every real use. Rosetta therefore mixes in different inputs.

Safety model

  • State-changing tools return a preview unless confirm=true; nothing is sent upstream on a preview.

  • Outbound requests are limited to allow-listed hosts, including across redirects.

  • Captured secrets never enter the IR, the report, the trace or tool output. The emit step scans every output file against the capture's secrets and fails the build on a match. Credentials come from environment variables at run time.

  • Write tools are only exercised by the verifier against a sandbox (loopback, or explicitly declared).

  • Every call is appended to an audit log (ROSETTA_AUDIT_LOG) with the tool, status and a hash of the arguments.

  • Upstream error text is treated as untrusted data, including when it is shown to a model.

Run it

pip install -e ".[dev]"
python -m demo.run_demo            # portal + capture + build + agent session, ~6 s
pytest                             # 69 tests, ~8 s

# on your own capture (Chrome DevTools: Network → Save all as HAR)
export ROSETTA_USERNAME=... ROSETTA_PASSWORD=...
rosetta build capture.har --name myapp --target https://sandbox.example.com \
       --reset-url https://sandbox.example.com/__reset --allow-writes --sandbox
rosetta serve out/ir.json          # stdio MCP server
rosetta graph capture.har          # data-flow graph as Mermaid

--brain claude lets Claude propose repairs for failures the rules cannot classify (needs ANTHROPIC_API_KEY or an ant auth login profile).

Limitations, stated plainly

  • Developed and measured against one purpose-built target. The heuristics are real, but how they fare on messy third-party systems is unproven.

  • Capture is HAR in, JSON and form bodies only. No multipart, GraphQL, MFA or OAuth flows. The recorder in rosetta.capture is for scripted sessions; a Playwright recorder for live sites is not included.

  • Provenance is value matching. A value that is transformed before reuse (beyond simple prefixes like Bearer) is not linked.

  • Path templating is pattern-based (numeric, UUID, P-1001-style ids). Slugs are not detected.

  • Verifying write tools needs a resettable sandbox. Without one, writes are reported as unverified.

  • ClaudeBrain is tested against a stub client (request shape, constraint handling, degradation). It has not been run against the live API.

  • Signatures computed in client-side JavaScript are escalated, not solved. Reading the JS bundle is the obvious next step.

Layout

src/rosetta/   har · templating · schema · dataflow (provenance graph) · synth · ir · runtime
               verify · diagnose · repair · probe · brain · claude_brain · loop
               stategraph · pipeline · emit · report · server · cli
demo/          portal (target), make_capture, run_demo
tests/         analysis · synthesis · runtime safety · loop contract · Claude brain · state graph · e2e · MCP
docs/          ARCHITECTURE.md

See docs/ARCHITECTURE.md for the design decisions and algorithms.

Integuru builds a request dependency graph from a HAR and generates code for a goal; tools like har-mcp and FastMCP's OpenAPI import turn traffic and specs into MCP servers. Rosetta's emphasis is what comes after generation: testing the result against a sandbox, repairing it under a regression gate, gating writes, and saying clearly what it could not do.

MIT licensed.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    B
    maintenance
    A configurable MCP server that adapts any HTTP API into an MCP toolset with generic HTTP tools (GET, POST, PUT, DELETE) and pluggable authentication. Includes API discovery scripts and supports dynamic tool generation from OpenAPI specs or wordlist scans.
    5
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Professional MCP server for HAR (HTTP Archive) network captures, enabling AI agents to extract endpoints, detect secrets, generate code, and export to Postman/OpenAPI.
    9 npm
    MIT