Orb MCP
Cookieless website analytics built for AI. Connect Claude, ChatGPT, Cursor, Grok, or any MCP client and ask what visitors did.
Hosted MCP Server
npx add-mcp 'https://orbmcp.com/api/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
Quickstart.
Set up Orb on a website: paste one script, connect the MCP server, then ask an AI about the traffic.
01
What Orb is
Orb is cookieless web analytics that an AI reads through MCP (Model Context Protocol) instead of a dashboard. One script records what visitors do. The MCP server lets Claude, ChatGPT, Cursor or any MCP client answer questions about that traffic in plain English. There is no dashboard to learn. Free for one website and 25,000 events a month, then from $10 a month. Every plan keeps 12 months of history.
This page is written to be followed start to finish by a coding agent. Every step is text or code. If you are an agent setting Orb up for someone, follow the sections in order.
02
Get a site ID
Every website has an ID that looks like site_XXXXXXXXXX. You need one before the script does anything. Ask the person you are working for to open https://orbmcp.com/connect, sign in, and press "Get a setup code". They give you a code that looks like ORB-XXXX-XXXX. It lasts 15 minutes and works once.
Exchange the setup code for a token
curl -s -X POST https://orbmcp.com/api/setup/exchange \
-H 'Content-Type: application/json' \
-d '{"code":"ORB-XXXX-XXXX"}'
The response contains a token. It can create websites and read analytics only for the websites it creates, never the rest of the account. Keep it out of version control: put it in an environment variable or the AI client config only.
Create the website and get its snippet
curl -s -X POST https://orbmcp.com/api/setup/sites \
-H 'Authorization: Bearer ORB_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"YOUR_SITE_NAME","domain":"YOUR_DOMAIN"}'
The response contains site_id and snippet. Use the snippet exactly as returned; it already has the right site ID. If the domain already exists on the account, the same site is returned rather than a duplicate. Register the domain the pages are actually served from, subdomains included: events from any other hostname are discarded. For a site you are only running locally, register the domain as localhost.
03
Add the script
Add this to the <head> of every page, replacing SITE_ID with the site ID from the previous step. It is asynchronous and sets no cookies, so it needs no consent banner.
The script
<script async src="https://orbmcp.com/orb.js" data-site="SITE_ID"></script>
Next.js (App Router): app/layout.tsx
import Script from 'next/script'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://orbmcp.com/orb.js" data-site="SITE_ID" strategy="afterInteractive" />
</body>
</html>
)
}
Vite, Create React App, or any index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My site</title>
<script async src="https://orbmcp.com/orb.js" data-site="SITE_ID"></script>
</head>
<body></body>
</html>
Plain HTML, every page or a shared header include
<head>
<script async src="https://orbmcp.com/orb.js" data-site="SITE_ID"></script>
</head>
Single-page apps need nothing extra: route changes are tracked automatically. Pageviews, sessions, referrers, campaigns, button clicks, form submissions, outbound clicks and downloads are all captured without configuration.
04
Connect the MCP server
The MCP server is Streamable HTTP at https://orbmcp.com/api/mcp. Authenticate with the token as a Bearer header. Clients that cannot set headers can use https://orbmcp.com/api/mcp/ORB\_TOKEN instead, which puts the token in the URL, so treat that URL as a secret.
Cursor: ~/.cursor/mcp.json, or.cursor/mcp.json in the project
{
"mcpServers": {
"orb": {
"url": "https://orbmcp.com/api/mcp",
"headers": {
"Authorization": "Bearer ORB_TOKEN"
}
}
}
}
Claude Code
claude mcp add --transport http orb https://orbmcp.com/api/mcp \
--header "Authorization: Bearer ORB_TOKEN"
Claude desktop and ChatGPT add it as a custom connector using the URL form https://orbmcp.com/api/mcp/ORB\_TOKEN. Any other MCP client uses the Streamable HTTP transport with the same URL and Bearer header.
Where the token ends up matters, and there are two good places. The command above stores it in the user's own client config, outside the project. If you are an agent that cannot write outside the working directory, use the project config below instead. Both are fine. What is not fine is a literal token written into a file inside the repository, because a project-scoped.mcp.json is committed like any other file.
For a config file inside the project, keep the token in the environment rather than the file. Claude Code and Cursor both expand ${ORB_TOKEN} at load time. If a token is ever exposed, revoke it at https://orbmcp.com/connect and issue another.
Project config with no secret in it:.mcp.json
{
"mcpServers": {
"orb": {
"type": "http",
"url": "https://orbmcp.com/api/mcp",
"headers": { "Authorization": "Bearer ${ORB_TOKEN}" }
}
}
}
Then keep the value out of git
echo 'ORB_TOKEN=ffk_your_token_here' >> .env.local
grep -qxF '.env.local' .gitignore || echo '.env.local' >> .gitignore
05
Check it works
One step here needs a browser, so an agent cannot finish it alone: a real page has to load once with the script on it. Everything up to that point is done.
- 01Deploy the site, or start it locally.
- 02Open one page in a browser. Ask the person you are working for to do this if you have no browser.
- 03Run the command below. While no page has been loaded yet the site reads waiting_for_data, which is expected, not a fault. Once a visit lands it reads receiving_data.
Two separate things decide whether a visit is recorded, and both must be right. First, the script has to run: it ignores localhost unless the tag carries data-allow-localhost, which is safe to leave in place because it changes nothing on a real domain. Second, the page hostname has to match the website registered here, subdomains included. A page served from localhost does not match a website registered as example.com, and the request still returns 202, so nothing tells you the events were dropped.
Local testing variant
<script async src="https://orbmcp.com/orb.js" data-site="SITE_ID" data-allow-localhost></script>
Confirm data is arriving
curl -s -X POST https://orbmcp.com/api/mcp \
-H 'Authorization: Bearer ORB_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_sites","arguments":{}}}'
If nothing arrives, check these in order: the script is on the page you actually loaded; the hostname in the browser address bar matches the domain the website is registered under; and the browser does not have Do Not Track or Global Privacy Control turned on, because those visitors are never counted.
06
Then ask
Once data is arriving, the person can ask their AI about the site. Naming Orb in the question tells the assistant to use the connection rather than guess.
- 01Use Orb to look at example.com and set up the conversions I should be tracking.
- 02Use Orb to show me what changed on my website since I last checked.
- 03Use Orb to tell me where people give up before buying.
There are 24 tools, covering traffic sources, pages, funnels, revenue, conversions and change detection. Conversions can be created through MCP with create_conversion, so setting them up needs no dashboard either.