OPRE
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@OPREinvestigate https://example.com and rebuild a working copy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
OPRE — Open Rebuild Engine
Understand. Rebuild. Reimagine.
OPRE is an open-source MCP server that lets any compatible AI agent investigate an existing website or application, build an evidence-backed knowledge base, and then rebuild a working alternative through an incremental, test-driven loop.
Understand — a real browser and a static analyser record what was observed, with sources, timestamps, confidence and explicit limitations.
Rebuild — a dependency-ordered backlog, task-scoped context, and a runner that actually starts and exercises the generated app.
Reimagine — reconstruct a capability, not a screenshot. Observed facts, source-derived facts and hypotheses are stored separately, so the agent never guesses silently.
OPRE ships no AI model of its own. Your agent reasons and writes code; OPRE provides research, persistent project state, retrieval, task coordination and validation.
your agent (reasoning + code) ──MCP──▶ OPRE ──▶ project directory on disk
research · knowledge · planning · validationTry it in 60 seconds
git clone https://github.com/Aayushbohora1/opre-mcp.git
cd opre-mcp
npm install # compiles dist/ automatically (prepare script)
npm run demo # drives the whole loop against https://example.com
npm run rebuild-demo # ...and rebuilds it, then scores the rebuild against the originalnpm run demo opens a real browser, records evidence, drafts a plan, and prints exactly what an
agent would see at each step. npm run rebuild-demo goes one step further: it stands in for the
coding agent with a deterministic builder, produces a runnable site, starts it, validates it in a
browser, and then measures how close it is to the original:
[6/6] fidelity against the reference
overall 93% close across 1 route(s)
93% / close
- tokens: missing "font:system-ui"
- tokens: missing "size:14px"
- tokens: unexpected "font:Times New Roman"That number is the point. Without OPRE the builder had a URL and nothing else; with it, the builder got structured evidence, persisted state, a started server, a real browser check, and an exact list of what still differs. Both demos use throwaway projects in a temp directory.
Then connect it to your agent:
{
"mcpServers": {
"opre": {
"command": "node",
"args": ["/absolute/path/to/opre-mcp/dist/index.js"],
"env": { "OPRE_HOME": "/absolute/path/to/opre-projects" }
}
}
}Your client will show 25 opre.* tools and two prompts (opreweb, opreapp). The agent's
first move should be opre.get_guide, which returns the exact next steps for the project.
Related MCP server: PixelCheck
Why it is built this way
Problem with "just look at the screenshots" | How OPRE answers it |
Agents reload the whole project into context every session | Every response is size-bounded and paginated; state lives on disk, not in the conversation. |
Claims drift from reality | Findings carry provenance, confidence and limitations; validation runs prove behaviour in a browser. |
Targets can try to manipulate the agent | Captured content is stored as untrusted evidence, scanned for injected instructions, and never treated as a command. |
One giant code-generation pass | A dependency-aware backlog; the agent takes one task, implements it, records it, validates it. |
"It looks the same" | Validation compares the running app to the reference structurally and visually, and reports a per-route fidelity score with the exact differences. |
agent (reasoning + codegen) <──MCP tools──> OPRE (research · knowledge · planning · validation) └──> project directory on disk (survives restarts)
---
## Table of contents
- [Requirements](#requirements)
- [Install](#install)
- [Connect a client](#connect-a-client)
- [The two workflows](#the-two-workflows)
- [Tool reference](#tool-reference)
- [Project layout](#project-layout)
- [Configuration (environment variables)](#configuration-environment-variables)
- [Context safety](#context-safety)
- [Security model](#security-model)
- [Development](#development)
- [What works today](#what-works-today)
- [Known limitations](#known-limitations)
- [License](#license)
---
## Requirements
| Requirement | Notes |
| ------------------------------- | ---------------------------------------------------------------------------------------------- |
| Node.js ≥ 20.10 (LTS) | Developed and tested on Node 22/24. |
| A Chromium build for Playwright | `npx playwright install chromium`. See [browser troubleshooting](#browser-troubleshooting). |
| An MCP client | Any client that speaks stdio MCP (Claude Desktop, Claude Code, Cursor, Windsurf, Continue, …). |
---
## Install
```bash
git clone <your-fork> opre-mcp
cd opre-mcp
npm install
npm run build
node dist/index.js --helpDuring development you can run the server straight from TypeScript:
npm run dev # tsx src/index.ts
npm test # unit + integration (real browser, local fixtures)
npm run verify # typecheck + lint + testsProjects live under OPRE_HOME (default ~/.opre). Each project is a self-contained directory.
Connect a client
{
"mcpServers": {
"opre": {
"command": "node",
"args": ["/absolute/path/to/opre-mcp/dist/index.js"],
"env": {
"OPRE_HOME": "/absolute/path/to/opre-projects",
"OPRE_MAX_RESPONSE_CHARS": "24000"
}
}
}
}After connecting, the client should list 24 opre.* tools and two prompts (opreweb, opreapp).
Slash commands are an agent-side convention, not an MCP feature, so OPRE ships ready-made
instructions in agents/ and /.claude/commands as well as MCP
prompts — use whichever your client supports.
Quick smoke test from a terminal:
node dist/index.js --print-configThe two workflows
/opreweb <url> — rebuild a website
opre.create_project— validate and record the target URL plus your authorisation.opre.start_research— inspect public pages with a real browser (routes, nav, forms, interactive elements, viewports, screenshots, console/network errors). Optional web search via a configured provider.opre.get_research_summary— compact, bounded overview of what was learned.opre.create_implementation_plan—mode: "draft"proposes features and tasks from the researched routes; refine withopre.upsert_task/opre.upsert_feature, or re-submit withmode: "apply".Configure the runner once:
opre.update_project_configwithrunnerCommand/runnerArgs/runnerPort(e.g.npm,["run", "dev", "--", "--port", "4173"]).Loop until the plan is satisfied:
opre.get_next_task→opre.prepare_build_context→ implement inapp/→opre.record_implementation_result→opre.run_validation.opre.get_validation_reportandvalidation/known-gaps.mdfeed the next iteration.
/opreapp <package> — rebuild an application as a web app
Same loop, different first steps:
opre.create_projectwithtargetType: "app"and an explicit authorisation statement.opre.inspect_app_package— authorised static analysis of a local.apk/.ipa/.zip(archive structure, declared permissions/components, resource names, DEX identifier and endpoint literals).opre.add_findingfor anything you learn from public documentation.Plan, build and validate exactly as in
/opreweb.
The output is always a browser-based application, not an Android package. OPRE recovers declared strings only — it never claims to have decompiled logic, and it records what it could not observe.
Tool reference
Every tool has a short title and a description that says when to use it and what it returns.
The same copy lives in src/tools/catalog.ts — the single owner of the
agent-facing surface.
Tool | Title | Use it to |
| Start a project | Create the isolated workspace for a target. |
| What to do next | Get the stage-aware playbook with example arguments. Start here. |
| List projects | Discover project names/ids. |
| Project status | See stage, counts, progress, next action. |
| Project settings | Configure the dev server, app dir, allowed hosts, attempt limits. |
| Research the target | Observe the real site in a browser and store evidence. |
| Research summary | Read a bounded overview and the explicit unknowns. |
| Search research | Ranked search over pages and findings. |
| Record a finding | Store an observed/derived/hypothesis conclusion with limitations. |
| Search the knowledge base | Bounded, paginated search across everything known. |
| Get a feature | Read one feature with criteria, evidence and tasks. |
| Create or update a feature | Write a feature record. |
| Get evidence | Check the observations behind a claim. |
| Read a document | Excerpt one project document, paginated. |
| Record a note | Append a requirement, decision, uncertainty or workflow. |
| Plan the build | Turn research into features and ordered tasks. |
| List tasks | Review the backlog and what is blocked. |
| Next task | Take the highest-priority actionable task. |
| Create or update a task | Write one task and its browser checks. |
| Update task status | Move a task through its lifecycle. |
| Prepare build context | Get everything one task needs, within budget. |
| Record the result | Store what was built, what passed, what is missing. |
| Run validation | Start the app, run acceptance checks, and score it against the reference. |
| Validation report | See run history, failures per task, open gaps. |
| Inspect an app package | Authorised static analysis of an |
Unsupported capabilities are never faked: tools return a structured unsupported_capability
error with an actionable hint (for example, no web-search provider configured, or no Chromium
available).
Project layout
<OPRE_HOME>/<project>/
opre.json manifest: target, authorisation, runner config, allowed hosts
README.md generated index: stage, progress, next task, where things live
research/
report.md generated report (routes, findings index, errors, blocked requests)
architecture.md generated inferences + what cannot be known
sources.json every source with trust level and timestamp
findings.json findings with embedded evidence and limitations
pages.json per-page inventory: links, forms, interactive elements, assets
knowledge/
features.json features, acceptance criteria, status
requirements.md appended requirements
decisions.md appended decisions
uncertainties.md appended open questions / blocked tasks
workflows/<id>.md user-flow notes
planning/
plan.md generated plan (tasks in dependency order)
tasks.json plan metadata + task records
validation/
runs.json structured validation runs
known-gaps.md failures appended by validation and build results
artifacts/
screenshots/ research and validation screenshots
reports/ build results, optional research HAR
app/ the rebuilt application (written by the agent)The directory name is the readable project slug (example-com); a second project for the
same target becomes example-com-2. The unique id lives in opre.json.
Regenerated markdown (README.md, research/report.md, research/architecture.md,
planning/plan.md) is written between <!-- opre:generated:begin --> and
<!-- opre:generated:end --> markers. Anything you write outside those markers is preserved.
Fidelity: proof, not vibes
This is the part that makes OPRE more than a research dump. During research each page gets a fingerprint: heading tree, landmarks, text blocks, link paths, form signatures, interactive controls, image alts, and design tokens (colours, font families, sizes, radii) — plus a screenshot. When you validate the rebuild, OPRE captures the same fingerprint from the running app and diffs them.
Section | Weight | What a mismatch means |
headings | 30% | wrong information architecture |
text | 25% | missing or invented copy |
links | 15% | broken or extra navigation |
forms | 10% | wrong fields, types or required flags |
interactive | 10% | missing controls |
design tokens | 5% | different look and feel |
visual | 5% | pixel delta of the screenshots |
Scoring is F1 per section, so missing content and invented content are both defects. The
result is a verdict (match ≥ 0.95, close ≥ 0.8, partial ≥ 0.5, otherwise divergent), a
per-section breakdown, and a named list of differences. The visual section is a sampled pixel diff
implemented in-tree (no extra dependency) and is always reported together with its tolerance,
because "90% of sampled pixels differ at tolerance 24/255" is a fact, not a vibe.
Fidelity gaps are written to validation/known-gaps.md exactly like failed checks, so the next
build iteration starts from the difference list. When there is no reference (a project that never
researched a target), the outcome is reported as unavailable — never as a zero.
Is it actually better than just using an agent?
That is a fair question, and it deserves a measurement rather than a claim.
npm run compare-modes runs the same deterministic builder three ways against the same target and
scores all three with the same fidelity engine:
mode | what the builder gets | builder input | fidelity | verified by | resumable |
A agent only | a URL, then raw HTML | 1 kB | 22% divergent | nothing | no |
B agent + tools | raw HTML of each route | 1 kB | 22% divergent | nothing | no |
C agent + OPRE | OPRE's research records over MCP | 5 kB | 62% partial | browser + fidelity | yes |
(reproduce with npm run compare-modes; the numbers move with the target, and OPRE's own validation
run independently reported 61% on the same build.)
Read honestly:
OPRE's advantage is not less context — it is better-shaped context. Mode C read more bytes and scored ~3× higher, because the bytes were structured: form field names and required flags, interactive controls, image alts, design tokens, provenance. Raw HTML only yields text and hrefs.
Without OPRE nothing checks the result. A and B have no way to know whether what they built matches; they rely entirely on the agent's own confidence. Mode C got a browser check and a per-route difference list written into
known-gaps.md.Without OPRE the work cannot be resumed. Tasks, findings and decisions live in the project directory, so a new session continues; a conversation-only agent re-derives everything.
This is a lower bound, not a ceiling. The builder here is deterministic on purpose, so it isolates the information advantage. A real LLM agent adds judgement to every row and would beat all three — but it would still be guessing without the evidence, the persisted state, and the number.
Where the gap is small: one trivial page. Where it is large: many routes, long sessions, and any requirement to prove what was built. OPRE also cannot help with authenticated areas or with the coding judgement itself.
Configuration (environment variables)
All configuration is environment-based, validated at startup, and printed by
node dist/index.js --print-config.
Variable | Default | Purpose |
|
| Directory that contains all projects. Must be absolute. |
|
| Hard ceiling for one tool response, in characters. |
|
| Default page size for retrieval tools. |
|
| Page cap per research run. |
|
| Link depth per research run. |
|
| Pages inspected at once. Raise for speed, lower for politeness. |
|
| Per-navigation timeout. |
|
| Links captured per page. |
|
| Viewport list for responsive capture. |
|
| Capture a screenshot per visited page. |
|
| Record a HAR file into |
| OPRE bot UA | User agent used by the research/validation browser. |
|
|
|
| – | Base URL of a SearXNG instance with JSON output enabled. |
|
| Results kept per search query. |
|
| Search timeout. |
| – | Path to an existing Chromium/Chrome binary. |
|
| Run the browser headless. |
|
| Allow targets that resolve to private/loopback addresses. |
|
| Size ceiling for package inspection inputs. |
|
| Master switch for starting the generated app. |
|
| Port used when the project does not set one. |
|
| How long to wait for the dev server. |
|
| Per-check browser timeout. |
|
| Retries per task before the loop stops. |
|
|
|
See .env.example for a copy-paste starting point.
Browser troubleshooting
If npx playwright install chromium cannot download (restricted network), OPRE falls back in this
order: OPRE_BROWSER_EXECUTABLE → the full headless Chromium build → the default Playwright
Chromium. If none can launch, browser tools return an unsupported_capability error explaining
what to install — non-browser features keep working.
Context safety
OPRE is designed around the assumption that the agent's context is expensive and finite.
Retrieval tools return ranked, bounded, paginated results with ids — never the whole corpus.
Document tools return paths, sizes and excerpts, not full file contents.
Every response is measured against
OPRE_MAX_RESPONSE_CHARS; when a payload is too large, items are dropped deterministically and the response says how many.opre.prepare_build_contextassembles only what one task needs and reports which sections were trimmed, so the agent can request them explicitly.State (tasks, decisions, progress) lives on disk, so it never has to be re-fed every session.
OPRE makes no claim about the host agent's context window, history or compaction. Its limits are character/byte ceilings it actually enforces, described as such.
Security model
Research targets, pages, READMEs and packages are treated as untrusted data.
Risk | Mitigation |
Prompt injection in page content | Content is stored as evidence with |
Path traversal / writes outside the project | Every project-relative path goes through |
Unsafe URL schemes & SSRF | Only |
Local file / secret exposure | Credential-shaped strings are redacted before storage or output; child processes get a scrubbed environment. |
Arbitrary command execution | No shell, ever. Denylisted executables, no metacharacters, fixed working directory inside the project, and |
Untrusted build scripts | OPRE never runs |
Cross-project contamination | Every operation is scoped to one project directory; ids are resolved only under |
Data loss | Generated sections are marker-delimited; append-only notes; atomic writes (temp + rename). |
OPRE will not bypass authentication, paywalls, access controls or anti-bot protections, and it has no stealth, credential-theft or security-bypass features. Only analyse software you own or are authorised to inspect. See SECURITY.md for reporting issues.
Development
npm install
npm run typecheck # tsc --noEmit, strict
npm run lint # eslint (type-checked rules)
npm run format # prettier
npm test # unit + integration (85 tests, includes real-browser runs)
npm run test:e2e # builds dist/, drives the built server AND the source server over stdio
npm run demo # one-command walkthrough against a real site
npm run bench # measured performance table
npm run verify # everything the CI runs, minus the buildPerformance
npm run bench measures what a user actually feels. Current numbers on a modest laptop
(4-page research, 200 synthetic findings):
Operation | Before | After |
cold start → first tool list | 604 ms | ~290 ms |
research, 4 pages, concurrency 3 | 3.84 s | 2.65 s |
| 6 ms | 6 ms |
MCP tool call round-trip | 1 ms | 1 ms |
What made the difference: Playwright is imported lazily (most tool calls never need a browser), and pages are inspected concurrently while results stay in deterministic frontier order.
Layout of the source:
src/
config.ts environment parsing/validation
server.ts MCP server assembly (transport-agnostic)
index.ts stdio entry point + CLI flags
core/ errors, ids, atomic JSON store, markdown sections, budget helpers
security/ path containment, URL/SSRF policy, untrusted-content handling
project/ manifest, layout, create/resolve/list
research/ crawler, search adapter, reports, app inspection (zip/axml/dex)
knowledge/ features, documents, bounded search
planning/ plan drafting/applying, task persistence, next-task selection
build/ task-scoped build context, implementation results
validation/ dev-server runner, browser checks, runs and feedback loop
tools/ MCP tool registrations grouped by domain
catalog.ts the agent-facing surface: every tool title + description
guide-tools.ts opre.get_guide — stage-aware next steps
scripts/ demo.mjs (walkthrough), bench.mjs (performance), smoke.mjsMilestone status and design decisions are tracked in docs/DEVELOPMENT_LOG.md.
Contributing, security, licence
CONTRIBUTING.md — setup, ground rules, how to add a tool.
SECURITY.md — threat model, controls, private reporting.
agents/README.md— the two workflows as agent instructions, for clients without slash-command support.MIT licensed. Respect the licences of dependencies and of anything you analyse.
What works today
Verified by the test suite (unit + integration + stdio end-to-end):
An MCP client can connect over stdio and call all 24 tools; two prompts are exposed.
Projects are created, isolated, listed and resumed across server restarts.
Website research runs a real Chromium against an authorised target and persists pages, screenshots, sources, findings and evidence; blocked requests and injection signals are recorded.
Planning drafts a dependency-ordered plan from research; the next task is selected by priority and dependency readiness.
Build context is task-scoped and budget-bounded; implementation results update task status, feature status and known gaps.
The runner starts a real dev server (no shell, scrubbed env) and Playwright checks run against it; failures, screenshots, console errors and failed requests are stored and re-readable.
Application packages are inspected statically with clear statements of what that cannot reveal.
Security controls (path traversal, SSRF, shell metacharacters, denied executables, symlink escapes, secret redaction) are covered by tests.
Known limitations
Stated plainly, and also returned by the tools themselves:
No AI model. OPRE orchestrates; the connected agent does the reasoning and coding.
No web search by default. Configure a SearXNG instance; otherwise OPRE says so instead of inventing results.
Authenticated areas are not visited. OPRE does not bypass logins, paywalls or bot protection.
Crawl coverage is bounded by page/depth/time limits; deeper areas stay unobserved.
Application inspection reads declared strings only — no decompilation to source, no runtime behaviour, no server-side logic.
Visual equivalence is not proof of functional equivalence. Validation checks are declarative assertions you define; OPRE does not claim completeness from a passing subset.
Transport is stdio only in v1. The server is transport-agnostic, but no HTTP transport is shipped.
Not yet implemented: multi-agent coordination, authenticated research sessions, diffing against a live target over time, and automatic dependency-manager support for generated apps.
License
MIT — see LICENSE. Respect the licenses of third-party dependencies and of any project you analyse; do not copy proprietary source into generated projects without authorisation.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
Turn any public website into an MCP server for agents to search, read and navigate.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
- RampifyOAuthdev.rampify
SEO MCP server: crawl your site, find AI-visibility gaps, and ship the fix from your coding agent.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceAn open-source MCP server that provides browser automation capabilities to external AI systems, enabling navigation, DOM interaction, and web content extraction.19Apache 2.0- AlicenseNot gradedqualityCmaintenanceAn MCP server that gives AI agents real browser capabilities including screenshotting, action execution, data extraction, and multi-persona auditing for frontend validation.52 npm6MIT
- AlicenseCqualityDmaintenanceA production-grade MCP server providing an autonomous AI agent swarm, persistent semantic memory, browser automation, multi-model reasoning, and 78+ tools for AI-first testing and development.63MIT
- AlicenseNot gradedqualityDmaintenanceA free, open-source MCP server that gives AI agents real filesystem, terminal, git, and process control over your machine for inspection, diagnosis, and repair.MIT