Semorel - client-side AI agent SDK

Let trusted AI agents
use your app - safely,
in-session.

Semorel is a drop-in, client-side SDK. Agents read what is on your live app right now and can invoke only the actions you authorize - no scraping, no screenshots, no backend changes.

index.htmlone tag to adopt

<!-- drop the SDK into a running app -->

<script src="semorel.js"></script>

// reading is automatic, from the page's

// own HTML5 / ARIA / JSON-LD semantics.

// invoking stays opt-in, per action.

agent connectedMCP-compatible
A laptop on a desk showing code in an editor
A developer's laptop and code. Photo is illustrative.

What you get

One tag in. Agents that read, and act only where you say.

Semorel gives an agent the meaning of what is on screen and a short, curated set of actions - governed by your rules, confirmed outside the page.

Adopt

One tag to adopt

Drop a single script into your running app. No backend changes, no rewrite, no parallel state to hand-author.

Read

Reads your app's own meaning

It reads the semantics your app already declares - not screenshots, not scraped pixels.

Invoke

Actions are opt-in

Nothing is callable until you curate and authorize it, one action at a time.

Consent

Confirm outside the page

Sensitive actions prompt in the browser extension, where a web page cannot click Allow for you.

Govern

Policy, redaction and consent

Rules you declare decide what leaves the app; passwords and hidden fields stay out by default.

Provider-agnostic

Works with your agent

Anthropic, OpenAI, Gemini, Ollama and more - swappable live, mid-session.

The model, in order

Derive, curate, invoke.

Semorel follows one ordered path. The DataDocument is derived from the meaning your app already declares, you curate the short set of actions an agent may use, then the agent invokes only what you authorized - nothing is callable by default.

01

Derive

DataDocument read from your app's own semantics

02

Curate

You author the short set of opt-in actions

03

Invoke

The agent calls only what you authorized

How it reads

Read by derivation, not by scraping.

Every app already declares what it means - in its HTML5 structure, ARIA roles, forms and JSON-LD. Semorel reads that directly and builds a clean picture of what is on screen right now. No screenshots, no OCR, no guessing from pixels - so it does not break when you refactor CSS or ship an A/B test.
  • Reads the meaning your app already declares
  • No screenshots, OCR or scraped pixels
  • Survives a redesign or an A/B test
Source code on a blue-lit screenSemantics
Application source and structure. Illustrative photo.

Who stays in control

The app stays in control of what leaves it.

Agents read only what your rules allow, and can act only on the handful of actions you curate. Passwords and hidden fields are held back by default, and sensitive actions ask for confirmation in the browser extension - outside the page, where a web page cannot click Allow for you. A preview mode lets you see exactly what would flow before you turn anything on.
  • Curated, opt-in actions - nothing callable by default
  • Passwords and hidden fields redacted by default
  • Confirmation prompts render outside the page
A phone showing an app in a dark interfaceConsent
A device running an app. Illustrative photo.

Where it fits

Where Semorel fits.

Semorel is not a replacement for server-side MCP - it is the situational half, reading live in-session state a backend never sees. Here is how the ways to drive an app trade off, plainly.

SemorelServer-side MCPDOM / screenshot scrapingAccessibility automationTesseron / WebMCP
What it readsYour app's declarative semantics - HTML5, ARIA, JSON-LD, formsBackend data and stored capabilitiesPixels, OCR and raw DOMThe accessibility treeIn-page declared actions
Live in-session stateYes - the live screen, selection and unsaved dataNo - backend only, and complementaryInferred from pixels, unreliablePartial - an accessibility snapshotYes - in-page
Holds up over timeSemantic, stable across a relayoutStable, typed APIBreaks on a CSS or A/B changeDrifts with the accessibility treeStable, registered actions
Effort to adoptOne tag, then curate the actions you chooseHand-write server-side toolsNone - it just scrapesNone - it drives the UIRegister each action by hand
Where you confirmIn the extension, outside the pageServer-side auth and scopesNowhereAn OS automation grantIn the page

Fair read: server-side MCP owns the backend, and an agent connected to both gets backend reach and live in-session context through one coherent, MCP-compatible model. Semorel adds the situational surface the server never sees - it is the complement to MCP, not a competitor. Tesseron / WebMCP and accessibility automation keep their own real strengths.

Under the hood

Read by derivation, invoke by curation.

The story above is the plain version. For evaluators, here is how it actually holds together - a client-side SDK that reads the app's own semantics, curates the actions you choose, and keeps the consent boundary outside the page. It is MCP-compatible: the same tools / resources vocabulary, but the surface lives inside the running session.

From ViewDocument to DataDocument

Every app renders a ViewDocument - pixels built for humans, brittle to read. Semorel derives the other one: a canonical, semantic projection of what the app means right now, read from the declarative signals the app already emits. A snapshot plus a MutationObserver diff stream keeps it live.

the running appViewDocument

Review your booking

DestinationmicrodataDubai
AmountJSON-LD120,000
Departuretime2026-06-12

form: payment

method: card - save card

