Todo Playground API

A small shared engine exposed through REST and hosted HTTP MCP for LLM clients.

Run The Server

The hosted service uses a simple bearer token for the toy demo. Set TODO_API_TOKEN before launch, or omit it to use the development token shown below.

export TODO_API_TOKEN="todo-user-token"
cabal run todo-rest
Base URL
https://api.badbank.ai
Auth header
Authorization: Bearer todo-user-token

REST Authentication

Every /api/v1 route requires the bearer token. Public install artifacts and this page do not require a token.

curl -s https://api.badbank.ai/api/v1/whoami \
  -H "Authorization: Bearer todo-user-token"

curl -s -X POST https://api.badbank.ai/api/v1/tasks \
  -H "Authorization: Bearer todo-user-token" \
  -H "Content-Type: application/json" \
  -d '{"title":"wire engine to LLM client"}'

Auth And Entitlement Modes

The toy can run in dev-bearer, workspace-token, clerk-toy-token, and real clerk-jwt modes. Stripe is modeled as an entitlement allowlist so you can test the gate before wiring the Stripe API.

# toy shared-token mode
TODO_AUTH_MODE=dev-bearer TODO_API_TOKEN=dev-token cabal run todo-rest

# Clerk-shaped boundary test mode
TODO_AUTH_MODE=clerk-toy-token \
TODO_CLERK_ALLOWED_ORIGINS=http://localhost:3000 \
cabal run todo-rest

# real Clerk JWT verification
TODO_AUTH_MODE=clerk-jwt \
TODO_CLERK_ISSUER=https://pleased-kiwi-28.clerk.accounts.dev \
TODO_CLERK_ALLOWED_ORIGINS=http://localhost:3000 \
CLERK_JWKS_JSON="$(curl -s https://pleased-kiwi-28.clerk.accounts.dev/.well-known/jwks.json)" \
cabal run todo-rest

# Stripe-shaped entitlement gate
TODO_STRIPE_ENTITLEMENTS=allowlist \
TODO_STRIPE_ALLOWED_WORKSPACES=workspace_123 \
cabal run todo-rest

Install As An OpenAPI Plugin

Use the OpenAPI URL in clients that can import an action, tool, or plugin from an OpenAPI document. Choose bearer authentication and paste the same token used by the server.

Manifest
https://api.badbank.ai/.well-known/ai-plugin.json
OpenAPI
https://api.badbank.ai/openapi.json
Auth type
HTTP bearer token

Install Hosted HTTP MCP

The MCP server is exposed over the same HTTPS origin as REST. Codex uses an environment variable for the bearer token; Claude Code installs the same URL with an Authorization header.

MCP URL
https://mcp.badbank.ai/mcp
Token env
TODO_MCP_TOKEN
export TODO_MCP_TOKEN="todo-user-token"
codex mcp add todo-playground --url https://mcp.badbank.ai/mcp --bearer-token-env-var TODO_MCP_TOKEN
export TODO_MCP_TOKEN="todo-user-token"
claude mcp add --transport http todo-playground https://mcp.badbank.ai/mcp --header "Authorization: Bearer $TODO_MCP_TOKEN"

Download Install Pill

Download the install pill, then ask Codex or Claude Code to use it. In this hosted toy the pill deliberately contains the demo user token.

Download todo-codex-pill.json

Download todo-claude-pill.json

export TODO_MCP_TOKEN="todo-user-token"
codex mcp add todo-playground --url https://mcp.badbank.ai/mcp --bearer-token-env-var TODO_MCP_TOKEN

Optional Plugin Layer

The clean demo does not require a plugin install. Claude Code connects directly to the hosted MCP endpoint; slash commands and workflow skills can be published later as a Git or hosted marketplace plugin that points at the same MCP URL.

Install With Codex

Use the Codex install page to generate a single JSON package containing the OpenAPI URL, bearer token, MCP config, and first test request.

Install page
https://api.badbank.ai/codex-install.html
Pill template
https://api.badbank.ai/codex-pill.json

Build Offline Artifacts

The plugin builder writes the same manifest, OpenAPI document, install page, MCP config, and logo to a directory for hosting or inspection.

cabal run todo-plugin-builder -- \
  --base-url https://api.badbank.ai \
  --mcp-url https://mcp.badbank.ai/mcp \
  --out plugin-dist

Next Integration Pass

Clerk JWT verification is wired at the REST boundary. The next pass should connect the React/Next Clerk session flow, resolve users and organizations to local workspaces, and replace the allowlist with real Stripe entitlement checks before dispatching to the service layer.