mcp-rnw-browser

mcp-rnw-browser

Enables browser automation for React Native Web applications using coordinate-based clicks to trigger RNW's gesture responder, with multi-tab management, screenshots, and persistent sessions.

Category
Visit Server

README

MCP Browser Server for React Native Web

npm version License: MIT

A Model Context Protocol (MCP) browser automation server specifically designed to work with React Native Web applications. Features multi-tab support, screenshot capabilities, and persistent browser sessions.

The Problem

React Native Web uses a gesture responder system that listens for mousedown/mouseup events instead of standard click events. This breaks standard browser automation tools like Playwright's locator.click() method.

The Solution

This MCP server uses coordinate-based clicks with Playwright's low-level page.mouse API, which properly triggers the mouse events that React Native Web components listen for.

Features

  • Coordinate-based clicking - Uses page.mouse.down() / page.mouse.up() instead of synthetic clicks
  • Multiple element finding strategies - CSS selector, text content, testID, or exact coordinates
  • Custom page snapshots - Shows interactive elements with positions (not reliant on accessibility tree)
  • Screenshot support - Returns base64-encoded PNG images that AI agents can view
  • Multi-tab management - Create, switch between, and close browser tabs
  • Persistent sessions - Browser stays open between tool calls for continuous interaction
  • Full browser control - Navigate, type, scroll, press keys, evaluate JavaScript

Installation

From npm

npm install @nizarius/mcp-rnw-browser
npx playwright install chromium

From source

git clone https://github.com/nizarius/mcp-rnw-browser.git
cd mcp-rnw-browser
npm install
npm run build
npx playwright install chromium

Configuration for Cursor

Add to your Cursor MCP settings (~/.cursor/mcp.json or Cursor Settings > MCP):

Using npm package (recommended)

{
  "mcpServers": {
    "rnw-browser": {
      "command": "npx",
      "args": ["@nizarius/mcp-rnw-browser"]
    }
  }
}

Using local installation

{
  "mcpServers": {
    "rnw-browser": {
      "command": "node",
      "args": ["/path/to/mcp-rnw-browser/dist/index.js"]
    }
  }
}

Available Tools

Navigation

rnw_navigate

Navigate to a URL. Creates a browser session if none exists.

{ "url": "http://localhost:8081" }

Returns: Page snapshot with all interactive elements.

Screenshots & Snapshots

rnw_snapshot

Get a text snapshot of interactive elements on the page with their positions. Returns element tags, text content, testIDs, roles, positions, and center coordinates for clicking.

// No parameters required
{}

Returns: Text list of all interactive elements with their positions.

rnw_screenshot

Take a screenshot and return as a base64-encoded PNG image.

// Viewport screenshot (default)
{}

// Full page screenshot (captures entire scrollable area)
{ "fullPage": true }

// Element screenshot (captures specific element)
{ "selector": "#my-component" }

Returns: Base64-encoded PNG image that AI agents can view directly.

Interactions

rnw_click

Click on an element using React Native Web compatible mouse events (mousedown/mouseup).

// By CSS selector
{ "selector": "button.submit", "findBy": "css" }

// By text content (partial match)
{ "selector": "Sign In", "findBy": "text" }

// By testID (data-testid attribute)
{ "selector": "login-button", "findBy": "testid" }

// By exact coordinates (useful when element detection fails)
{ "x": 500, "y": 300, "findBy": "coordinates" }

Returns: Click coordinates and updated page snapshot.

rnw_type

Type text into a focused element or find an element first and type into it.

// Type into currently focused element
{ "text": "Hello World" }

// Find element first, then type (clicks to focus)
{ "text": "Hello World", "selector": "input", "findBy": "css" }

// Type and press Enter (e.g., for search/submit)
{ "text": "Hello World", "selector": "input", "findBy": "css", "pressEnter": true }

Returns: Confirmation of typed text.

rnw_scroll

Scroll the page or a specific scrollable element.

// Scroll page down by 300 pixels
{ "direction": "down", "amount": 300 }

// Scroll page up
{ "direction": "up", "amount": 500 }

// Scroll within a specific container
{ "direction": "down", "amount": 200, "selector": ".scroll-container" }

Parameters: direction (up/down/left/right), amount (pixels, default: 300), selector (optional).

Returns: Updated page snapshot.

rnw_wait

Wait for a specified time or until an element appears on the page.

// Wait for 1 second (1000ms)
{ "time": 1000 }

// Wait for element to appear (with 5s timeout)
{ "selector": "button.loaded", "findBy": "css" }

// Wait for text to appear
{ "selector": "Loading complete", "findBy": "text" }

Returns: Confirmation when wait completes or error if timeout.

rnw_press_key

Press a keyboard key. Useful for navigation, form submission, or triggering shortcuts.

// Press Enter
{ "key": "Enter" }

// Press Escape
{ "key": "Escape" }

