All use cases
Agents in your app

Let an agent operate your app alongside the user

Give an AI assistant real control of your interface — without screen scraping.

The problem

You want an assistant that can actually do things in your product: fill the form, switch the tab, correct the entry. The usual answer is browser automation — point Playwright at your own app and have it hunt for buttons.

That works until it doesn't. Automation driving a real UI breaks on every markup change, cannot tell a disabled button from a missing one, and locks the human out while it runs. You end up maintaining a second, worse client for your own app.

The problem is the interface: the agent is on the outside, guessing. It should be a participant, with the same access to state the UI has.

What you are building

Live surfaces, not screenshots — every one composed from the same components you would install.

Agents in your app

Live presence over a real page — agents act through MCP tools on stable handles, not DOM scraping.

Your app, co-driven2 agents
Researcher
Reviewer

Agents act through MCP tools on stable handles — never Playwright, never DOM scraping.

Hand over a session

The share surface an operator uses to bring an external agent into the running app.

Hand over the session
Sharingsession SgzsLgbC · token tok_exam
connected
Paste this straight into an AI agent — it connects over MCP, no browser
You're joining a live Human+ co-browsing session on a web app. This is an MCP
(Model Context Protocol) session — NOT a website to visit. Do NOT open the URL
in a browser and do NOT use any browser/Playwright tool. You drive the real,
running app through MCP tools while a human watches and can take over.

Session link (carries the session id + token — treat it as a secret):
  https://fancy.gen/agent-relay#session=SgzsLgbC&token=tok_example

Connect by running the relay client as an MCP server (zero install):
  npx -y mcp-relay-client "https://fancy.gen/agent-relay#session=SgzsLgbC&token=tok_example"

That exposes the app's own tools (e.g. page_describe, page_read, nav_visit,
page_click, page_set_field, page_submit, plus surface tools like whiteboard_*).
Then:
  1. Call page_describe first to see the current page and its interactive handles.
  2. Act only on the STABLE HANDLES the tools return — never guess DOM selectors.
  3. Navigate with nav_visit, type with page_set_field, click with page_click.
     Submits and destructive clicks are staged for the human to confirm.

If you can't register an MCP server but can run a shell, drive it directly:
  curl -O https://raw.githubusercontent.com/Particle-Academy/mcp-relay-client/main/connect.sh
  bash connect.sh "https://fancy.gen/agent-relay#session=SgzsLgbC&token=tok_example" tools
  bash connect.sh "https://fancy.gen/agent-relay#session=SgzsLgbC&token=tok_example" call page_describe '{}'

The code

Expose the surface as tools, not a DOMts
// The adapter is the whole contract: getters and setters over the state the
// human is already looking at. Every mutation broadcasts an AgentActivity
// event, so presence, undo and coaching compose for free.
registerFormBridge(server, {
  adapter: {
    getFields: () => fields,
    setField: (handle, value) => update(handle, value),
    submit: () => form.submit(),
  },
  pendingMode: true,   // destructive actions are PROPOSED, a human confirms
});
Hand an external agent the sessiontsx
// One session, one tool surface. Site tools are always present; a page's tools
// are contributed while it is mounted and withdrawn when it unmounts.
const { contributeBridges } = useCoBrowse();

useEffect(() => contributeBridges((server) =>
  registerArtboardBridge(server, { adapter }).dispose), []);

How to solve it

  1. Make the surface controlled

    An agent can only read what your app can hand it. Anything the agent should see or change needs to live in value + onChange state rather than inside the component. Most Fancy components are already controlled this way.

  2. Install the bridge layer

    One package carries the MCP server and every per-surface bridge.

    Run thisbash
    npm install @particle-academy/agent-integrations
  3. Register a bridge for each surface

    A bridge is an adapter: getters and setters over your existing state. Registering one exposes MCP tools the agent can call — form_* for forms, sheet_* for workbooks, flow_* for workflows, page_* to navigate the app itself. The agent calls a tool; your onChange fires exactly as if a human had typed.

  4. Show the human what the agent touched

    Every mutation broadcasts an AgentActivity event. Wire it up and the element the agent is working on highlights in the live UI, so the human watches rather than wonders.

  5. Stage anything destructive

    Mutations that a human would want to approve support a pendingMode: the agent proposes, the change appears as pending, and a person confirms it. Use it for anything you would not want done silently.