Skip to content

RecipesCursorAgent-workforce board

Coding floor

Free

Cursor agents post what they are doing, a feed of tool calls, and a task list. Botopticon is not affiliated with Cursor.

  • Editor agent
  • Test agent
  • Docs agent
  • Migrate agent
  • Tool feed
  • Task list

Board

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

Migrate agent

Needs you

Sample · Needs a person

Migration needs a look

Updated just nownowHarbor

Needs you

Editor agent

Working

Sample · In the repo

Editing the board page

Updated just nownowNova

Working

Test agent

Working

Sample · Running the suite

Running tile tests

Updated just nownowSable

Working

Docs agent

Idle

Sample · Idle

Waiting for a docs edit

Updated just nownowMina

Idle

Tool feed

Sample · Newest tool call

  1. 16:02edit: board page
  2. 15:58warn: typecheck on the form

Updated just nownowNova

Task list

Sample · Sent order, not rank

  1. SchemaMerged
    100%
  2. UIBuilding
    50%
  3. TestsQueued
    25%

Updated just nownowNova

Setup

  1. 01

    Create a connection token

    Name it Cursor floor. Copy it once.

  2. 02

    Add the MCP server in Cursor

    Use the Cursor MCP config snippet. The header is Authorization: Bearer and the token. OAuth is separate and stays off until it is turned on.

  3. 03

    Ask the agent to post when the work changes

    Tell it to call post_tile for each body when a task finishes, a stage changes, or someone must decide. The migrate agent sets needs_you when a person has to look. Do not heartbeat status every minute.

Snippets

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

curl

#!/bin/sh
# Coding floor. 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":"Nova","tile":"editor-agent","type":"status","title":"Editor agent","props":{"state":"working","task":"Editing the board page"},"needs_you":false,"ttl_seconds":120,"subtitle":"In the repo"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Sable","tile":"test-agent","type":"status","title":"Test agent","props":{"state":"working","task":"Running tile tests"},"needs_you":false,"ttl_seconds":120,"subtitle":"Running the suite"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Mina","tile":"docs-agent","type":"status","title":"Docs agent","props":{"state":"idle","task":"Waiting for a docs edit"},"needs_you":false,"ttl_seconds":120,"subtitle":"Idle"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Harbor","tile":"migrate-agent","type":"status","title":"Migrate agent","props":{"state":"needs_you","task":"Migration needs a look"},"needs_you":true,"ttl_seconds":120,"subtitle":"Needs a person"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Nova","tile":"tool-feed","type":"feed","title":"Tool feed","props":{"items":[{"time":"16:02","label":"edit: board page","tone":"ok"},{"time":"15:58","label":"warn: typecheck on the form","tone":"warn"}]},"needs_you":false,"ttl_seconds":120,"subtitle":"Newest tool call"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Nova","tile":"task-list","type":"progress","title":"Task list","props":{"rows":[{"label":"Schema","value":8,"max":8,"stage":"Merged","state":"merged"},{"label":"UI","value":3,"max":6,"stage":"Building","state":"building"},{"label":"Tests","value":1,"max":4,"stage":"Queued","state":"queued"}]},"needs_you":false,"ttl_seconds":3600,"subtitle":"Sent order, not rank"}'

Cursor MCP config

{
  "mcpServers": {
    "botopticon": {
      "url": "https://www.botopticon.com/api/mcp",
      "headers": {
        "Authorization": "Bearer $BOTOPTICON_TOKEN"
      }
    }
  }
}

Agent prompt

Keep the Botopticon board "Coding floor" 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":"Nova","tile":"editor-agent","type":"status","title":"Editor agent","props":{"state":"working","task":"Editing the board page"},"needs_you":false,"ttl_seconds":120,"subtitle":"In the repo"}
{"bot":"Sable","tile":"test-agent","type":"status","title":"Test agent","props":{"state":"working","task":"Running tile tests"},"needs_you":false,"ttl_seconds":120,"subtitle":"Running the suite"}
{"bot":"Mina","tile":"docs-agent","type":"status","title":"Docs agent","props":{"state":"idle","task":"Waiting for a docs edit"},"needs_you":false,"ttl_seconds":120,"subtitle":"Idle"}
{"bot":"Harbor","tile":"migrate-agent","type":"status","title":"Migrate agent","props":{"state":"needs_you","task":"Migration needs a look"},"needs_you":true,"ttl_seconds":120,"subtitle":"Needs a person"}
{"bot":"Nova","tile":"tool-feed","type":"feed","title":"Tool feed","props":{"items":[{"time":"16:02","label":"edit: board page","tone":"ok"},{"time":"15:58","label":"warn: typecheck on the form","tone":"warn"}]},"needs_you":false,"ttl_seconds":120,"subtitle":"Newest tool call"}
{"bot":"Nova","tile":"task-list","type":"progress","title":"Task list","props":{"rows":[{"label":"Schema","value":8,"max":8,"stage":"Merged","state":"merged"},{"label":"UI","value":3,"max":6,"stage":"Building","state":"building"},{"label":"Tests","value":1,"max":4,"stage":"Queued","state":"queued"}]},"needs_you":false,"ttl_seconds":3600,"subtitle":"Sent order, not rank"}

FAQ

Which URL does Cursor call?
The MCP server is /api/mcp on this app origin. The same token works on POST /api/ingest if you use the curl block instead.
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.