Give your AI coding agent eyes into your running app.
AgentEyes streams console logs, network requests, DOM snapshots, errors, performance metrics, React component renders, and screenshots from your browser — directly to your coding agent over MCP.
Dev-only by default. In production, AgentEyes is completely inert — no monkey-patching, no WebSocket connections, zero overhead.
┌──────────────┐ WebSocket ┌──────────────┐ stdio/MCP ┌──────────────┐
│ Your App │ ──────────────> │ AgentEyes │ <────────────> │ Any Agent │
│ (browser) │ events stream │ MCP Server │ tools/queries │ (Kiro, │
│ │ │ :9960 │ │ Cursor...) │
└──────────────┘ └──────────────┘ └──────────────┘
React (Provider component)
import { AgentEyesProvider } from '@everkers/agent-eyes';
function App() {
return (
<AgentEyesProvider config={{ mcpBridge: true }}>
<YourApp />
</AgentEyesProvider>
);
}Vite (Plugin — zero app code)
// vite.config.ts
import { agentEyesPlugin } from '@everkers/agent-eyes/vite';
export default defineConfig({ plugins: [agentEyesPlugin()] });Next.js (Client component wrapper)
// app/agent-eyes-provider.tsx
"use client";
import { AgentEyesProvider } from "@everkers/agent-eyes";
export default function AgentEyesWrapper({ children }: { children: React.ReactNode }) {
return (
<AgentEyesProvider config={{ mcpBridge: true }}>
{children}
</AgentEyesProvider>
);
}
// app/layout.tsx
import AgentEyesWrapper from "./agent-eyes-provider";
export default function RootLayout({ children }) {
return (
<html><body><AgentEyesWrapper>{children}</AgentEyesWrapper></body></html>
);
}Vanilla (no framework)
import { AgentEyes } from '@everkers/agent-eyes';
const eyes = new AgentEyes({ mcpBridge: true });
eyes.start();Add to your MCP config (.kiro/settings/mcp.json, .cursor/mcp.json, claude_desktop_config.json):
{
"mcpServers": {
"agent-eyes": {
"command": "npx",
"args": ["@everkers/agent-eyes"]
}
}
}That's it. Your agent can now see your app.
See the examples/ directory for complete working apps:
| Example | Setup | Description |
|---|---|---|
examples/react |
AgentEyesProvider |
React app using the provider component |
examples/vite |
agentEyesPlugin() |
Vite app with zero-config plugin auto-injection |
examples/nextjs |
"use client" wrapper |
Next.js App Router with client component provider |
To run any example:
cd examples/react # or vite, nextjs
npm install
npm run dev| Tool | Description |
|---|---|
get_console_logs |
Console log/warn/error/debug/info with args and stack traces. Filter by level. |
get_network_requests |
Fetch & XHR with headers, bodies, status, timing. Filter by method, status, URL. |
get_errors |
Runtime errors and unhandled promise rejections with stack traces. |
get_dom_snapshot |
Simplified DOM snapshot with semantic attributes (id, class, role, aria-label, data-testid). |
get_performance_metrics |
Core Web Vitals (FCP, LCP), load timing, memory usage. |
get_react_components |
Component names, props, and render counts. Filter by name. |
get_snapshot |
Full state dump — everything at once. |
get_failed_requests |
All failed network requests (status >= 400 or errors). |
take_screenshot |
Visual screenshot of the running app. Supports CSS selector targeting. |
get_status |
Connection status — connected browsers, event counts by type. |
clear_events |
Clear the event buffer. |
agent-eyes auto-detects the environment and is completely inert in production:
- Checks
import.meta.env.DEV(Vite),process.env.NODE_ENV(CRA/Next.js), and localhost hostname - No console/fetch/XHR monkey-patching in production
- No WebSocket connections
- All methods return empty data — zero runtime overhead
const eyes = new AgentEyes({
maxBufferSize: 500, // max events in memory (default: 500)
enabled: true, // force enable/disable (auto-detects by default)
mcpBridge: true, // connect to MCP server at ws://localhost:9960
redactPatterns: ['authorization', 'cookie', 'token', 'password'],
filter: (event) => true, // drop events before they enter the buffer
onEvent: (event) => {}, // callback for every captured event
collectors: {
console: true,
network: true,
errors: true,
dom: true,
performance: true,
reactComponents: false, // opt-in (needs React DevTools hook)
},
});const eyes = new AgentEyes({
mcpBridge: true,
// Console
console: {
levels: ['warn', 'error'], // only capture these levels
maxArgLength: 5000, // truncate serialized args
stackTraceAll: false, // stack traces for all levels, not just errors
},
// Network
network: {
methods: ['GET', 'POST'], // only capture these HTTP methods
captureRequestHeaders: true,
captureResponseHeaders: true,
captureRequestBody: true,
captureResponseBody: true,
maxBodySize: 10000, // truncate large bodies
ignorePatterns: ['/analytics', /hot-update/],
},
// DOM
dom: {
maxDepth: 8, // how deep to traverse the tree
debounceMs: 1000, // debounce mutation-triggered snapshots
disableAutoSnapshot: false, // disable auto-snapshots on mutations
extraAttributes: ['data-cy', 'data-automation-id'],
},
// Performance
performance: {
disableLCP: false,
disableMemory: false,
},
// React Components (opt-in)
reactComponents: {
includeNames: [/^App/, 'Header'], // only track matching components
excludeNames: [/^Styled/], // skip these
captureProps: true,
maxPropsDepth: 2,
},
});agentEyesPlugin({
devOnly: true, // only inject in dev mode (default: true)
inject: true, // auto-inject script tag (default: true)
mcpBridge: true, // connect to MCP bridge (default: true)
redactPatterns: ['authorization', 'cookie'],
})| Variable | Default | Description |
|---|---|---|
AGENT_EYES_PORT |
9960 |
WebSocket port for the MCP server |
Set it in your MCP config:
{
"mcpServers": {
"agent-eyes": {
"command": "npx",
"args": ["@everkers/agent-eyes"],
"env": {
"AGENT_EYES_PORT": "8888"
}
}
}
}Then point the client to the same port:
const eyes = new AgentEyes({ mcpBridge: 'ws://localhost:8888' });- Sensitive headers and body fields are redacted when
redactPatternsis set - Patterns match against header names and JSON keys (case-insensitive)
- The WebSocket server only binds to localhost — not accessible from the network
- No data leaves your machine. Everything stays between browser ↔ MCP server ↔ agent
- In production, nothing runs at all
import { useAgentEyes, useAgentEvents, useAgentSnapshot } from '@everkers/agent-eyes';
function DevPanel() {
const eyes = useAgentEyes(); // the AgentEyes instance
const errors = useAgentEvents('error'); // live-updating error list
const snapshot = useAgentSnapshot(); // full state snapshot
return <pre>{JSON.stringify(snapshot, null, 2)}</pre>;
}AgentEyesmonkey-patchesconsole.*,fetch, andXMLHttpRequestto capture events- A
MutationObserverwatches the DOM for structural changes PerformanceObservertracks Core Web Vitals and memory- Events stream over WebSocket to the MCP server process
- The MCP server exposes tools over stdio that any agent can call
- Screenshots use
html2canvas— the MCP server sends a request to the browser, which renders and returns the image
MIT
