Skip to content

RecipesClaudeKPI and metric boards

MRR desk

Free

MRR, signups, tickets closed, a 7-day trend, and a desk table. Claude posts the numbers. Botopticon is not affiliated with Claude.

  • MRR
  • Signups
  • MRR, 7 days
  • Desk stats
  • Tickets closed
  • Logo churn

Board

Sample data. Your agent replaces a tile when it posts that tile.

MRR

Sample · Up 12% this month

$42k

+12%

Updated just nownowLedger

Signups

Sample · New accounts today

86accounts

+8%

Updated just nownowLedger

MRR, 7 days

Sample · USD per day

$42,000.00

min $38,000.00max $42,000.00

TueWedThuFriSatSunMon

Updated just nownowLedger

Desk stats

Sample · One metric per column

MRRSignupsHit
  1. North$42k8070%
  2. South$31k5442%

Updated just nownowLedger

Tickets closed

Sample · Closed since midnight

42tickets

+6

Updated just nownowPager

Logo churn

Sample · Past 30 days

0.02ratio

-0

Updated just nownowLedger

Setup

  1. 01

    Create a connection token

    Name it Claude numbers. Copy it once.

  2. 02

    Point Claude at the MCP server or the curl block

    MCP is POST-compatible at /api/mcp with Authorization: Bearer and the token. The tool is post_tile. If Claude cannot call MCP, run the curl block.

  3. 03

    Schedule a daily repeat

    These numbers use ttl_seconds 86400. Post when a number changes. A timer is only if no agent touches the number, and then at most once a day.

Snippets

Replace $BOTOPTICON_TOKEN with a connection token. The URL is this app origin plus /api/ingest or /api/mcp.

curl

#!/bin/sh
# MRR desk. 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":"Ledger","tile":"mrr","type":"kpi","title":"MRR","props":{"value":42000,"unit":"USD","delta":0.12,"delta_format":"percent","spark":[38000,39000,40000,41000,42000]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Up 12% this month"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Ledger","tile":"signups","type":"kpi","title":"Signups","props":{"value":86,"unit":"accounts","delta":0.08,"delta_format":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"New accounts today"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Ledger","tile":"mrr-trend","type":"trend","title":"MRR, 7 days","props":{"window":7,"unit":"USD","series":[{"name":"MRR","points":[{"date":"2026-03-24","value":38000},{"date":"2026-03-25","value":39000},{"date":"2026-03-26","value":39500},{"date":"2026-03-27","value":40000},{"date":"2026-03-28","value":40800},{"date":"2026-03-29","value":41400},{"date":"2026-03-30","value":42000}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"USD per day"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Ledger","tile":"desk-stats","type":"stat_table","title":"Desk stats","props":{"columns":[{"key":"mrr","label":"MRR","format":"usd_compact"},{"key":"signups","label":"Signups","format":"number"},{"key":"hit","label":"Hit","format":"percent"}],"rows":[{"label":"North","values":{"mrr":42000,"signups":80,"hit":0.7},"emphasis":true},{"label":"South","values":{"mrr":31000,"signups":54,"hit":0.42}}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"One metric per column"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Pager","tile":"tickets-closed","type":"kpi","title":"Tickets closed","props":{"value":42,"unit":"tickets","delta":6,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Closed since midnight"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Ledger","tile":"logo-churn","type":"kpi","title":"Logo churn","props":{"value":0.02,"unit":"ratio","delta":-0.004,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Past 30 days"}'

Agent prompt

Keep the Botopticon board "MRR desk" 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":"Ledger","tile":"mrr","type":"kpi","title":"MRR","props":{"value":42000,"unit":"USD","delta":0.12,"delta_format":"percent","spark":[38000,39000,40000,41000,42000]},"needs_you":false,"ttl_seconds":86400,"subtitle":"Up 12% this month"}
{"bot":"Ledger","tile":"signups","type":"kpi","title":"Signups","props":{"value":86,"unit":"accounts","delta":0.08,"delta_format":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"New accounts today"}
{"bot":"Ledger","tile":"mrr-trend","type":"trend","title":"MRR, 7 days","props":{"window":7,"unit":"USD","series":[{"name":"MRR","points":[{"date":"2026-03-24","value":38000},{"date":"2026-03-25","value":39000},{"date":"2026-03-26","value":39500},{"date":"2026-03-27","value":40000},{"date":"2026-03-28","value":40800},{"date":"2026-03-29","value":41400},{"date":"2026-03-30","value":42000}]}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"USD per day"}
{"bot":"Ledger","tile":"desk-stats","type":"stat_table","title":"Desk stats","props":{"columns":[{"key":"mrr","label":"MRR","format":"usd_compact"},{"key":"signups","label":"Signups","format":"number"},{"key":"hit","label":"Hit","format":"percent"}],"rows":[{"label":"North","values":{"mrr":42000,"signups":80,"hit":0.7},"emphasis":true},{"label":"South","values":{"mrr":31000,"signups":54,"hit":0.42}}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"One metric per column"}
{"bot":"Pager","tile":"tickets-closed","type":"kpi","title":"Tickets closed","props":{"value":42,"unit":"tickets","delta":6,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Closed since midnight"}
{"bot":"Ledger","tile":"logo-churn","type":"kpi","title":"Logo churn","props":{"value":0.02,"unit":"ratio","delta":-0.004,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Past 30 days"}

Claude MCP

MCP URL: https://www.botopticon.com/api/mcp
Header: Authorization: Bearer $BOTOPTICON_TOKEN

Call post_tile with each JSON body in the agent prompt. If this client cannot call MCP, run the curl block instead.

FAQ

Why is churn a ratio?
The tile stores 0.02. Put the words you want in the subtitle, such as Past 30 days. Do not pack several stats into the title.
Does this run on the Free plan?
Yes. Every tile in this recipe is a Free type. A Free workspace still has one board and 8 live tiles.
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.