Confirm booking
DataDocument (snapshot)derived / live

{

"screen": "booking_review",

"entities": {

"booking": {

"destination": "Dubai",

"amount": 120000,

"departure": "2026-06-12"

}

},

"forms": { "payment": { ... } }

}

// snapshot + a diff stream, so agents track

// live state without re-reading it all.

Derived from

HTML5 sectioningARIA rolesmicrodataJSON-LDformstablesframework state

Reading is automatic, invoking is a decision

The two halves have different cost and safety profiles, so Semorel treats them differently: deriving state is on by default; invoking an action is opt-in, per action. The only per-screen work is filling in handler bodies - not authoring registration boilerplate.

01

Derive

automatic

Drop in the SDK. A DOM walker builds the DataDocument and discovers action candidates from the semantics the page already declares - no parallel state object to hand-author.

02

Curate

you author

Run semorel discover to generate typed *PageActions stubs, then fill in a manifest and a handler body. One class per route, in a dedicated src/semorel/ folder.

03

Invoke

opt-in

Nothing is callable until the app marks it agent-eligible. The agent reads the document, finds the curated tools, and invokes only what you authorized.

semorel/BookingReview.actions.tsthe manifest

{

"name": "confirm_booking",

"description": "Confirms the displayed booking.",

"requires_confirmation": true,

"input_schema": { "type": "object" }

}

// curated metadata, reviewable in a PR

// diff as a security artifact.

BookingReview.tsx@semorel/react

useSemorelTool("confirm_booking", {

requiresConfirmation: true,

handler: confirmBooking

});

// mark it invocable, attach a handler,

// require confirmation. that is all.

The consent boundary sits outside the page

A Chrome side panel presents the app's tools over an MCP-compatible surface. When an agent calls an action marked requires_confirmation, the prompt renders in the extension chrome - outside the page's React tree. A malicious page cannot reach in to auto-click Allow.

Semorelside panelconnected
ChatAuditLogsSettings

Book SFO -> JFK on 2026-06-01, cheapest.

reading DataDocument

Found trip.book. This action needs confirmation.

confirm - trip.book

SFO -> JFK, 2026-06-01. Charge 420 USD to saved card?

Allow onceDeny

rendered in extension chrome - the page cannot click this

Seven packages, DOM walker to agent

  • @semorel/coreRegistry, DataDocument, MCP dispatcher, redaction, policy
  • @semorel/webDOM extractor + the drop-in script bundle
  • @semorel/reactSemorelProvider + router / query / hook-form adapters
  • @semorel/clidiscover / check / init - codegen and CI drift
  • @semorel/agentReference MCP client
  • @semorel/extensionChrome side panel - Chat / Audit / Logs / Settings
  • @semorel/bridgeLocal daemon that connects vendor MCP hosts

Provider-agnostic: Claude Code and Codex connect via a local bridge daemon; Anthropic, OpenAI, Gemini and Ollama connect directly; Groq via an OpenAI-compatible path.

A CLI that scaffolds, a CI gate that catches drift

This is what makes an app agent-drivable without hand-registering every action. semorel discover walks your routes and generates typed *PageActions.ts stubs - regeneration is lossless, preserving every dev-edited handler. semorel check fails the build when the on-disk manifest drifts from the captured semantics.

terminal@semorel/cli 0.1.0

$ semorel discover

// walks routes, captures candidates

create src/semorel/HomePageActions.ts

create src/semorel/ResultsPageActions.ts

2 files - dev-edited handlers preserved

$ semorel check --audit-file results.json

/ in sync

trip.book in audit, not in manifest

error: manifest drift - exit 1

// exit 1 fails the CI job.

src/semorel/HomePageActions.tsgenerated

export class HomePageActions extends AuthoredActions {

tripSearch() {

const action = new AuthoredAction({

name: "trip.search",

inputSchema: { type: "object" },

});

action.invoke = this.tripSearchInvoke; // fill this in

}

}

// pages stay Semorel-unaware; you edit

// only files under src/semorel/.

semorel initsemorel discoversemorel checkcodegen + CI drift gate

Policy modes, from live to locked down

Policy is an in-app layer, enforced before any state or action reaches an agent, with conservative defaults that respect what the author already declared. Pick the posture that fits your risk.

mode: "live"default

The auto-derived DataDocument flows to trusted agents, subject to your redaction rules. The pragmatic default for reading, which is observable in dev tools anyway.

Redaction defaults (declared intent)

  • <input type="password">excluded
  • aria-hidden="true"excluded
  • [data-semorel="private"]excluded

Semorel enforces what you declare; it does not heuristically pattern-match for PII. A preview run sits alongside your existing GDPR / SOC2 / HIPAA / PCI review.

Request a pilot

Make your web app agent-drivable - safely, semantically, in-session.

Semorel is provider-agnostic and complementary to server-side MCP - a live, situational surface from inside the running session. It is private and unpublished today: access is clone-and-build, with no public npm or download command. If you are building agent-native workflows, we would like to compare notes.

Private / unpublished - clone-and-build access only