MCP Server
Connect any MCP-compatible AI coding agent (Claude Code, Cursor, Windsurf, Cline, Continue) to Responsive Tester through a local bridge. The agent launches pages, tests every breakpoint at once, edits CSS, and verifies with screenshots.
What It Does
Once the bridge is connected, the agent can drive the multi-viewport shell:
- Launch any URL in a new tab and activate the shell on it, with no clicks from you.
- Read computed styles for the same element in every live viewport in a single call, a matrix no single-page tool can produce.
- Audit any element's effective responsive behavior: width segments listing only the properties that actually change, cascade-aware and with variables resolved.
- Inspect the full cascade and edit real CSS rules live, so one change follows the media queries into every viewport.
- Manage viewports: add, remove, rotate, force light or dark per frame, or switch to site breakpoints mode.
- Capture per-viewport screenshots the agent can reason about visually.
Every edit flows through the editor's Changes panel, same as a manual edit. Diffs, undo, and Copy CSS all work the same way.
Requirements
- Responsive Tester with a Pro license (or an active trial).
- An MCP-compatible AI client (Claude Code, Cursor, Windsurf, Cline, Continue, or any client that speaks MCP over stdio).
- Node.js 18 or newer installed on the machine.
Setup
1. Install the Bridge
The bridge is published on npm as @responsive-tester/mcp. Setup happens in the AI client's configuration, not in the extension.
Claude Code: run this once in any terminal, then restart Claude Code:
claude mcp add responsive-tester -- npx -y @responsive-tester/mcp
Cursor, Windsurf, Cline, Continue, others: add the following to the client's MCP config file (location varies; each client documents where its mcp.json lives):
{
"mcpServers": {
"responsive-tester": {
"command": "npx",
"args": ["-y", "@responsive-tester/mcp"]
}
}
}
2. Connect from the Shell
Open Responsive Tester on any page and click the plug icon in the bottom-left corner, then Connect. The icon fills in when the bridge is live, and the menu flips to Disconnect.
The connection persists across browser restarts until you choose Disconnect. If the connection fails, see Troubleshooting.
3. Verify
Ask the agent to do something with the browser:
Use responsive-tester to launch example.com and list its breakpoints.
Using It
A few rules to remember:
- The agent works with session tabs. A session is any tab with the shell active. The agent can create one itself with
launch, or use a tab you activated from the toolbar icon. - Only one AI client can drive Responsive Tester at a time. Starting a second client takes control from the first.
- Frames need a moment after navigation. After
launch,navigate, or viewport changes, the agent pollsget_stateuntil every viewport reportsloading: false. - Element ids expire on navigation. They address the document they came from; the agent re-runs
query_selectorafter moving to a new page.
Example Prompts
Launch our staging site and tell me what breaks on phones.
What does the hero section actually do at each breakpoint?
Why is the card grid one column on tablet? Fix it.
Check dark mode at every width and screenshot anything with poor contrast.
Give me the CSS for everything you changed.
Tool Reference
All 25 tools the bridge exposes. Every tool requires a tabId from list_sessions or launch unless noted otherwise.
| Tool | Description |
|---|---|
ping | Health check. Confirms the extension is reachable. No tabId. |
list_sessions | List tabs with an active session. Returns tabId, url, title. No tabId. |
launch | Open a URL in a new tab and activate the shell on it, no user action needed. Optionally replaces the viewport set. Returns the new tabId. No tabId. |
close_session | End the session and return the tab to the plain page. Edits and element ids are discarded. |
focus_tab | Bring a session tab to the foreground so the user can watch. Handy before an edit. |
get_state | Session snapshot: url, mode, zoom, and each viewport's size, touch flag, scheme, rotation, and loading state. The readiness poll after navigation. |
navigate | Navigate every viewport frame to a new URL. Edits and element ids reset. |
add_viewport | Add a viewport frame with given CSS pixel dimensions, optional name and touch spoofing. |
remove_viewport | Remove a viewport frame. |
rotate_viewport | Swap a viewport's width and height. |
set_viewport_scheme | Emulate prefers-color-scheme for one frame: light, dark, or follow the app theme. Media queries react live. |
set_zoom | Set the shell's frame zoom (0.25 to 2). Visual only; computed styles and screenshots are unaffected. |
enter_breakpoints_mode | Replace the viewport set with one frame per CSS breakpoint found in the page's stylesheets. |
exit_breakpoints_mode | Restore the user's own viewport list. |
list_page_breakpoints | The width breakpoints declared in the page's stylesheets, without changing the viewports. |
query_selector | CSS selector query. Returns element summaries (tag, classes, rect, text, computed CSS subset) with ids that address the same element in every viewport. |
get_element_details | Uniform summary for one element in one viewport. |
get_element_audit | The element's effective responsive story: width segments listing only the properties whose effective value changes, cascade-aware, variables substituted. |
get_matched_rules | Full cascade view: rules per @media bucket with declarations, specificity, active flags, and a ruleRef for editing. Pass refs back exactly as received. |
compare_across_viewports | Computed styles for the same element in every live viewport simultaneously, one call. The single best tool for verifying responsive behavior. |
apply_styles | Apply CSS declarations. With a ruleRef the rule itself is edited, so the change follows the cascade everywhere. Without one, sets inline styles on the element. Empty value deletes; values may carry !important. |
add_rule | Add a new CSS rule, optionally inside a media condition and with seed declarations. Returns a ruleRef for follow-up edits. |
get_my_edits | Every tracked CSS change plus the combined paste-ready CSS text. Matches the editor's Changes panel. |
revert_all_edits | Revert every CSS change across all viewports and clear the Changes panel. |
screenshot_viewport | PNG of one viewport frame, downscaled to 1024px on the long edge. Rendered from a live DOM snapshot; cross-origin images may be missing. |
Troubleshooting
"Could Not Reach the MCP Server" When Clicking Connect
The MCP server package is not running. The bridge is not a background service; it is started by your AI client on demand. Make sure:
- You ran
claude mcp add responsive-tester ...(Claude Code) or added the config entry (other clients). - You restarted the AI client after configuring it.
- The client is currently running when you click Connect.
"MCP Server Outdated"
Your AI client is running an older version of @responsive-tester/mcp than this extension expects. Restart the client to pull the latest, or update the pinned version in its MCP config if you have one.
The Agent Says It Is Not Active on the Tab
There is no session on that tab. Ask the agent to call launch, or click the toolbar icon on the tab yourself. list_sessions only returns tabs with an active session.
"Only One Client at a Time"
Starting a second AI client takes control from the first. This is expected; the bridge is single-tenant. Disconnect the client you are not using.
The MCP Pill Is Locked
MCP is a Pro feature. Without a license or trial the plug icon shows dimmed, and Connect opens the pricing section. The Setup Guide stays available.
Screenshots Look Slightly Off
Captures are rendered from a live DOM snapshot inside the frame, not a pixel-perfect tab capture. Cross-origin images and canvases may be missing, and font rendering can differ slightly. Treat them as layout evidence, not pixel proofs.
Privacy
The MCP server runs locally and bridges the AI client to the extension over a localhost WebSocket. No page content or browser data is sent to any external service by the bridge itself. The AI client may send what it receives to its own backend; that side is governed by the client's own privacy policy.