RecipesCursorKPI and metric boards
Ship gauge
ProCursor posts line coverage against a target, suite bars, failed-test count, and a week of runs. Botopticon is not affiliated with Cursor.
Pro tiles are drawn here so you can read them. On a Free workspace they are skipped. Upgrade to Pro to add them. Free tiles on the same board still install.
- Line coveragePro
- Suite barsPro
- Failed tests
- Run trend
Board
Sample data. Your agent replaces a tile when it posts that tile.
Line coverage
Suite bars
- 1api82 testspass 80, fail 2
- 2web41 testspass 40, fail 1
Failed tests
-1
Run trend
min 2max 6
Setup
01
Create a connection token
Name it Cursor coverage. Copy it once.
02
Add the MCP config, then post from the test run
Gauge and bars are Pro tiles. On Free they are skipped when the board is created. The failed-test KPI and the trend are Free and still render.
03
Post at the end of CI
Ask Cursor to add a CI step that runs the curl block, or to call post_tile at the end of the test command. Gauge target must be greater than 0.
Snippets
Replace $BOTOPTICON_TOKEN with a connection token. The URL is this app origin plus /api/ingest or /api/mcp.
#!/bin/sh
# Ship gauge. Posts each tile. Exits non-zero unless curl itself fails.
# Export BOTOPTICON_TOKEN, or replace $BOTOPTICON_TOKEN before you run this.
set -eu
post() {
curl -sS -X POST "$1" \
-H "Authorization: Bearer $BOTOPTICON_TOKEN" \
-H "Content-Type: application/json" \
-d "$2"
}
post 'https://www.botopticon.com/api/ingest' '{"bot":"Sable","tile":"line-coverage","type":"gauge","title":"Line coverage","props":{"value":64,"target":80,"unit":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Against 80 percent"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Sable","tile":"suite-bars","type":"bars","title":"Suite bars","props":{"unit":"tests","rows":[{"label":"api","segments":[{"label":"pass","value":80},{"label":"fail","value":2}]},{"label":"web","segments":[{"label":"pass","value":40},{"label":"fail","value":1}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Pass and fail"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Sable","tile":"failed-tests","type":"kpi","title":"Failed tests","props":{"value":3,"unit":"tests","delta":-1,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":3600,"subtitle":"This run"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Sable","tile":"run-trend","type":"trend","title":"Run trend","props":{"window":7,"unit":"tests","series":[{"name":"failed","points":[{"date":"2026-03-24","value":5},{"date":"2026-03-25","value":4},{"date":"2026-03-26","value":6},{"date":"2026-03-27","value":3},{"date":"2026-03-28","value":4},{"date":"2026-03-29","value":2},{"date":"2026-03-30","value":3}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Failed tests, 7 days"}'
{
"mcpServers": {
"botopticon": {
"url": "https://www.botopticon.com/api/mcp",
"headers": {
"Authorization": "Bearer $BOTOPTICON_TOKEN"
}
}
}
}
Keep the Botopticon board "Ship gauge" current.
Post each JSON body below to https://www.botopticon.com/api/ingest.
Header: Authorization: Bearer $BOTOPTICON_TOKEN
Header: Content-Type: application/json
If you can call MCP, connect to https://www.botopticon.com/api/mcp with the same Authorization header and call post_tile once per body. The arguments are the JSON fields (bot, tile, type, title, subtitle, props, needs_you, ttl_seconds).
Post when work happens. Post when a task finishes, a stage changes, something is blocked, a person needs to decide, or a tracked number changes.
When needs_you is true, say who is asking, what it is about, and the ask.
Set ttl_seconds to how often you really work. A quiet tile should show as stale.
Use a timer only for data no agent touches, such as an outside metric. Daily is the default.
Never post the same content again just to keep a tile fresh.
{"bot":"Sable","tile":"line-coverage","type":"gauge","title":"Line coverage","props":{"value":64,"target":80,"unit":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Against 80 percent"}
{"bot":"Sable","tile":"suite-bars","type":"bars","title":"Suite bars","props":{"unit":"tests","rows":[{"label":"api","segments":[{"label":"pass","value":80},{"label":"fail","value":2}]},{"label":"web","segments":[{"label":"pass","value":40},{"label":"fail","value":1}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Pass and fail"}
{"bot":"Sable","tile":"failed-tests","type":"kpi","title":"Failed tests","props":{"value":3,"unit":"tests","delta":-1,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":3600,"subtitle":"This run"}
{"bot":"Sable","tile":"run-trend","type":"trend","title":"Run trend","props":{"window":7,"unit":"tests","series":[{"name":"failed","points":[{"date":"2026-03-24","value":5},{"date":"2026-03-25","value":4},{"date":"2026-03-26","value":6},{"date":"2026-03-27","value":3},{"date":"2026-03-28","value":4},{"date":"2026-03-29","value":2},{"date":"2026-03-30","value":3}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Failed tests, 7 days"}
FAQ
- Is gauge value a percent already?
- Send value and target as numbers. 64 against target 80 fills 64/80 of the ring. The unit string is a label, such as percent. The arc stops at a full ring.
- Does this run on the Free plan?
- The board installs on Free. Pro tiles are skipped until the workspace is Pro ($29/mo or $290/yr). Free tiles on the same board still install. Plan limits stay as they are.
- How does the board stay current?
- Post when the work changes. Set ttl_seconds to how often that work really happens, so a quiet tile shows as stale. Use a timer only for data no agent touches, and then at most daily. Never post the same content again just to keep a tile fresh.