decision-server
Provides an MCP server deployed as a Cloudflare Worker that integrates with Cloudflare Workers AI (Clef models for decision calls), AI Gateway (spend-limit budget management), Cloudflare Access (authentication), and D1 (storage for OAuth tokens and call logs). It routes decision calls to free Workers AI models and falls back to Jev when needed.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@decision-servershould we launch the new pricing page today or wait until Monday?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
decision-server
A Cloudflare Worker that answers Jev-format decision calls ({model, state, questions}) on free Workers AI Clef models first (clef-flash, clef, clef-omni) and falls back to Jev when the free budget is gone, a model fails, or the question is too important to risk. REST plus a stateless remote MCP server.
POST /v1/systemone Jev-compatible; adds servedBy, routeReason, neurons, ms
GET /v1/budget today's usage, spend-limit/quota errors, skip-Clef flag
GET /v1/stats mix, fallbacks, p50/p90 per tier, free %, shadow disagreement
GET /v1/calls call log with full payloads
POST /mcp tools: decide, budget, stats, recent_calls
GET /health needs auth (see below)
GET /visualize dashboard (Access login)Auth
The whole host sits behind Cloudflare Access, and the Worker checks credentials itself. Three ways in:
Decision key (machines):
Authorization: Bearer $DECISIONS_TOKENworks on every route.Cloudflare Access login (browser):
/,/health,/visualizeand/v1/*accept a valid Access JWT (Cf-Access-Jwt-Assertionheader orCF_Authorizationcookie), verified againsthttps://$ACCESS_TEAM_DOMAIN/cdn-cgi/access/certs(RS256,iss,aud=ACCESS_AUD). IfACCESS_AUDis empty or stillREPLACE_WITH_ACCESS_AUD, this path is off and only the decision key works.MCP OAuth (
/mcponly): the server is its own OAuth authorization server (dynamic client registration, PKCE S256)./oauth/authorizerequires the Access login, so approving a client means logging in. Access and refresh tokens are opaque, hashed in D1 (migration0002_oauth.sql); access tokens last 1h, refresh tokens 30 days and rotate. They are rejected on/v1/*.
Set up Access once: OWNER_EMAIL=you@example.com bash scripts/setup-access.sh creates the owner-only whole-host app plus a Bypass app for /v1, /mcp, /oauth/token, /oauth/register and /.well-known, and prints the ACCESS_AUD to put in cloudflare.config.ts. No new secrets; just apply the D1 migration before deploying.
Related MCP server: jevx-mcp
How a call is routed
Forced
model(flash/clef/omni/jev) wins.Embedded image/audio/video in
stategoes toclef-omni.A skip-Clef flag (set by a gateway spend-limit error, code 2041, for 15 min, or a Workers AI free-quota error, 4006, until 00:00 UTC) goes straight to Jev.
X-Decisionin the static table (src/routes.ts) picks flash or clef; "either" types run flash and escalate to clef when answers are ambiguous.Unknown decision types ask
clef-flashwhich tier fits.
Any Clef error, timeout, or incomplete answer falls back to Jev within the request deadline (X-Deadline-Ms, default 3800). If Jev fails too the server returns 502 (or 504 on deadline). It never invents answers.
Budget. Clef calls go through the AI Gateway named by AI_GATEWAY_ID (default default). That gateway's spend-limit rules are the budget, and there's no counter in the server. If other tools share the gateway, they share its limit: when one trips it, the server falls back to Jev, and the other tools are locked out until it resets. On a Workers Paid plan with no gateway rule, usage past the free 10k neurons is billed at $0.011 per 1,000 instead of returning an error.
Issues. Workers Issues is enabled (observability.issues). Hitting the spend limit or free quota only logs a console.warn. When the gateway limit blocks Clef and Jev also fails (or its circuit is open), the server logs BothDownError ("both-down: clef spend-limit + jev unavailable") via console.error, whether the paid emergency Clef call rescued the request or a 502/504 was returned. A tripped Jev circuit breaker logs JevCircuitOpenError. Messages are fixed so occurrences group into one Issue each; details (status, decision, tier) are attached as the second argument.
Media. Embedded media goes only to clef-omni. On a Jev fallback the top-level images/audio/videos arrays are dropped, because Jev's API has no media fields. Calls with media are never shadowed. Shadow. With SHADOW=on, free-served calls are also sent to Jev in the background, and both answers are stored in shadow_pairs for the agreement stats.
Setup
Uses the Cloudflare cf CLI (cloudflare.config.ts), with @cloudflare/vite-plugin (vite.config.ts) as the build backend.
bun install
cp .dev.vars.example .dev.vars # fill in DECISIONS_TOKEN (e.g. openssl rand -hex 32) and TYPESAFE_API_KEY
bun run typecheck # cf workers types && tsc
bun run test:run # vitest (not `bun test`, which is bun's own runner)
cf d1 create --name decisions-db # put the returned id in cloudflare.config.ts (DB binding)
export DECISIONS_DB_ID=<that id>
bun run db:migrate # cf d1 migrations apply "$DECISIONS_DB_ID"
# First deploy: the Worker doesn't exist yet, so its required secrets ship with the deploy.
bunx cf deploy --secrets-file .dev.vars # serves decisions.prashamhtrivedi.app
# Later rotations: cf workers secrets update <NAME> --worker decision-server --text "$VALUE"Deploys after that come from git (Workers Builds). Every push runs bun run typecheck && bun run test:run. On main it then runs bun run deploy to production. On any other branch it runs bun run preview (cf previews deploy), which publishes a Preview named after the branch. Previews share production's D1 and secrets.
Config (cloudflare.config.ts): AI_GATEWAY_ID (default default, every Clef call goes through that AI Gateway, so its spend-limit rules are the budget), SHADOW (on sends each free-served call to Jev too and stores both answers), RETENTION_DAYS (30; a daily cron purges older rows). AMBIGUITY_BAND (e.g. 0.3,0.85) can be added as a text binding to tune escalation.
Local dev: bun run dev (cf dev), bun run db:migrate:local.
Use it
curl -s -X POST "$DECISIONS_URL/v1/systemone" \
-H "Authorization: Bearer $DECISIONS_TOKEN" -H "Content-Type: application/json" \
-H "X-Decision: shell-safety" \
-d '{"model":"auto","state":{"command":"ls -la"},"questions":{"dangerous":{"type":"noul","instructions":"Could this destroy data?"}}}'
# MCP with OAuth (browser login via Access, no key stored):
claude mcp add --transport http decisions "$DECISIONS_URL/mcp"
# or with the decision key:
claude mcp add --transport http decisions "$DECISIONS_URL/mcp" --header "Authorization: Bearer $DECISIONS_TOKEN"Optional headers: X-Decision, X-Mode, X-Agent, X-Session, X-Deadline-Ms, X-Replay (tags the call as a replay and skips the live shadow). See docs/agent-setup-prompt.md for a paste-in agent setup.
Replay (agreement check)
DECISIONS_TOKEN=... bun scripts/replay.ts --limit 1000Reads logged calls locally from the harness jev.db, posts them with X-Replay: 1, and prints per-decision agreement with the logged Jev answers at the harness default thresholds. Nothing leaves your machine except calls to your own server.
Rollback
Redeploy the previous commit (git checkout <sha> && bun run deploy), or create a deployment of an older Worker version with cf workers deployments create. For the harness side, remove endpoint from ~/.jev-harness/config.json.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Decision Layer for AI Agents — 58+ tools, Advisor, MCP. Free key: POST /v1/register {}.
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Paid MCP tools behind one endpoint. Agents pay per call in USDC on Base via x402.
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables MCP clients to obtain typed Jev judgments (Choice, Score, and Noul answers) through the Vercel AI Gateway with a single API key, using nine deadline-aware tools and offline mock testing.9MIT
- AlicenseAqualityCmaintenanceEnables running Jev AI typed decisions from any MCP client, returning choices, scores, or yes/no with calibrated probabilities.36 npmMIT
- AlicenseNot gradedqualityBmaintenanceExposes bounded TypeSafe Jev/System One decision primitives as MCP tools, enabling agents to make choices, scores, yes/no judgments, and batched decisions over remote HTTPS with shared state.MIT
- FlicenseCqualityAmaintenanceEnables MCP-compatible AI agents to make decisions using JEV, execute local skills, and list available skills through MCP tools.51-