Server data from the Official MCP Registry
Debug bridge inside your web app: an agent reads the DOM, console and network. Any browser.
Debug bridge inside your web app: an agent reads the DOM, console and network. Any browser.
Valid MCP server (2 strong, 3 medium validity signals). No known CVEs in dependencies. ⚠️ Package registry links to a different repository than scanned source. Imported from the Official MCP Registry. 1 finding(s) downgraded by scanner intelligence.
18 files analyzed · 1 issue found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Set these up before or after installing:
Environment variable: FEEDTHROUGH_PORT
Environment variable: FEEDTHROUGH_ALLOWED_HOST_SUFFIXES
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-feedthrough-feedthrough": {
"env": {
"FEEDTHROUGH_PORT": "your-feedthrough-port-here",
"FEEDTHROUGH_ALLOWED_HOST_SUFFIXES": "your-feedthrough-allowed-host-suffixes-here"
},
"args": [
"-y",
"@feedthrough/mcp"
],
"command": "npx"
}
}
}From the project's GitHub README.
Debug with AI — from inside your app.
Feedthrough injects a lightweight debug bridge into any running web page, then exposes everything — DOM state, console logs, network requests, and user interactions — as MCP tools. Any MCP-compatible AI agent can inspect and drive the page conversationally, in real time.
Browser (any)
└── @feedthrough/core ← injected into your page
├── console interceptor
├── fetch / XHR interceptor
└── DOM inspector
↕ WebSocket
@feedthrough/mcp ← MCP server, exposes tools over stdio
└── Tools: click, fill, inspect_element, query_dom,
get_console_logs, get_network_requests, …
↕ MCP protocol
Claude Code / Cursor / any MCP client
Many physics and chemistry experiments run inside a sealed vacuum chamber, with all the air pumped out so nothing contaminates the experiment. The catch: you still need to control instruments inside the chamber and read their measurements, and the smallest air leak ruins the run. A feedthrough is the part that solves this — a specially engineered connector that carries electrical signals through the chamber wall while keeping the vacuum perfectly intact. You can't reach inside, but the feedthrough lets you observe and control what's happening in there anyway.
The parallel is exact: Feedthrough extracts runtime debug data from inside a running web app without disturbing it, and sends control signals back in — clicks, keystrokes, DOM queries — without breaking the execution environment.
Every other browser MCP tool is an external observer — it controls the browser from outside via Puppeteer or CDP and only works in Chrome. Feedthrough is an embedded agent. It runs inside the page, so it sees:
| Package | Description |
|---|---|
@feedthrough/core | In-browser bridge — intercepts console, fetch, XHR; handles commands |
@feedthrough/mcp | MCP server — bridges any MCP client to the browser via WebSocket |
@feedthrough/cypress | Cypress adapter — auto-injects the bridge before each test page load |
@feedthrough/playwright | Playwright adapter — injects the bridge via page.addInitScript() |
@feedthrough/vite | Vite plugin for apps with a static index.html |
@feedthrough/webpack | Webpack plugin — adds bridge as a global entry point |
@feedthrough/nextjs | Next.js adapter — wraps next.config.ts with withFeedthrough() |
@feedthrough/nuxt | Nuxt 3 module |
@feedthrough/sveltekit | SvelteKit adapter — injects via the handle hook |
@feedthrough/remix | Remix adapter — injects via a Vite dev server middleware |
| Framework | Adapter | Notes |
|---|---|---|
| Vite + React / Vue / Solid / Preact | @feedthrough/vite | Static index.html — plugin uses transformIndexHtml |
| Next.js | @feedthrough/nextjs | Wraps the webpack config; dev only |
| Nuxt 3 | @feedthrough/nuxt | Registers as a Nuxt module; dev only |
| SvelteKit | @feedthrough/sveltekit | handle hook with transformPageChunk; dev only |
| Remix | @feedthrough/remix | Vite dev server middleware; dev only |
| Webpack apps | @feedthrough/webpack | Global entry point; guards against production mode |
| Cypress | @feedthrough/cypress | window:before:load hook |
| Playwright | @feedthrough/playwright | page.addInitScript() |
npx @feedthrough/mcp
The server listens for browser connections on ws://127.0.0.1:8765 and exposes MCP tools on
stdio. Override the port with FEEDTHROUGH_PORT=9000.
{
"mcpServers": {
"feedthrough": {
"command": "npx",
"args": ["@feedthrough/mcp"]
}
}
}
Vite + React / Vue / Solid / Preact:
// vite.config.ts
import { feedthrough } from "@feedthrough/vite";
export default defineConfig({ plugins: [feedthrough()] });
Next.js:
// next.config.ts
import { withFeedthrough } from "@feedthrough/nextjs";
export default withFeedthrough()({ /* your next config */ });
Nuxt 3:
// nuxt.config.ts
export default defineNuxtConfig({ modules: ["@feedthrough/nuxt"] });
SvelteKit:
// src/hooks.server.ts
import { feedthroughHandle } from "@feedthrough/sveltekit";
import { sequence } from "@sveltejs/kit/hooks";
export const handle = sequence(feedthroughHandle);
Remix:
// vite.config.ts
import { feedthrough } from "@feedthrough/remix";
export default defineConfig({ plugins: [remix(), feedthrough()] });
Webpack:
// webpack.config.mjs
import { FeedthroughPlugin } from "@feedthrough/webpack";
export default { plugins: [new FeedthroughPlugin()] };
Cypress:
// cypress/support/e2e.ts
import { setupFeedthrough } from "@feedthrough/cypress";
setupFeedthrough();
Playwright:
// import test from the adapter instead of @playwright/test
import { test, expect } from "@feedthrough/playwright";
Or manually (any bundler):
// main.ts
if (import.meta.env.DEV) {
import("@feedthrough/core").then(({ init }) => init());
}
Once the bridge connects you'll see [feedthrough] tab connected in the MCP server output.
For the simplest experience, keep a single tab open. Multiple tabs can connect at the same time
and commands are routed to the most recently active one, but a single tab avoids any ambiguity.
Then ask your AI agent:
> What's on the page right now?
> Click the submit button and tell me what network requests fired
> Why is the counter showing the wrong value?
| Tool | Description |
|---|---|
get_instructions() | Usage guide — recommended workflow, tool ordering, and selector tips |
query_dom(selector) | All elements matching a CSS selector |
inspect_element(selector, properties?) | Tag, attributes, full bounding rect + inViewport, curated computed styles, live form state; properties reads extra CSS props by name |
get_html(selector) | Raw outerHTML of a region (capped at 50 KB) |
get_console_logs(limit?, levels?, match?, since?) | Console output (all methods) plus uncaught errors & promise rejections; filter by levels, match, or since timestamp |
get_network_requests(filter?, since?) | Captured fetch + XHR — URL, method, status, duration, headers, request/response bodies (10 KB cap); narrow by filter or since |
get_page_info() | URL, title, readyState, viewport size, scroll position, user agent |
connection_status() | List connected tabs and which one is currently active |
click(selector) | Click an element |
fill(selector, value) | Type into an input field |
hover(selector) | Trigger mouseover/mouseenter |
press_key(selector, key) | Dispatch a key press — Enter, Escape, Tab, arrow keys, or a character |
set_style(selector, properties) | Preview a visual fix — set inline CSS live (not saved to source) |
set_attribute(selector, name, value) | Preview an attribute change — toggle disabled, swap a class, set aria-* (null removes) |
set_text(selector, text) | Preview wording/label changes — replace an element's text |
reset_overrides() | Undo every live set_style / set_attribute / set_text change |
Live edit is a preview, not a save. set_style / set_attribute / set_text mutate the
running DOM so the agent can show you a fix without a rebuild. They are not written to your
source and reset on reload/HMR. The loop: the agent previews live, you confirm, then it edits the
actual source to make it stick. Changes a framework owns (text, controlled attributes) may be
overwritten on the next render — the tool result flags this so the agent can tell you.
examples/react-app is a small React app with three deliberate bugs — a good sandbox for
trying out the diagnostic workflow:
# Terminal 1 — app
cd examples/react-app && pnpm dev # http://localhost:5173
# Terminal 2 — MCP server
cd packages/mcp && node dist/index.js
Connect an AI agent and ask it to find what's wrong. The three bugs are all invisible from the
UI but findable in under a minute via get_console_logs, get_network_requests, and query_dom.
connection_status() — confirm the bridge is connected before anything elseget_console_logs() — errors and app output often identify the root cause immediatelyget_network_requests() — look for failed fetches, wrong URLs, or missing callsquery_dom(selector) — find elements and check what's renderedinspect_element(selector) — deep-dive on a specific elementclick() / fill() — interact, then re-check logs and networkAdd this to whatever project-memory file your AI agent reads — CLAUDE.md for Claude Code,
.cursor/rules/*.md for Cursor, and so on — to prime it with the right workflow:
## Debugging with Feedthrough
A Feedthrough MCP server is configured. When investigating UI bugs:
1. Call `connection_status()` first — fail fast if no browser is connected.
2. Check `get_console_logs()` before touching the DOM.
3. Check `get_network_requests()` for failed or missing API calls.
4. Use `query_dom` to orient yourself, `inspect_element` to dig into a specific element.
5. Interact with `click` / `fill`, then re-check logs.
Prefer element IDs as selectors — they're stable. Avoid long attribute selectors.
For one-off sessions with any MCP client:
You have access to the Feedthrough MCP server. It gives you live access to a running web app
from inside the browser — console logs, network requests, DOM state, and the ability to click
and fill inputs. Start by calling get_instructions() for the recommended workflow.
v1 is local-only. Two guards enforce this:
127.0.0.1, so it is not reachable
from other machines on the network.Origin header.
Loopback origins (localhost, 127.0.0.1, ::1) are always accepted, as is any host ending
with an allowed suffix (default .test, so local dev domains like Laravel Valet's myapp.test
connect out of the box). Override the suffix list with FEEDTHROUGH_ALLOWED_HOST_SUFFIXES
(comma-separated; replaces the default — set it empty for loopback-only). Any other origin is
rejected. A .test origin can only be presented by a page actually served from a .test host,
which resolves locally, so this widens which local origins connect, not network reach.Captured network requests include request and response bodies and headers, including
Authorization, Cookie, and any other headers your app sends. That's intentional — debugging
auth and session flows needs them. But the data does leave the page over the local WebSocket,
flows through the MCP server, and reaches whichever AI agent you've connected. If that agent is
cloud-backed, sensitive values reach the provider. Run Feedthrough only on dev machines and dev
data. Do not inject @feedthrough/core into production builds.
pnpm install # install all workspace deps
pnpm build # build all packages
pnpm typecheck # typecheck all packages
Requires Node.js ≥ 22 and pnpm.
Packages are versioned independently — bump only the package(s) you actually changed and leave
the rest alone. Publishing to npm is handled by CI: the Publish to npm workflow runs on every
published GitHub Release and publishes only the packages whose name@version isn't on npm yet,
skipping the ones already published (via OIDC trusted publishing, no tokens).
To cut a release:
# 1. Bump the changed package(s) only
pnpm --filter @feedthrough/mcp exec npm version 0.1.1 --no-git-tag-version
# When bumping @feedthrough/mcp, also bump the version (and packages[].version) in
# packages/mcp/server.json to match — the MCP registry validates them against npm.
git add packages/mcp/package.json packages/mcp/server.json
git commit -m "Release @feedthrough/mcp 0.1.1"
git push
# 2. Create a GitHub Release (this triggers the publish workflow)
gh release create v0.1.1 --title "v0.1.1" --notes "..."
The workflow builds all packages and publishes only the newly bumped ones. When @feedthrough/mcp
itself is published, the workflow also publishes it to the official MCP registry
(io.github.feedthrough/feedthrough) via GitHub OIDC — no extra step. Mark the release as a
pre-release to skip publishing.
MIT — see LICENSE.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Modelcontextprotocol · Developer Tools
Web content fetching and conversion for efficient LLM usage
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.