Built for AI agents
Let your AI agent manage your coffee money. FreeCoffee ships an MCP-compatible HTTP API — agents can create campaigns, fund them, and read the performance stats straight from the ledger.
Create campaigns
Publish a validated campaign array to the
live ad feed. Same feed contract the web app speaks: https-only click URLs, cpm clamped
0–100, deduped by id, capped at 20 campaigns.
POST /admin/feedGET /feed.json
Admin routes require a bearer token
(Authorization: Bearer …) — set it as an encrypted Worker secret, never in
the agent's prompt.
Read performance
Every amount is computed server-side from the served feed — the agent (and everyone else) sees the same numbers the ledger keeps.
GET /earnings/{deviceId}GET /health
The deviceId is the random UUID this browser already uses — no account, no email, no PII. See Profile to find yours.
Fund & settle
Top up campaign balance and settle payout rails from the agent, without opening a dashboard.
Phase 3 — planned
Honest note: payout-provider integration isn't built yet — no endpoint exists today, and this page won't pretend otherwise. Phase 3 wires the same ledger to a payment provider.
MCP-style tool manifest
Hand this to any MCP-capable client — Claude, OpenAI agents, Grok, OpenClaw and friends — as the tool description, and the agent can drive the FreeCoffee API directly.
{
"name": "freecoffee",
"description": "Menu-bar advertising on FreeCoffee — create campaigns, read earnings.",
"tools": [
{
"name": "freecoffee_publish_feed",
"description": "Replace the current ad feed with a validated campaign array (max 20).",
"inputSchema": {
"type": "object",
"properties": {
"campaigns": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "sponsor"],
"properties": {
"id": { "type": "string", "maxLength": 40 },
"sponsor": { "type": "string", "maxLength": 40 },
"tagline": { "type": "string", "maxLength": 90 },
"clickUrl": { "type": "string", "pattern": "^https://" },
"cpm": { "type": "number", "minimum": 0, "maximum": 100 },
"logoText": { "type": "string", "maxLength": 2 },
"accent": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" }
}
}
}
},
"required": ["campaigns"]
}
},
{
"name": "freecoffee_get_earnings",
"description": "Read the server-side earnings ledger for a device: totals, rows, counters.",
"inputSchema": {
"type": "object",
"properties": {
"deviceId": { "type": "string", "pattern": "^[a-f0-9-]{8,64}$" }
},
"required": ["deviceId"]
}
},
{
"name": "freecoffee_health",
"description": "Platform health check — returns { ok: true } when the API is up.",
"inputSchema": { "type": "object", "properties": {} }
}
]
}
Works with any MCP-capable client (Claude, OpenAI agents, Grok, OpenClaw…). This manifest is an illustrative shape for the HTTP API below — FreeCoffee doesn't ship a hosted MCP server yet.
curl examples
The same three capabilities over plain HTTP.
Point $BASE at your deployed Worker (see backend/README.md).
1 · Publish the feed (admin)
curl -X POST "$BASE/admin/feed" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"id": "camp_001",
"sponsor": "Acme Coffee Co.",
"tagline": "Single-origin beans — 20% off first bag",
"clickUrl": "https://advertiser.example/offer?utm_source=freecoffee",
"cpm": 6.0,
"logoText": "AC",
"accent": "#C98F4E"
}
]'
2 · Read earnings
curl "$BASE/earnings/$DEVICE_ID"
3 · Health check
curl "$BASE/health"
Demo documentation — the endpoints exist in
backend/src/worker.js; $BASE is your deployed Worker URL and
$ADMIN_TOKEN is a Worker secret, set via wrangler secret put.
The demo site itself is simulated data.