@agent-mcp/react
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@agent-mcp/reactFilter customers to at-risk with revenue above 1M"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
agent-mcp-react
Make your React page an MCP server.
Expose a running React application as an MCP server, so an agent can drive it through typed tools instead of clicking its UI.
customers.set_filters({ health: ["at_risk"], arrMin: 1000000 })instead of opening filters, finding Health, clicking At risk, then setting a revenue floor by hand.

A person describes a dashboard; the agent composes it by calling the tools the page declared, and the panels it built are then driven by hand. Twenty seconds of the full three-minute recording. The left pane is the agent's real tool calls — nothing there is a transcript written for the video.
The application keeps owning its state. MCP is a second control interface onto the same application actions the human UI already calls. It is not browser automation, and not a second store.
This library is the browser half. The MCP server runs in the tab. The page asks your app for a URL, connects out to your gateway, and answers from there. You still supply the gateway, a ticket minter, and an agent runtime where the MCP client lives.
What the agent can do
Application tools you declare in React. They exist while that UI is on screen. Input is schema-checked before the handler runs. You must configure a validator.
Optional DOM tools (experimental): inspect the page, then click, fill, type, or scroll. Reading and acting are separate permissions. Off by default. These tools never enter the shared page registry.
Optional JavaScript evaluation in the page. Off by default. Privileged. Each call needs approval. This tool never enters the shared page registry.
Capability and confirmation checks apply to this library's connection. Other callers using the shared page registry skip those gates. Keep real authorization in your handlers.
Related MCP server: React Native MCP Server
Browser requirements
Requirement | Why |
A secure context | The tool registry is defined only in a secure context. |
A tool registry | One browser channel ships |
| Engine floor: Chrome 116, Safari 17.4, Firefox 124. |
The documented browser matrix is a support target, not fully verified. Three Playwright engines are not nine browser-and-version combinations. What has been run, and what has not: docs/browser-support.md.
Quickstart — using it in your app
npm install agent-mcp-reactESM only. React >=18 as a peer, Node >=22 for the toolchain, and a secure context in the browser
(localhost counts).
Wrap your app in the provider and declare one tool in the component that owns the state — both shown in full under Use it below. Then open the page and paste this into the browser console:
const mc = document.modelContext;
const tool = (await mc.getTools()).find((t) => t.name === 'counter.increment');
await mc.executeTool(tool, JSON.stringify({ by: 7 }));The number on the page changes. You needed no agent, no API key and no backend to see that — the tool is in the browser's own per-document registry, which is exactly where a browser-native agent looks. Connecting an external agent over a socket is a later step, and your backend owns it.
The same path, at a slower pace and with the reasons: docs/tutorial-first-tool.md — about fifteen minutes.
Working from a checkout instead? Pack it and depend on the tarball; a file: dependency on the
directory does not work, because publishConfig applies when a package is packed and never when a
directory is linked. Routes and failure modes:
docs/consuming-without-publishing.md.
pnpm pack # → agent-mcp-react-<version>.tgzUse it
Four props are required: connection, server, capabilities, and onUnexpectedState. This
snippet is compiled against the packed tarball from a project outside this repository.
import { AgentMcpProvider, CONFIRMATION } from 'agent-mcp-react';
import { createAjvValidator } from 'agent-mcp-react/validation';
<AgentMcpProvider
connection={{
getUrl: async () => {
// Called once per connection attempt. Opaque to the library: never parsed,
// never amended, never stored. Your backend mints a single-use credential.
const { url } = await fetch('/api/mcp-ticket', { method: 'POST' }).then((r) => r.json());
return url;
},
}}
server={{ name: 'my-app', version: '1.0.0' }}
// Every member is required. An omitted one is denied rather than defaulted.
capabilities={{
application: true,
dom: { inspect: false, interact: false },
evaluate: false,
}}
onUnexpectedState={(failure) => console.error('[mcp]', failure)}
validation={{ validator: createAjvValidator() }}
// Asked before a tool declared `confirmation: 'required'` runs. Without a resolver such a
// tool is refused at every call — absence is not consent.
confirmation={{
resolver: (request) =>
window.confirm(`Allow ${request.tool}?`) ? CONFIRMATION.approved : CONFIRMATION.refused,
}}
>
<App />
</AgentMcpProvider>Declare a tool in the component that owns the feature. It exists while that component is mounted, and the handler always reads current state:
import { useMcpTool } from 'agent-mcp-react';
useMcpTool({
name: 'account.set_health',
title: "Change the open account's health",
description: 'Set the relationship health of the account whose drawer is open.',
inputSchema: {
type: 'object',
properties: {
health: { type: 'string', enum: ['green', 'amber', 'red'] },
reason: { type: 'string', minLength: 1 },
},
required: ['health', 'reason'],
additionalProperties: false,
},
permissions: { confirmation: 'required' },
handler: (input) => {
dashboard.setHealth(account.id, input.health as Health, ACTOR.agent);
return { account: account.name, to: input.health };
},
});The schema is enforced in the runtime before the handler runs.
What you have to supply
A WebSocket gateway | Terminates the socket and relays MCP to your agent runtime |
A ticket minter | A backend endpoint issuing a single-use credential per connection attempt |
An agent runtime | Where the MCP client lives, because that is where the socket is held |
tools/mock-agent/ implements all three for local development and is not a production component.
The provider takes getUrl() and never a credential.
Things that will bite you
|
|
| A registry-integrity alarm has no response to travel back on. |
A schema with no validator | The declaration is refused with |
| Under a strict policy it throws at declaration, so the page exposes no tools at all and an agent sees an empty page rather than an error. |
A secure context is required |
|
A mutating handler must await | Otherwise it resolves before React commits, and a state read in the same turn returns the previous render. The agent is told the mutation succeeded and then reads a value that does not include it — which looks exactly like a tool that silently did nothing, so the agent retries. Commit and registration. |
| The agent waits for a person; any script, widget or extension on the page calls the same tool with no dialog. It is not authorization. Anything that must never happen without consent belongs inside the handler. Declaring a tool. |
| The provider adopts the registry asynchronously, in an effect. A sibling or child that reads the registry in its own mount effect finds nothing and, if it only looks once, stays empty forever. Reading the registry from the page. |
A page-script call refused for bad arguments is invisible to your observers | The registry validates against the declared schema and throws before this library sees the call, so nothing reaches |
Docs
If you want | Read |
To see it work in fifteen minutes | |
Every public export | |
To use it without publishing it | |
To declare a tool | |
To wire the socket | |
To let an agent read state | |
To bind Redux, Zustand, or a router | |
The design, condensed | |
What changed, and when | |
Everything else |
Quickstart — working on the library
git clone https://github.com/A-Launch/agent-mcp-react.git
cd agent-mcp-react
pnpm install # Node >=22; corepack enable gets the pinned pnpm
scripts/setup-git-hooks.sh # points core.hooksPath at .githooks/
pnpm gate # everything that must be green before a pull requestpnpm gate is the whole health check in one command and takes a few minutes. If it passes on a fresh
clone, your environment is right and anything that breaks later is yours.
To watch an agent drive a real page, run three servers in three terminals — the pages are demonstrators in this repository, and the agent is a mock that stands in for a real runtime:
pnpm dev:agent # mock agent runtime :45000
pnpm dev:example # customer dashboard :45010
pnpm dev:board # composable board :45030Then open http://localhost:45010, and drive it from
http://localhost:45020 (pnpm dev:chat) or by calling the mock agent's HTTP endpoints directly.
Ports, environment variables, capability profiles and the test layers:
docs/local-development.md.
Before your first pull request, read sections 2 and 3 of CONTRIBUTING.md — setup and the gate. The rest can wait until you need it.
Health gate
pnpm gateRequired after any change under src/, examples/ or tools/. What it runs, and in which order, is
in package.json — it builds the library and the examples, runs the unit, React, transport and
integration suites, typechecks, lints, and verifies the packed tarball and an external consumer.
Three of those ask a question the suites cannot. pnpm build asserts what is in dist/ rather
than what the compiler returned, because a build can exit zero having emitted nothing and exit non-zero
having emitted something unloadable. verify:package resolves every export the packed tarball
declares, from inside the tarball. verify:consumer installs that tarball into a project outside
this repository, typechecks it against the shipped types and bundles it with a real bundler — which
is the only check that asks whether an embedder can actually consume this package, since everything
in-repo resolves through workspace paths and a root tsconfig instead.
Three more run separately, because they need dev servers or browser binaries:
pnpm test:e2e # three engines, real browser, real socket
pnpm test:e2e:native # opt-in: Chromium with a real native tool registry
pnpm verify:consumer:runs # loads an external project's production bundle in a browserContributing
Issues and pull requests are welcome. CONTRIBUTING.md owns every convention here — where code goes, the five invariants that fail silently, what the gate requires of a change, and the patterns that are refused outright. Read sections 2 and 3 before your first pull request; they are the setup and the gate, and everything else can be read when you need it.
By participating you agree to the code of conduct.
Found a security problem? Do not open an issue. SECURITY.md says how to report it privately — a reachability hole in this library is reachable on every page that embeds it, from the moment the issue is readable.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Run multi-step tasks in a real Chrome browser: persistent environments, live view, human takeover.
Build and run grounded business agents over MCP: agents, knowledge bases, skills, Storylines.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables MCP-compatible AI agents to execute typed live-app actions over WebSocket, allowing agents to directly interact with real application state without browser automation or scraping.20-
- AlicenseNot gradedqualityDmaintenanceEnables automation and monitoring of React Native apps by providing tools to tap, swipe, screenshot, inspect component state, profile renders, and mock network requests via MCP.127MIT
- FlicenseNot gradedqualityBmaintenanceMCP server that lets agents drive a browser and record every action into a replayable trace, then replay it deterministically with network request assertions. It exposes tools for navigating, clicking, filling, and verifying requests.-
- -licenseNot gradedqualityCmaintenanceEnables AI agents to discover and call business actions from browser-only legacy web applications as typed MCP tools, executing them through the original GUI via Playwright.-