High-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.
MCP bridge for browser UI and source code
Domscribe connects a running web app to source code so an agent can work from live browser state instead of guessing. It injects stable DOM IDs at build time, captures runtime props and state, and exposes that context through MCP tools, a relay server, and an overlay picker. It supports React, Vue, Next.js, Nuxt, Vite, Webpack, and Turbopack, with agent plugins for Claude Code, Copilot, Cursor, Gemini CLI, and Kiro. The repo includes the CLI, MCP server, framework adapters, and the browser overlay that turns clicks into source-linked annotations.
Builders who want their agent to inspect a live frontend, resolve a UI element back to source, and make changes with context.
You can point an agent at the exact element or source line and get live browser context instead of re-explaining the UI.
What it does
Bidirectional source and UI lookup
An agent can query a source file and line to see the live DOM, props, and state, or resolve a clicked element back to its source location.
Stable build-time DOM IDs
The transform injects deterministic `data-ds` IDs and records them in an append-only manifest so mapping survives HMR and fast refresh.
Framework adapters
React and Vue adapters extract runtime context, while Next.js and Nuxt packages provide framework-specific setup.
MCP tool surface
The server exposes tools for source queries, manifest lookup, annotation handling, status checks, and verification.
Overlay annotation workflow
The browser overlay lets you click an element, leave an instruction, and watch the agent respond in real time.
Agent plugin bundles
Marketplace and extension files package MCP config and skills for Claude Code, Cursor, Gemini CLI, Copilot, and Kiro.
Zero production impact
Instrumentation is stripped from production builds and sensitive data is redacted before leaving the browser.
How to get it
- 1Run
npx domscribe init
- 2If your frontend app is in a subdirectory (e.g. apps/web), pass --app-root during init
npx domscribe init --app-root apps/web
- 3Run
claude plugin marketplace add patchorbit/domscribe claude plugin install domscribe@domscribe
- 4Run
copilot plugin install patchorbit/domscribe
- 5Run
gemini extensions install https://github.com/patchorbit/domscribe
- 6Install the Domscribe skills
npx skills add patchorbit/domscribe
README
Domscribe
AI coding agents edit your source files blind — they can't see your running frontend, and your frontend can't tell them where to look.
Domscribe bridges both directions: click a DOM element to tell your agent what to change, or let your agent query any source location to see exactly what it looks like live in the browser. Build-time stable IDs, deep runtime context (props, state, DOM), framework-agnostic, any MCP-compatible agent. Zero production impact.
Getting Started
npx domscribe init
The setup wizard walks you through two steps:
- Connect your coding agent — select your agent (Claude Code, Copilot, Gemini, Kiro, or others) and the wizard installs the plugin automatically.
- Add to your app — select your framework and bundler, the wizard installs the right package and shows you the config snippet to add.
That's it. Start your dev server and you're ready to go.
Prefer to set things up manually, or need finer control? See the manual setup instructions below.
Features
Code → UI: Let the agent see the browser
Your agent calls domscribe.query.bySource with a file path and line number and gets back the live DOM snapshot, current props, component state, and rendered attributes — directly from the running browser. No human interaction needed.
[!TIP] Agents don't spontaneously query runtime state — prompt them explicitly: "Fix the button color — use domscribe to check what CSS classes it has before changing anything." Your dev server must be running with the target page open in the browser.
UI → Code: Point and tell
Click any element in the browser overlay, describe the change in plain English, and submit. Domscribe captures the element's source location, runtime context, and your instruction as an annotation. The agent claims it, navigates to the exact file and line, and implements the change. The overlay shows the agent's response in real time via WebSocket.
More
- 🎯 Build-time stable IDs — deterministic
data-dsattributes injected via AST, stable across HMR and fast refresh - 🧩 Framework-agnostic — React 18-19, Vue 3, Next.js 15-16, Nuxt 3+, with an extensible adapter interface
- 📦 Any bundler — Vite 5-7, Webpack 5, Turbopack
- 🔍 Deep runtime capture — live props, state, and DOM snapshots via React fiber walking and Vue VNode inspection
- 🛡️ Zero production impact — all instrumentation stripped in production builds, enforced in CI
- 🔒 PII redaction — emails, tokens, and sensitive patterns automatically scrubbed before leaving the browser
- 📁 Annotations live in your repo — stored as JSON files in
.domscribe/annotations/, exposed via REST APIs that MCP wraps for agent access - 📡 Real-time feedback — WebSocket relay pushes agent responses to the browser overlay as they happen
Manual Setup
[!NOTE]
npx domscribe inithandles both steps below automatically. Use manual setup only if you need finer control.
Domscribe has two sides: app-side (bundler + framework plugins) and agent-side (MCP for your coding agent). Both are needed for the full workflow.
App-Side — Add to Your Bundler
Next.js (15 + 16) — npm install -D @domscribe/next
// next.config.ts
import type { NextConfig } from 'next';
import { withDomscribe } from '@domscribe/next';
const nextConfig: NextConfig = {};
export default withDomscribe()(nextConfig);
Nuxt 3+ — npm install -D @domscribe/nuxt
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@domscribe/nuxt'],
});
React 18–19 — npm install -D @domscribe/react
Vite plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { domscribe } from '@domscribe/react/vite';
export default defineConfig({
plugins: [react(), domscribe()],
});
Webpack plugin:
// webpack.config.js
const { DomscribeWebpackPlugin } = require('@domscribe/react/webpack');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: '@domscribe/transform/webpack-loader',
options: { enabled: isDevelopment },
},
],
},
],
},
plugins: [
new DomscribeWebpackPlugin({
enabled: isDevelopment,
overlay: true,
}),
],
};
Vue 3+ — npm install -D @domscribe/vue
Vite plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { domscribe } from '@domscribe/vue/vite';
export default defineConfig({
plugins: [vue(), domscribe()],
});
Webpack plugin:
// webpack.config.js
const { DomscribeWebpackPlugin } = require('@domscribe/vue/webpack');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: '@domscribe/transform/webpack-loader',
options: { enabled: isDevelopment },
},
],
},
],
},
plugins: [
new DomscribeWebpackPlugin({
enabled: isDevelopment,
overlay: true,
}),
],
};
Any framework — npm install -D @domscribe/transform (DOM→source mapping only, no runtime capture)
Vite plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import { domscribe } from '@domscribe/transform/plugins/vite';
export default defineConfig({
plugins: [domscribe()],
});
Webpack plugin:
// webpack.config.js
const {
DomscribeWebpackPlugin,
} = require('@domscribe/transform/plugins/webpack');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: '@domscribe/transform/webpack-loader',
options: { enabled: isDevelopment },
},
],
},
],
},
plugins: [
new DomscribeWebpackPlugin({
enabled: isDevelopment,
overlay: true,
}),
],
};
Working examples: See
packages/domscribe-test-fixtures/fixtures/for complete app setups across every supported framework and bundler combination.
For plugin configuration options, see the @domscribe/transform README.
Monorepos
If your frontend app is in a subdirectory (e.g. apps/web), pass --app-root during init:
npx domscribe init --app-root apps/web
Or run npx domscribe init and follow the prompts — the wizard asks if you're in a monorepo.
This creates a domscribe.config.json at your repo root that tells all Domscribe tools where your app lives. CLI commands (serve, stop, status) and agent MCP connections automatically resolve the app root from this config — no extra flags needed.
Agent-Side — Connect Your Coding Agent
Domscribe exposes 12 tools and 4 prompts via MCP. Agent plugins bundle the MCP config and a skill file that teaches the agent how to use the tools effectively.
Claude Code
claude plugin marketplace add patchorbit/domscribe
claude plugin install domscribe@domscribe
GitHub Copilot
copilot plugin install patchorbit/domscribe
Gemini CLI
gemini extensions install https://github.com/patchorbit/domscribe
Amazon Kiro
Open the Powers panel → Add power from GitHub → enter https://github.com/patchorbit/domscribe/tree/main/domscribe-power.
Cursor
Any agent (Skills and MCP)
Install the Domscribe skills:
npx skills add patchorbit/domscribe
Then add this MCP config to your agent:
{
"mcpServers": {
"domscribe": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@domscribe/mcp"]
}
}
}
How It Works
1. Inject. The bundler plugin parses each source file, injects HMR-stable data-ds IDs via xxhash64, and records each mapping in .domscribe/manifest.jsonl.
2. Capture. Framework adapters (React fiber walking, Vue VNode inspection) extract live props, state, and component metadata. The overlay UI lets you click any element and see its full context.
3. Relay. A localhost Fastify daemon connects the browser and your agent via REST, WebSocket, and MCP stdio. A file lock prevents duplicate instances across dev server restarts.
4. Agent. Your coding agent connects via MCP to query by source (see what any line looks like live) or process annotations (claim, implement, and respond to UI change requests).
Comparison
| Feature | Domscribe | Stagewise | DevInspector MCP | React Grab | Frontman |
|---|---|---|---|---|---|
| Build-time stable IDs | ✅ data-ds via AST | ❌ Runtime (CDP) | ❌ No stable IDs | ❌ _debugSource | ❌ Runtime framework introspection |
| DOM→source manifest | ✅ JSONL, append-only | ❌ | ❌ | ❌ | ❌ |
| Code→live DOM query | ✅ Agent queries source, gets live runtime | ❌ | ❌ | ❌ | ❌ |
| Runtime props/state | ✅ Fiber + VNode walking | ⚠️ Shallow | ⚠️ DOM-level + JS eval | ❌ HTML + component names only | ⚠️ Props only (framework APIs) |
| Multi-framework | ✅ React · Vue · Next.js · Nuxt · extensible | ⚠️ React only | ✅ React + Vue + Svelte + Solid + Preact | ❌ React only | ⚠️ Next.js + Astro + Vite |
| Multi-bundler | ✅ Vite + Webpack + Turbopack | ❌ N/A (Electron browser) | ✅ Vite + Webpack + Turbopack | ❌ N/A | ❌ Dev server middleware |
| MCP tools | ✅ 12 tools + 4 prompts | ❌ Proprietary protocol (Karton) | ✅ 9 tools | ⚠️ Lightweight add-on | ❌ Internal MCP only |
| Agent-agnostic | ✅ Any MCP client | ❌ Bundled Electron agent | ✅ | ✅ | ❌ Bundled Elixir agent |
| In-app element picker | ✅ Lit shadow DOM | ✅ Built-in browser selector | ✅ Inspector bar | ✅ Hover-to-capture | ✅ Chat interface |
| Source mapping | ✅ Deterministic (AST IDs) | ⚠️ AI-inferred | ⚠️ AST-injected (not stable) | ⚠️ _debugSource (workaround needed) | ⚠️ Runtime framework introspection |
| License | ✅ MIT | ⚠️ AGPL | ✅ MIT | ✅ MIT | ⚠️ Apache + AGPL |
No single competitor combines build-time stable IDs, deep runtime capture, bidirectional source↔DOM querying, and an MCP tool surface in a framework-agnostic way.
MCP Tools
The agent-facing surface — tools, prompts, wire schemas, and error envelope — is listed below as a human-readable index.
| Tool | Description |
|---|---|
domscribe.query.bySource | Query a source file + line and get live runtime context (props, state, DOM snapshot) |
domscribe.manifest.query | Find manifest entries by file path, component name, or element ID |
domscribe.manifest.stats | Manifest coverage statistics (entry count, file count, component count, cache hit rate) |
domscribe.resolve | Resolve a data-ds element ID to its source location (file, line, col, component) |
domscribe.resolve.batch | Resolve multiple element IDs in one call |
domscribe.annotation.process | Atomically claim the next queued annotation (prevents concurrent agent conflicts) |
domscribe.annotation.respond | Attach agent response and transition to PROCESSED |
domscribe.annotation.updateStatus | Manually transition annotation status |
domscribe.annotation.get | Retrieve annotation by ID |
domscribe.annotation.list | List annotations with status/filter options |
domscribe.annotation.search | Full-text search across annotation content |
domscribe.verify.baseline | Capture a pre-edit style/geometry snapshot of a rendered element |
domscribe.verify.afterEdit | Compare the element against the baseline — deterministic verdict + per-property deltas |
domscribe.status | Relay daemon health, manifest stats, queue counts |
See the @domscribe/mcp README for detailed tool schemas, response formats, and prompt definitions.
Packages
| Package | Description |
|---|---|
@domscribe/core | Zod schemas, RFC 7807 error system, ID generation, PII redaction, constants |
@domscribe/manifest | Append-only JSONL manifest, IDStabilizer (xxhash64), BatchWriter, ManifestCompactor |
@domscribe/relay | Fastify HTTP/WS server, MCP stdio adapter, annotation lifecycle |
@domscribe/transform | Parser-agnostic AST injection (Acorn, Babel, VueSFC), bundler plugins |
@domscribe/runtime | Browser-side ElementTracker, ContextCapturer, BridgeDispatch |
@domscribe/overlay | Lit web components (shadow DOM), element picker, annotation UI |
@domscribe/react | React fiber walking, props/state extraction, Vite + Webpack plugins |
@domscribe/vue | Vue 3 VNode resolution, Composition + Options API support, Vite + Webpack plugins |
@domscribe/next | withDomscribe() config wrapper for Next.js 15 + 16 |
@domscribe/nuxt | Nuxt 3+ module with auto-relay and runtime plugin |
domscribe | CLI binary (domscribe serve, status, stop, init, mcp) |
@domscribe/mcp | Standalone MCP server binary (domscribe-mcp) |
@domscribe/test-fixtures | Black-box integration + e2e suite (not published) |
Contributing
pnpm install
nx run-many -t build test lint typecheck
Conventions are in .claude/rules/. PRs welcome.
License
Files in the repo
- .claude
- .claude-plugin
- .cursor-plugin
- .github
- .plugin
- .verdaccio
- .vscode
- docs
- domscribe-power
- packages
- scripts
- skills
- .gitignore
- .mcp.json
- .nxignore
- .prettierignore
- .prettierrc
- CLAUDE.md
- eslint.config.mjs
- gemini-extension.json
- LICENSE
- nx.json
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
- README.md
- TECHNICAL_SPEC.md
- tsconfig.base.json
- tsconfig.json
- vitest.workspace.ts
Discussion (0)
Ask about usage, or say what you built with itSign in to join the discussion.
No comments yet. Be the first to say what this is good for.
More connectors

Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code
Git-native persistent memory for AI coding agents. Implements Google OKF v0.2 with sub-300µs in-memory BM25 search, embedded MCP server, and progressive disclosure. Slashes token bloat by 80% with zero external databases or dependencies. Built in pure Go.
Local-first code intelligence graph for MCP and CLI. Builds a persistent map of your codebase so AI coding tools read only what matters, with benchmarked context reductions on reviews and large-repo workflows.
Stop your AI from making things up — it proposes, deterministic tools decide, every claim checked against ground truth with evidence. Grounded facts and context survive resets. Reverse engineering is the proving ground. MCP server + CLI.
20 MB lightweight cross-platform database client for 90+ databases, including MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, SQL Server, and Dameng. Built-in AI, MCP Server, CLI, desktop and Docker. | 轻量级跨平台数据库管理工具,支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、达梦等 90+ 数据库,提供桌面端、Docker、CLI、内置 AI 助手和 MCP Server。
