agenticschema
Turn Schema.org, JSON-LD, RDFa and Microdata into tools for AI agents. Zero backend, browser-first, with MCP and WebMCP support
Install / Use
claude mcp add searchstefano -- npx -y github:searchstefano/agenticschemaIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
Customer SupportSupported Platforms
Tags
Skill content
View source on GitHubAgenticSchema ·

Turn the Schema.org markup a page already has into MCP tools an AI agent can call.
Most pages already publish structured data. Agents still scrape them. This library closes that
gap: it reads the JSON-LD, microdata and RDFa already in the page and emits Model Context
Protocol tools. You write no new API and you run no backend.
Website
│
│ the Schema.org markup it already publishes:
│ JSON-LD · microdata · RDFa
▼
AgenticSchema
│
│ one callable tool per thing the page describes
│
┌─────┴─────┐
▼ ▼
WebMCP MCP
(browser) (Node)
└─────┬─────┘
▼
Agent
Here is what comes out of a page that exists today:
world.openfoodfacts.org/product/3017620422003
read get_web_site
read get_organization
read get_search_action
action search_web_site(search_term_string)
search_web_site is executable. An agent holding it queries Open Food Facts directly instead of
guessing a URL or going through a search engine. Nobody published anything new to make that
happen: the page has carried a SearchAction all along, and even the parameter name is the one
the page itself declares in query-input.
Run that page yourself. No browser, and no transport to configure:
npx @agenticschema/server https://world.openfoodfacts.org/product/3017620422003
(get_search_action in that list is noise, a read tool over the action's own definition. It is a
known rough edge, left visible rather than trimmed out of the example.)
On your own site it is one file. The script-tag build is a plain classic script with the WebMCP
polyfill already inside, roughly 27 KB gzipped, so it goes wherever a <script> tag goes: a
WordPress theme, a Shopify theme, a React, Next.js or Astro layout, or Google Tag Manager.
<script src="https://cdn.jsdelivr.net/npm/@agenticschema/browser@latest"></script>
You install no package and you configure no bundler. That tag reads the page and registers the tools, which is the whole of step one. Something still has to carry them to an agent: Chrome has run an origin trial for the native path since version 149, and there is a local relay for development. The next section is about that choice, and it is the part people get wrong.
Contents
The six sections worth reading before anything else. GitHub's own outline menu has the rest.
- Read this first: registration is not transport
- Quick start
- Why this is worth doing at all
- The core pipeline
- Security
- Troubleshooting
Read this first: registration is not transport
This is the single thing that trips people up, so it comes before everything else.
Getting a page's data to an agent takes two steps, and this library only does the first one:
① REGISTRATION ② TRANSPORT
@agenticschema/browser a WebMCP-capable browser,
reads the page's Schema.org an extension, or a local relay
markup and registers tools carries those tools to the agent
on document.modelContext
│ │
└──────────► document.modelContext ◄─────┘
(the meeting point)
@agenticschema/browser writes tools into document.modelContext. That is the whole job. It
does not open a connection to anything, because a browser tab cannot listen on a port. See
Three constraints.
So after adding the script tag you have a page whose tools are correctly registered and that no agent can reach yet. Nothing is broken; the second half is simply not there. You pick the transport separately, and the choice depends on who is meant to call the tools. See Choosing a transport.
The symptom of forgetting step ② is very specific and worth recognising: the tools show up in
Chrome DevTools (Application panel) but your MCP client reports zero sources. DevTools reads
document.modelContext in-process; your MCP client is a separate program that cannot. Everything
is working, and nothing is connected.
Quick start
Two tags. The first registers the tools, the second carries them to a local MCP client such as Claude Desktop, Cursor or Claude Code.
<!-- ① registration: read this page's Schema.org markup, publish it as WebMCP tools -->
<script src="https://cdn.jsdelivr.net/npm/@agenticschema/browser@latest"></script>
<!-- ② transport (development only): bridge those tools to a local MCP relay -->
<script src="https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay@4/dist/browser/embed.js"></script>
Then run the relay and point your MCP client at it:
{
"mcpServers": {
"webmcp-local-relay": {
"command": "npx",
"args": ["-y", "@mcp-b/webmcp-local-relay@latest"]
}
}
}
Open the page, and the tools appear in your client. Verify with webmcp_list_sources: your tab
should be listed with a tool count above zero.
Four things worth knowing before you paste that in:
- Order matters. The relay embed reads whatever is already registered and subscribes to changes, so put it after the registration tag.
- Leave off
type="module". The script-tag build is an IIFE, so it runs as an ordinary script, which is what makes it work through a tag manager. Addingtype="module"still works, but it costs youdocument.currentScriptand with it the simplest way to read options. See How the adapter finds its own tag. - Tag ② is for development. Shipping it to real visitors makes every one of their browsers probe
127.0.0.1. See Keep the relay out of production. - Pin your versions. Unversioned jsDelivr URLs are cached at the edge for days, long enough to
keep serving a build you have already replaced.
@latestand@4above are pins.
If you only want the browser's own built-in agent to use the tools, you need tag ① alone.
Why this is worth doing at all
That first sentence is measurable rather than a pitch. Schema.org publishes the usage statistics from Google's crawl, counting how many domains use each term:
| Term | Domains |
| ----------------- | ------- |
| potentialAction | 10M+ |
| SearchAction | 10M+ |
| EntryPoint | 10M+ |
| urlTemplate | 10M+ |
| query-input | 10M+ |
Over ten million domains already declare how to search them, machine-readably, today. That is a capability this library hands to an agent as a callable tool, and nobody had to publish anything new for it to work. The vocabulary's tail is shorter than it looks, too: of 958 types, 16 appear on 10M+ domains, 50 on 1M+ and 95 on 100K+, so a hand-written profile registry can cover the part of the web that exists in practice.
One caveat worth stating plainly: those counts are what sites declare, not what is well formed
enough to map. That is a different number, and the table does not claim it. Source:
schemaorg/schemaorg data/public_stats/google,
2026-07.
Try it without committing to anything
Three ways in, in rising order of commitment.
1. In the browser, nothing installed
Paste any JSON-LD and watch the tools appear. Try the hostile sample: it is the fastest way to see what the library refuses and why. Alongside it, a live page carrying the script tag for the WebMCP path end to end.
Both pages load the packages from jsDelivr at exact versions, so what you are trying is what you would ship, not a local build.
2. Read a real page from the terminal
No browser, and no transport question. The Node adapter fetches the page itself and speaks plain MCP over stdio:
npx @agenticschema/server https://en.wikipedia.org/wiki/Backpack
Wire it into Claude Desktop:
{
"mcpServers": {
"page": {
"command": "npx",
"args": ["-y", "@agenticschema/server", "https://en.wikipedia.org/wiki/Backpack"]
}
}
}
Every entity also becomes a readable MCP resource, which the browser adapter cannot do.
This is the shortest path to seeing real output, and the one with the fewest moving parts. If you are evaluating the library, start here.
3. On your own site
See Quick start above, then The script tag, in full.
The script tag, in full
Where the tag goes
The build is a single classic script with no bundler and no package install behind it, so
anywhere you can paste a <script> tag will do:
| Platform | Where |
| --- | --- |
| WordPress | The theme's header template, or any plugin that inserts scripts into <head>. |
| Shopify | theme.liquid, before the closing </head>. |
| React, Next.js, Astro | The shared layout or document component, alongside your other third-party tags. |
| Plain HTML | In <head>, or before </body>. |
| Google Tag Manager, Cloudflare Zaraz | A Custom HTML tag. See Through a tag manager. |
Put it in the layout that every page shares rather than on one page, and as early as you can. In
a single-page app the adapter follows history.pushState and route changes by itself, so a
single tag covers every route with no extra wiring.
One thing can stop it outright: a Content-Security-Policy that does not allow the CDN. That is a one-line fix, or you can self-host the file. See Content-Security-Policy.
If you would rather import the package instead, it is on npm, and the JavaScript API takes the options the attributes cannot express.
How the adapter finds its own tag
To read its data-* options the adapter first has to find the tag it was loaded from. It tries
three things, in order:
document.currentScript, set while a classic script runs, including one a tag manager inserted, andnullin a module script because the HTML specification says so,script[data-agenticschema], an explicit marker,script[src*="agenticschema"], the src of the standard snippet.
Since the build is an IIFE, the plain snippet takes rule 1 and everything works with no marker, whatever the file is called and however it got onto the page:
<script data-max-tools="8"
src="https://cdn.jsdelivr.net/npm/@agenticschema/browser@latest"></script>
Adding type="module" gives up rule 1. The tag then has to be identifiable some other way:
the URL above still matches rule 3, but a self-hosted copy under an unrelated filename matches
nothing, and its options are ignored in silence.
<!-- module script, and nothing in the src says "agenticschema": rule 2 or nothing -->
<script type="module" data-agenticschema data-max-tools="8"
src="/assets/webmcp-bundle.js"></script>
Using 0.1.2 or earlier? That build was ESM, so the tag needed
type="module", rule 1 never applied and rul
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
77.4kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
ruflo
70.1k🌊 The original agent meta-harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
headroom
68.3kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
46.8kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-model, multi-channel. Lightweight, extensible, one-line install. (formerly chatgpt-on-wechat)
