Web analytics your AI agent can read. Same idea as Google Analytics — add a JS snippet to your site — but instead of dashboards, your agent queries the data via CLI or API.
Pair it with OpenClaw or any coding agent and it becomes a growth machine — your agent checks traffic, runs A/B tests, finds funnel drop-offs, and tells you what to fix. While you sleep.
Self-host on Cloudflare Workers (free tier) or Node.js. Or use the managed service if you don't want to run infrastructure.
Runs on the free tier. D1 database included.
# 1. Clone
git clone https://github.com/Agent-Analytics/agent-analytics.git
cd agent-analytics
# 2. Create a D1 database
npx wrangler d1 create agent-analyticsThis outputs something like:
database_name = "agent-analytics"
database_id = "abc123-your-id-here"
Update wrangler.toml:
- Replace
YOUR_DATABASE_IDwith your actual database ID. - Optionally change
nameat the top for a custom Worker name (determines your deploy URL).
Keep the binding as
DB— don't copy the binding name from thed1 createoutput (it generatesagent_analytics, but the code expectsDB).
# 3. Initialize the schema
npx wrangler d1 execute agent-analytics --remote --file=./schema.sqlTroubleshooting: Authentication error? Set your account ID:
export CLOUDFLARE_ACCOUNT_ID=your-account-id
# 4. Install dependencies
npm install
# 5. Deploy
npx wrangler deploy
# 6. Set secrets (after deploy — the Worker must exist first)
echo "your-secret-read-key" | npx wrangler secret put API_KEYS
echo "pt_your-project-token" | npx wrangler secret put PROJECT_TOKENSYour endpoint: https://agent-analytics.YOUR-SUBDOMAIN.workers.dev
Optional: Enable Queue (high-traffic sites)
By default, events write directly to D1 via ctx.waitUntil() — already non-blocking. For very high-traffic sites, enable Cloudflare Queues for batching and retries (requires Workers Paid plan, $5/month).
npx wrangler queues create agent-analytics-eventsUncomment [[queues.producers]] and [[queues.consumers]] in wrangler.toml, then npx wrangler deploy.
Events are batch-written (up to 100 per batch, flushed every 5s). Falls back to direct write if the queue fails.
git clone https://github.com/Agent-Analytics/agent-analytics.git
cd agent-analytics && npm install
API_KEYS=my-secret-key PROJECT_TOKENS=pt_my-token npm start
# Or: PORT=3000 DB_PATH=./data/analytics.db API_KEYS=key1,key2 npm startUses SQLite via better-sqlite3. Database auto-created at DB_PATH (defaults to ./analytics.db).
Drop one line before </body> — just like Google Analytics:
<script src="https://your-server.com/tracker.js" data-project="my-site" data-token="pt_your-project-token"></script>Replace your-server.com with your Worker URL or Node.js host.
This auto-tracks page views with URL, referrer, and screen size. For custom events:
window.aa.track('signup_click', { plan: 'pro', page: '/pricing' });
window.aa.identify('user_123');
window.aa.page('Dashboard');Framework guides:
- Plain HTML — add before
</body>ofindex.html - React/Next.js — add to
_document.tsxorlayout.tsxvia<Script> - Vue/Nuxt — add to
nuxt.config.tshead.scriptorapp.vue - Astro — add to
Layout.astro<head>
Your agent reads the data instead of you opening a dashboard:
# Point CLI at your instance
npx @agent-analytics/cli login --token your-secret-read-key --url https://your-server.com
# Query
npx @agent-analytics/cli stats my-site # Last 7 days
npx @agent-analytics/cli stats my-site --days 30 # Last 30 days
npx @agent-analytics/cli events my-site # Recent events
npx @agent-analytics/cli projects # List all projectsYour agent turns that into: "4,821 pageviews from 1,203 unique visitors this week, up 23% from last week. 127 signup clicks at 2.6% conversion."
Everything you can do with the API, you can do with npx @agent-analytics/cli:
# Auth
npx @agent-analytics/cli login --token YOUR_KEY --url https://your-server.com
npx @agent-analytics/cli whoami # Show current account
# Projects
npx @agent-analytics/cli create my-site --domain https://mysite.com # Create + get snippet & token
npx @agent-analytics/cli projects # List all projects
npx @agent-analytics/cli delete <project-id> # Delete a project
# Query (your agent runs these)
npx @agent-analytics/cli stats my-site # Last 7 days overview
npx @agent-analytics/cli stats my-site --days 30 # Custom period
npx @agent-analytics/cli events my-site # Recent raw events
npx @agent-analytics/cli events my-site --days 30 --limit 50 # With filters
# Account
npx @agent-analytics/cli revoke-key # Revoke + regenerate API keyEnvironment variables:
AGENT_ANALYTICS_API_KEY— API key (overrides config file)AGENT_ANALYTICS_URL— Custom API URL (for self-hosted instances)
npm: https://www.npmjs.com/package/@agent-analytics/cli
Everything the CLI does is also available as HTTP endpoints. Use X-API-Key header or ?key= param for auth.
Two types of keys — same model as Mixpanel:
| Key | Purpose | Visibility | Used by |
|---|---|---|---|
Project Token (pt_...) |
Identifies which project events belong to | Public (embedded in JS snippet) | tracker.js, /track |
| API Key | Read access to query stats | Private (keep secret) | CLI, /stats, /events, /query |
Called automatically by tracker.js on your site. You don't need to call this manually.
curl -X POST "https://your-server.com/track" \
-H "Content-Type: application/json" \
-d '{
"project": "my-site",
"token": "pt_your_token",
"event": "page_view",
"properties": { "page": "/home", "browser": "chrome" },
"user_id": "user_123"
}'| Field | Required | Description |
|---|---|---|
project |
Yes | Project identifier |
token |
Yes* | Project token (*optional if PROJECT_TOKENS not set on server) |
event |
Yes | Event name |
properties |
Arbitrary JSON | |
user_id |
User identifier | |
timestamp |
Unix ms (defaults to now) |
Each event carries its own project field. Auth token is at the top level.
curl -X POST "https://your-server.com/track/batch" \
-H "Content-Type: application/json" \
-d '{
"token": "pt_your_token",
"events": [
{ "project": "my-site", "event": "click", "user_id": "u1" },
{ "project": "my-site", "event": "scroll", "user_id": "u2" }
]
}'| Field | Required | Description |
|---|---|---|
token |
Yes* | Project token (*optional if PROJECT_TOKENS not set) |
events |
Yes | Array of event objects (max 100) |
events[].project |
Yes | Project identifier (per event) |
events[].event |
Yes | Event name |
events[].properties |
Arbitrary JSON | |
events[].user_id |
User identifier | |
events[].timestamp |
Unix ms (defaults to now) |
npx @agent-analytics/cli stats my-site --days 7curl equivalent
curl "https://your-server.com/stats?project=my-site&days=7" \
-H "X-API-Key: YOUR_API_KEY"Returns daily breakdown (unique users + total events), top events by count, and period totals.
{
"project": "my-site",
"period": { "from": "2026-02-01", "to": "2026-02-07", "days": 7 },
"totals": { "unique_users": 1203, "total_events": 4821 },
"daily": [{ "date": "2026-02-07", "unique_users": 187, "total_events": 712 }],
"events": [
{ "event": "page_view", "count": 3920 },
{ "event": "signup_click", "count": 127 }
]
}npx @agent-analytics/cli events my-site --event page_view --days 7 --limit 100curl equivalent
curl "https://your-server.com/events?project=my-site&event=page_view&days=7&limit=100" \
-H "X-API-Key: YOUR_API_KEY"The power endpoint. Supports metrics, grouping, filtering, and sorting.
curl -X POST "https://your-server.com/query" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project": "my-site",
"metrics": ["event_count", "unique_users"],
"group_by": ["event", "date"],
"filters": [
{ "field": "event", "op": "eq", "value": "page_view" },
{ "field": "properties.browser", "op": "eq", "value": "chrome" }
],
"date_from": "2026-01-01",
"date_to": "2026-01-31",
"order_by": "event_count",
"order": "desc",
"limit": 50
}'| Parameter | Description |
|---|---|
metrics |
event_count, unique_users |
group_by |
event, date, user_id |
filters[].op |
eq, neq, gt, lt, gte, lte |
filters[].field |
event, user_id, date, or properties.* for JSON property filters |
order_by |
Any metric or group_by field |
limit |
Max 1000 rows (default: 100) |
curl "https://your-server.com/properties?project=my-site&days=30" \
-H "X-API-Key: YOUR_API_KEY"Returns event names with counts, first/last seen dates, and all known property keys. Useful for building dynamic queries.
| Endpoint | Description |
|---|---|
GET /health |
{ "status": "ok", "service": "agent-analytics" } |
GET /tracker.js |
Client-side tracking script (see Add Tracking) |
flowchart TB
subgraph Clients
website["Your Website<br/><small>tracker.js auto-tracks page views</small>"]
agent["AI Agent / CLI<br/><small>npx @agent-analytics/cli stats ...</small>"]
end
subgraph Server ["Server (this repo)"]
auth["auth.js<br/><small>Token + API key validation</small>"]
cf["platforms/cloudflare.js<br/><small>CF Worker + D1Adapter</small>"]
node["platforms/node.js<br/><small>Node.js HTTP + SQLite</small>"]
end
subgraph Core ["@agent-analytics/core"]
handler["createAnalyticsHandler()<br/><small>Platform-agnostic routing</small>"]
d1["D1Adapter<br/><small>Cloudflare D1 queries</small>"]
tracker["tracker.js<br/><small>Client-side tracking script</small>"]
helpers["Date helpers, property validation"]
end
website -- "POST /track" --> auth
agent -- "GET /stats · POST /query" --> auth
auth --> cf & node
cf --> handler
node --> handler
cf -.-> d1
node -.-> sqlite[("SQLite")]
handler --> d1 & tracker & helpers
@agent-analytics/core does the heavy lifting — it exports createAnalyticsHandler({ db, validateWrite, validateRead }), a platform-agnostic request handler. This repo plugs in the auth layer and platform glue: Cloudflare Workers with D1, or Node.js with SQLite. Add a new platform by providing a database adapter and calling the handler factory.
src/ (this repo — platform glue + auth)
auth.js — Token + API key validation (constant-time compare)
db/
sqlite.js — better-sqlite3 adapter (self-host)
platforms/
cloudflare.js — CF Worker entry (D1Adapter + ctx.waitUntil)
node.js — Node.js HTTP server entry
@agent-analytics/core (npm dependency — does the heavy lifting)
src/
handler.js — Platform-agnostic request routing + response building
db/
adapter.js — Date helpers, shared query logic
d1.js — Cloudflare D1 adapter (D1Adapter, validatePropertyKey)
tracker.js — Client-side tracking script (served at GET /tracker.js)
ulid.js — ULID generation for event IDs
Don't want to self-host? Agent Analytics Cloud gives you the same API with zero infrastructure — sign in, get your keys, start tracking.
MIT