Chromeflow vs Periscope MCP — MCP Server Comparison | AllMCPs
Side-by-Side Model Context Protocol Comparison
Chromeflow vs Periscope MCP
In-depth architectural comparison of the Chromeflow and Periscope MCP MCP servers. Compare execution transports, security boundaries, tool capabilities, quality scores, and ready-to-paste client installation snippets for Claude, Cursor, Windsurf, and VS Code.
At a Glance & Executive Verdict
Chromeflow
Browser Automation · Local stdio
Quality: 64/100 (Good) | Auth: No auth required
Periscope MCP
Browser Automation · Local stdio
Quality: 49/100 (Fair) | Auth: No auth required
Verdict Summary: Choose Chromeflow if you need specialized Browser Automation tools running via a local process. Choose Periscope MCP if your workspace requires Browser Automation integration with local subprocess execution. Both servers can be configured concurrently in your client's mcpServers manifest.
Which MCP Server Should You Choose?
Choose Chromeflow when:
You need dedicated capabilities in the Browser Automation domain.
You prefer local stdio subprocess transport architecture.
Your security boundary fits: No auth required (Free / Open Source).
Lets Claude Code or Codex CLI drive your real Chrome — sessions intact, 26 browser tools.
Website & web-app testing built for AI agents rather than raw browser bindings: 66 Playwright tools with hard assertions, auto form-fill, persistent authenticated sessions (incl. interactive login for 2FA/SSO), network mocking, real INP, and accessibility/SEO/GEO (llms.txt, AI-crawler access, WebMCP) + Lighthouse audits.
Navigate to a URL. By default reuses the active tab. Set new_tab=true to open alongside the current tab without losing it. After navigating, call get_page_text to read the page — do NOT take a screenshot.
Set background=true (only with new_tab=true) to open the new tab WITHOUT switching focus to it. Use this when the current tab has a partially-filled form whose page auto-saves on focus loss (e.g. eBay seller listings) — switching away would trigger the auto-save and corrupt the in-progress draft.
After tabs.onUpdated fires status=complete, chromeflow also runs a 6s settle check (document.readyState=complete, no visible spinner element, 250ms of mutation quiet). If a spinner is still visible at the end of the window, the response carries `stuck_spinner: true` with the matching selector — the canonical case is an SPA route that left a permanent .spinner-wrapper because the API request died. Set expect_selector to wait for a known-good element to appear before considering the page settled — the response carries `expect_selector_appeared: false` if it never showed up.
inspect_request_headers
Capture the request headers Chrome sends to a URL — useful for diagnosing server-side bot detection. Returns method, URL, and all headers. Cookie values are redacted by default to avoid leaking session tokens into the agent context; pass redact_cookies: false to see them. By default opens a background tab for the inspection so your active tab keeps its scroll position and form state — set new_tab: false to use the active tab instead.
switch_to_tab
Ready-to-Paste Client Configurations
Paste either (or both) of these JSON server blocks into your client config file (e.g. claude_desktop_config.json or ~/.cursor/mcp.json).
Chromeflow is categorized under Browser Automation and uses a local stdio subprocess. In contrast, Periscope MCP belongs to Browser Automation using local stdio subprocess. Select Chromeflow when you need capabilities focused on browser automation and Periscope MCP when you require tools for browser automation.
Switch the active tab to a different open tab. Use this after open_page(new_tab=true) to switch back to the original tab, or to jump between tabs.
Accepts: a tab number (1-based), a URL substring, or a title substring.
Pass it as either `tab` (mirrors the verb in the tool name — natural when targeting by index) or `query` (clearer when matching by URL/title substring). Both work identically.
Examples: switch_to_tab({tab: 1}) for the first tab, switch_to_tab({tab: "form"}) or switch_to_tab({query: "form"}) for a tab whose URL or title contains "form".
list_tabs
List all open tabs in the current window with their index, title, and URL. Use this before switch_to_tab if you're not sure which tab to switch to.
close_tab
Close a tab by number, URL substring, or title substring. Mirrors switch_to_tab's matcher. Defaults to closing the ACTIVE tab when no query is given. Use this to clean up the tab pile after a multi-step workflow.
close_other_tabs
Close every tab in the current window EXCEPT the active one (or any tab matching keep_query). Use at the end of a session to tidy up; do NOT use mid-flow if you may need to return to one of the closed tabs.
interactive_snapshot
Compact, accessibility-style list of the page's ACTIONABLE elements — each as [role] name — selector. Use this INSTEAD of get_page_text or take_screenshot when your goal is to ACT (click / type / select), not to read prose: it is far cheaper in tokens than dumping page text, and every line gives a ready-to-use selector for click_element / type_text. Pierces open AND closed shadow roots (Reddit faceplate-*, Radix/Stencil/Lit), which a raw accessibility tree misses. Returns the top elements by document order; pass max to widen. For reading article/body text, still use get_page_text.
take_screenshot
Capture a screenshot of the active tab. By default the image is returned to the agent inline UNLESS it exceeds ~500KB base64, in which case it's saved to a temp file and the path is returned instead (preserves the agent's context window). Set inline="always" to force inline regardless of size, or inline="never" to always write to a file. Set save_to or copy_to_clipboard to also share the image with the user. Reserved for cases where DOM lookup has already failed — use get_page_text and find_text for reading content.
Refuses fast on pages that are in fullscreen mode (captureVisibleTab hangs there). Exit fullscreen first with execute_script("document.exitFullscreen()") or pass allow_fullscreen: true if you really must try anyway.
capture_terminal
Capture a screenshot of the terminal window (Terminal, iTerm2, Warp, VS Code, Ghostty, etc.) and save it as a PNG.
Use this when you need a screenshot of terminal output — e.g. test results, build logs, or command output — to upload to a form via set_file_input.
Auto-detects the terminal app. Returns the image to Claude AND saves the PNG file.
The saved file path can be passed directly to set_file_input(hint, file_path) to upload it.
clear_overlays
Remove all highlights and callout annotations from the current page.
get_form_fields
Inventory form fields on the active page (inputs, textareas, selects, CodeMirror editors). Sorted top-to-bottom by y-position; includes fields below the fold.
Pass `query` to filter+rank by label/placeholder/aria-label/name/id (the old find_input behavior — match strength reported as aria-eq / placeholder-eq / label-text-eq / name-eq / id-eq / *-includes / fuzzy-text-walk). Pass `exact: true` to refuse fuzzy text-walk matches.
Pass `only_empty: true` to filter the inventory to required-but-empty fields. This is the "why is Submit disabled" diagnostic: it returns just the required fields that haven't been filled yet (or radios/checkboxes still unchecked) and skips everything that's already populated. Required-ness is detected via the `required` attribute, `aria-required`, or a trailing `*` in the associated label text.
type_text
Type text into the currently focused element via CDP keystrokes (produces isTrusted=true events). Use when fill_input fails because the page validates isTrusted (CodeMirror/Monaco/Ace editors, shadow DOM inputs, isTrusted-gated forms). Pass `into_selector` to focus the target before typing (shadow-piercing CSS) — combined with `clear_first: true`, this collapses the old "wait_for_click → execute_script selectAll → type_text" pattern into a single call. Pass `frame: "iframe.selector"` to type into a same-origin iframe's first editable element.
**Post-type landing verification, always on.** Whether you pass `into_selector` or type into whatever's already focused, type_text reads back the target element after typing and returns `landed:false` (success:false) if the text did NOT actually stick — never trust a bare "Typed N characters" without checking this. Two known causes: (1) a rich-text editor's own state machine reverts the keystrokes (TipTap/ProseMirror — auto-recovers via `document.execCommand('insertText', ...)`, message records "recovered via execCommand insertText"); (2) tenant-level anti-automation discards synthetic keystrokes outright with zero visible error (seen on some Workday tenants) — for a plain `<input>`/`<textarea>` this attempts a native-value-setter recovery, and if that ALSO fails, reports `landed:false` so you stop and report the wall instead of proceeding on a false premise.
+20 more tools listed on main page
Periscope MCP Tools (74)
create_project
Create a new testing project
list_projects
List all projects
get_project
Get project details
delete_project
Delete project + data
set_form_login
Configure username/password form login
set_basic_auth
Configure HTTP Basic Auth
set_cookies
Inject session cookies
login_project
Execute login using configured auth
interactive_login
Open a **visible** window to log in by hand (2FA/SSO/CAPTCHA), then `save_login
save_login
Capture the manual-login session; the project then runs authenticated + headless