// Press arrow keys
{ "key": "ArrowDown" }

// Press Tab to move focus
{ "key": "Tab" }

Common keys: Enter, Escape, Tab, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Backspace, Delete, Space.

Returns: Confirmation of key pressed.

rnw_evaluate

Execute JavaScript in the browser context. Useful for debugging, reading state, or performing custom interactions.

// Get page title
{ "script": "document.title" }

// Get current URL
{ "script": "window.location.href" }

// Read localStorage value
{ "script": "localStorage.getItem('authToken')" }

// Get element count
{ "script": "document.querySelectorAll('button').length" }

// Trigger custom action
{ "script": "window.scrollTo(0, document.body.scrollHeight)" }

Returns: JSON-stringified result of the script execution.

Tab Management

rnw_tabs_list

List all open browser tabs with their index, title, and URL.

// No parameters required
{}

Returns: List of all tabs showing index, active status, title, and URL.

rnw_tabs_new

Create a new browser tab and optionally navigate to a URL. The new tab becomes the active tab.

// Create empty new tab (about:blank)
{}

// Create new tab and navigate to URL
{ "url": "http://localhost:8081/settings" }

Returns: New tab index and page snapshot.

rnw_tabs_select

Switch to a specific tab by index (0-based). Use rnw_tabs_list to see available tabs.

// Switch to second tab
{ "index": 1 }

// Switch to first tab
{ "index": 0 }

Returns: Snapshot of the selected tab's page.

rnw_tabs_close

Close a browser tab. If the closed tab was active, switches to the nearest remaining tab.

// Close current active tab
{}

// Close specific tab by index
{ "index": 2 }

Returns: Confirmation and snapshot of the new active tab.

Session Management

rnw_session_status

Get current browser session status. Useful for checking if a session is active before performing actions.

// No parameters required
{}

Returns:

  • isRunning: Whether browser is active
  • tabCount: Number of open tabs
  • currentTabIndex: Index of active tab
  • currentUrl: URL of active tab
  • viewport: Browser window dimensions (width x height)

rnw_close

Close the browser and end the session. All tabs are closed and resources are released.

// No parameters required
{}

Returns: Confirmation that browser session has ended.

How It Works

Standard Playwright Click (Doesn't work with RNW)

// This dispatches a synthetic 'click' event that RNW ignores
await element.click();

This MCP Server's Click (Works with RNW)

// This triggers real mousedown/mouseup events that RNW responds to
await page.mouse.move(x, y);
await page.mouse.down();
await page.mouse.up();

Example Usage with AI Agent

Agent: Let me navigate to your React Native Web app, take a screenshot, and click the login button.

> rnw_navigate { "url": "http://localhost:8081" }

Page loaded. I can see the following interactive elements:
[0] button testid="login-button"
    text: "Sign In"
    center: (640, 400)

> rnw_screenshot {}

[Returns PNG image of the page]

> rnw_click { "selector": "login-button", "findBy": "testid" }

Clicked at (640, 400). The login form is now visible.

> rnw_tabs_new { "url": "http://localhost:8081/settings" }

Created new tab [1] and navigated to settings page.

> rnw_tabs_list {}

Open Tabs (2):
[0] Home - http://localhost:8081/
[1] (active) Settings - http://localhost:8081/settings

Continuous Session Workflow

The browser session persists across tool calls, enabling:

  1. Multi-step interactions - Navigate, screenshot, interact, screenshot again
  2. Visual verification - Take screenshots to verify UI state after actions
  3. Multi-page workflows - Open multiple tabs for complex testing scenarios
  4. Debugging - Use rnw_evaluate to inspect page state
Agent: I'll test the multi-step form submission.

> rnw_navigate { "url": "http://localhost:8081/form" }
> rnw_screenshot {}  // Verify initial state
> rnw_type { "text": "John Doe", "selector": "[data-testid='name-input']", "findBy": "css" }
> rnw_screenshot {}  // Verify text entered
> rnw_click { "selector": "Submit", "findBy": "text" }
> rnw_screenshot {}  // Verify submission result
> rnw_close {}       // End session when done

Troubleshooting

Elements not found

  • Make sure your React Native Web components have testID props set
  • Use rnw_snapshot to see available elements
  • Try using text content with findBy: "text"

Clicks not registering

  • Ensure the element is visible and not covered by another element
  • Try increasing the delay with rnw_wait before clicking
  • Use coordinates directly if element finding fails

Screenshots not working

  • Ensure the browser session is active (rnw_session_status)
  • For element screenshots, verify the selector matches a visible element

Version History

v2.0.0

  • Added screenshot support with base64 image return
  • Added multi-tab management (list, new, select, close)
  • Added session status tool
  • Improved tool response format
  • Persistent browser sessions

v1.0.0

  • Initial release with RNW-compatible clicking
  • Basic navigation, snapshot, and interaction tools

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured