The missing runtime context for AI coding agents.
AI can read your code, but can't see what's happening at runtime. DevInspector provides the missing context: source code location, DOM state, styles, network, console, terminal output, and screenshots.
Two modes: Use with your IDE's AI (Cursor, VSCode) via MCP, or run AI agents directly in the browser via ACP (Claude Code, Codex CLI, Gemini CLI, OpenCode, more).
Watch the demo: https://www.youtube.com/shorts/TCt2oOtPS_k
Twittter/X Post: https://x.com/yaoandyan/status/1995082020431753600
Click any element to inspect it, or drag to select a region. AI gets the full context: source code location, computed styles, component hierarchy, IDs, classes, text content, and automatically captures screenshots for pixel-perfect visual understanding.
get_page_info provides AI with a semantic understanding of the page: URL, viewport, and an accessibility tree showing landmarks, headings, forms, and links. AI can navigate the page structure without screenshots.
AI can access Network and Console logs from any browser (via client-side interception) or full Chrome DevTools (via chrome devtools mcp). It sees what you see, regardless of your environment.
Switch between agents (Claude Code, Codex, Gemini, Opencode...) and track their debugging progress visually with a floating status bar.
# npm - basic installation
npm i -D @mcpc-tech/unplugin-dev-inspector-mcp
# pnpm - basic installation
pnpm add -D @mcpc-tech/unplugin-dev-inspector-mcp
# yarn - basic installation
yarn add -D @mcpc-tech/unplugin-dev-inspector-mcp
Note: If you don't need the ACP agents (Inspector Bar mode), add
--no-optionalto skip installing agent packages:npm i -D @mcpc-tech/unplugin-dev-inspector-mcp --no-optional pnpm add -D @mcpc-tech/unplugin-dev-inspector-mcp --no-optional yarn add -D @mcpc-tech/unplugin-dev-inspector-mcp --no-optional
Run the setup command to automatically configure your vite.config.ts, webpack.config.js, or next.config.js:
npx @mcpc-tech/unplugin-dev-inspector-mcp setup
Options:
--dry-run - Preview changes without applying them--config <path> - Specify config file path (auto-detect by default)--bundler <type> - Specify bundler type: vite, webpack, nextjs--no-backup - Skip creating backup files--help - Show help messageExamples:
# Preview changes before applying
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --dry-run
# Setup specific config file
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --config vite.config.ts
# Setup for specific bundler
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --bundler vite
This will:
If you prefer to configure it manually:
// vite.config.ts
+import DevInspector from '@mcpc-tech/unplugin-dev-inspector-mcp';
import react from '@vitejs/plugin-react'; // or vue(), svelte(), solid(), preact()
export default {
plugins: [
+ DevInspector.vite({
+ enabled: true,
showInspectorBar: true, // Default: true. Set to false to hide the UI.
+ autoOpenBrowser: false, // Default: false. Automatically open browser when server starts.
+ // Disable Chrome DevTools integration (useful in CI/headless/cloud environments)
+ // disableChrome: true,
}),
react(), // or vue(), svelte(), solid(), preact()
],
};
š“ Disable Chrome DevTools integration: set
disableChrome: truein plugin options or exportDEV_INSPECTOR_DISABLE_CHROME=1.
ā ļø Plugin order matters: Place
DevInspector.vite()beforereact(),vue(),svelte(),solid(), orpreact(). Otherwise source locations may showunknown:0:0.
If your project doesn't use HTML files (e.g., miniapp platforms that only bundle JS):
// vite.config.ts
```typescript
// vite.config.ts
DevInspector.vite({
enabled: true,
autoInject: false, // Disable HTML injection
entry: 'src/main.ts' // Inject inspector into entry file
})
virtual:dev-inspector-mcp)If you use TypeScript and import virtual:dev-inspector-mcp, make sure your TS config includes the plugin client types:
// tsconfig.json / tsconfig.app.json
{
"compilerOptions": {
"types": [
"vite/client",
"@mcpc-tech/unplugin-dev-inspector-mcp/client"
]
}
}
ā
Zero Production Impact: In production builds, virtual:dev-inspector-mcp becomes a no-op module. The inspector runtime is guarded by if (import.meta.env.DEV), which bundlers statically replace with false during production builds.
If virtual:dev-inspector-mcp conflicts with your project, you can customize it:
// vite.config.ts
DevInspector.vite({
enabled: true,
autoInject: false,
virtualModuleName: 'virtual:my-custom-inspector' // ā Custom name
})
// main.ts
import 'virtual:my-custom-inspector'; // ā Use your custom name
// webpack.config.js
+const DevInspector = require('@mcpc-tech/unplugin-dev-inspector-mcp');
module.exports = {
plugins: [
+ DevInspector.webpack({
+ enabled: true,
+ }),
],
};
Next.js supports both Webpack and Turbopack modes:
// next.config.ts
+import DevInspector, { turbopackDevInspector } from '@mcpc-tech/unplugin-dev-inspector-mcp';
const nextConfig: NextConfig = {
+ // Webpack configuration (default mode: `next dev`)
+ webpack: (config) => {
+ config.plugins.push(
+ DevInspector.webpack({
+ enabled: true,
+ })
+ );
+ return config;
+ },
+
+ // Turbopack configuration (`next dev --turbopack`)
+ turbopack: {
+ rules: turbopackDevInspector({
+ enabled: true,
+ }),
+ },
};
export default nextConfig;
Then add to your root layout:
// app/layout.tsx
import { DevInspector } from "@mcpc-tech/unplugin-dev-inspector-mcp/next";
export default function RootLayout({ children }) {
return (
<html>
<body>
<DevInspector />
{children}
</body>
</html>
);
}
Running modes:
next dev (uses webpack configuration)next dev --turbopack (uses turbopack configuration, Next.js 16+ default)// vite.config.ts
import { reactRouter } from "@react-router/dev/vite";
import DevInspector from '@mcpc-tech/unplugin-dev-inspector-mcp';
export default defineConfig({
plugins: [
DevInspector.vite({
enabled: true,
entry: "app/root.tsx" // Inject inspector into root layout
}),
reactRouter(),
],
});
.jsx and .tsx files (Vite, Webpack, Next.js).vue single-file components (Vite, Webpack).svelte components (Vite, Webpack).jsx and .tsx files (Vite, Webpack).jsx and .tsx files (Vite, Webpack)The plugin automatically updates MCP configuration files for detected editors when the dev server starts. This saves you from manually configuring MCP endpoints.
Supported editors: Cursor, VSCode, Windsurf, Claude Code, Antigravity
// vite.config.ts
DevInspector.vite({
// Auto-detect and update (default: true)
updateConfig: true,
// Or specify editors manually
updateConfig: ['cursor', 'vscode'],
// Or disable
updateConfig: false,
// Server name in MCP config (default: 'dev-inspector')
updateConfigServerName: 'my-app-inspector',
})
Custom editors: For non-standard editors, use customEditors:
DevInspector.vite({
customEditors: [
{
id: 'my-editor',
name: 'My Editor',
configPath: '~/.my-editor', // absolute, ~/relative, or project-relative
configFileName: 'mcp.json',
serverUrlKey: 'url', // default: 'url'
configFormat: 'mcpServers', // 'mcpServers' or 'servers' (vscode-style)
},
],
})
DevInspector supports multiple AI agents via ACP.
For npm-based agents (Claude Code, Codex CLI, Cursor Agent, Droid), you can pre-install them as dev dependencies for faster loading.
For system-level agents, install globally:
npm install -g @google/gemini-cli
uv tool install --python 3.13 kimi-cli
pipx install goose-ai
curl -fsSL https://opencode.ai/install | bash
npm install -g @tencent-ai/codebuddy-code
Note: If you don't pre-install npm-based agents, they will be launched via
npxon first use (slower startup).
The recommended way is to install agents during initial setup (see Installation above).
Alternatively, install them later as dev dependencies:
# npm
npm i -D @zed-industries/claude-code-acp
# pnpm
pnpm add -D @zed-industries/claude-code-acp
# Or add directly to package.json
{
"devDependencies": {
"@zed-industries/claude-code-acp": "^0.12.4",
"@zed-industries/codex-acp": "^0.7.1",
"@blowmage/cursor-agent-acp": "^0.1.0",
"@yaonyan/droid-acp": "^0.0.8"
}
}
About optionalDependencies: Agent packages are installed by default. If you don't need them, use
--no-optionalwhen installing.
Why install as devDependencies?
require.resolve instead of npx)This plugin uses the Agent Client Protocol (ACP) to connect with AI agents.
ā±ļø Note: Initial connection may be slow as agents are launched via npx (downloads packages on first run).
Default agents: View configuration ā
You can customize available AI agents, filter visible agents, and set a default agent:
// vite.config.ts
export default {
plugins: [
DevInspector.vite({
enabled: true,
// Option 1: Only show specific agents (filters merged agents)
visibleAgents: ['Claude Code', 'Gemini CLI', 'Goose'],
// Option 2: Add custom agents (merges with defaults)
agents: [
{
name: "Claude Code", // Matches default - auto-fills icon and env
command: "npx",
args: ["-y", "@zed-industries/claude-code-acp"],
},
{
name: "My Custom Agent",
command: "my-agent-cli",
args: ["--mode", "acp"],
env: [{ key: "MY_API_KEY", required: true }],
meta: { icon: "https://example.com/icon.svg" }
}
],
// Option 3: Combine both - add custom agents and filter visibility
agents: [
{
name: "My Custom Agent",
command: "my-agent-cli",
args: ["--mode", "acp"],
env: [{ key: "MY_API_KEY", required: true }],
meta: { icon: "https://example.com/icon.svg" }
}
],
visibleAgents: ['Claude Code', 'My Custom Agent'], // Only show these
// Set default agent to show on startup
defaultAgent: "Claude Code"
}),
],
};
Key Features:
agents: Merges your custom agents with defaults. Agents with the same name as default agents automatically inherit missing properties (icons, env)visibleAgents: Filters which agents appear in the UI (applies after merging). Great for limiting options to only what your team usesdefaultAgent: Sets which agent is selected on startupYou can configure external MCP servers for agents to access additional tools.
DevInspector.vite({
mcpServers: [
// HTTP/SSE Server
{
name: 'remote-server',
type: 'sse', // or 'http'
url: 'https://api.example.com/sse',
headers: [{ name: 'Authorization', value: process.env.MCP_TOKEN ?? '' }]
},
// Local Stdio Server
{
name: 'local-server',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-memory'],
env: { MY_VAR: 'value' }
}
]
})
Click element ā Describe issue ā AI analyzes ā Get fix
Examples:
pointer-events, z-index, overlaysDevInspector offers two ways to interact with your AI, depending on your preference:
Best for: Code-heavy tasks, refactoring, and maintaining flow.
Best for: Quick fixes, visual tweaks, or if you don't use an AI editor.
capture_element_contextCapture single element context. Two modes:
selector param for programmatic captureReturns: source location, DOM hierarchy, computed styles, dimensions, user notes, screenshot.
capture_area_contextCapture multiple elements in an area. Two modes:
containerSelector or bounds paramReturns: array of element contexts (max 50).
get_page_infoGet page overview with accessibility tree. Returns URL, title, viewport, document size, and semantic structure (landmarks, headings, forms, links). Start here to understand the page.
list_inspectionsList all captured inspections with ID, element details, source location, notes, and status (pending/in-progress/completed/failed).
update_inspection_statusUpdate inspection status. Parameters: inspectionId (optional, auto-detects), status ('in-progress'|'completed'|'failed'|'deleted'), message (required for completed/failed).
execute_page_scriptExecute JavaScript in browser context. Access: window, document, DOM APIs, React/Vue instances, localStorage. Must return a value.
get_network_requestsGet network requests from browser. Returns list with reqid, method, URL, status. Use reqid param to get full request/response details (headers, body, timing).
get_console_messagesGet console messages from browser. Returns list with msgid, level (log/warn/error), message. Use msgid param to get full message details.
get_stdio_messagesGet dev server stdout/stderr. Returns list with stdioid, stream type, content. Use stdioid param to get full message.
chrome_devtoolsAgentic tool for Chrome DevTools access. Provides network inspection, console logs, performance metrics, element interaction, and more.
You can register your own custom tools to be used by the AI agent. These tools run directly in the browser context, giving the AI access to your application's state, logic, or any browser APIs.
registerInspectorToolUse this function to register a tool. It handles the MCP schema definition and implementation in one place.
// main.ts or any entry file
import { registerInspectorTool } from 'virtual:dev-inspector-mcp';
registerInspectorTool({
name: "get_user_state",
description: "Get current user session and preferences",
inputSchema: {
type: "object",
properties: {
includeToken: {
type: "boolean",
description: "Whether to include the auth token"
}
}
},
implementation: (args) => {
// This runs in the browser!
const user = window.useUserStore?.getState();
if (args.includeToken) {
return { user, token: localStorage.getItem('token') };
}
return { user };
}
});
These custom tools are automatically discovered and made available to the connected AI agent along with the built-in inspector tools.
capture_element_contextCapture single element context. Interactive (user clicks) or automated (selector param).
capture_area_contextCapture multiple elements in area. Interactive (user draws rectangle) or automated (containerSelector/bounds param).
list_inspectionsView all element inspections in the queue with their status.
launch_chrome_devtoolsLaunch Chrome DevTools and navigate to a specified URL for debugging and inspection.
Parameter: url (required) - The URL to navigate to (e.g., http://localhost:3000)
get_network_requestsList network requests or get details of a specific one. Always refreshes the list first.
get_console_messagesList console messages or get details of a specific one. Always refreshes the list first.
get_stdio_messagesList stdio (stdout/stderr) messages from the server process. Always refreshes the list first.
For a deep dive into how the MCP context, CMCP library, and Puppet binding mechanism work together, see the Architecture Documentation.
Key concepts: