| name | mupot-operator |
| description | Operator knowledge for mupot — the Cloudflare-native agent substrate. Covers provisioning a new pot, understanding org/RBAC/board/memory concepts, enabling the DMN brain, and avoiding known pitfalls (migration drift, token scope, cron symlink failure). Load when a user wants to set up, operate, or troubleshoot mupot.
|
| version | 0.2.0 |
| required_environment_variables | ["MUPOT_CF_ACCOUNT_ID","MUPOT_CF_API_TOKEN"] |
| optional_environment_variables | ["MUPOT_SLUG","MUPOT_BRAND","MUPOT_OAUTH_PROVIDER"] |
| tools | ["mupot_provision","mupot_status","mupot_brain_enable"] |
| companion_skills | ["cloudflare/skills"] |
mupot Operator Skill
v0.2 ships the real CF provisioner. mupot_provision with confirm=True, dry_run=False
calls the Cloudflare API directly (pure stdlib urllib) to create D1 databases and KV
namespaces, then writes wrangler.<slug>.toml with resolved IDs. Default (dry_run=True)
emits a plan without touching Cloudflare. Requires MUPOT_CF_API_TOKEN and
MUPOT_CF_ACCOUNT_ID in the environment for apply mode.
What mupot is
mupot is a Cloudflare-native sovereign agent substrate — org, RBAC, board, memory, and
bus in a single Cloudflare Worker. Each user owns their own instance (their own D1, KV,
Workers slot) under their own Cloudflare account. No Mumega server sees your data.
Core concepts:
- Pot — one mupot deployment = one Cloudflare Worker (
mupot-<slug>.workers.dev)
- Org — your organisation, with members, roles, and capability grants
- Board — task board (work units, gates, done_when predicates)
- Memory — D1 relational + Vectorize semantic recall (Vectorize deferred to v0.2)
- Brain — an optional always-on DMN prioritiser (qwen3.7-plus via OpenRouter, free tier)
Provision flow (v0.2 — real CF provisioner)
Prerequisites:
- A Cloudflare account (free tier is sufficient for a single pot)
- A scoped CF API token — minimum permissions: Workers Scripts:Edit, D1:Edit,
Workers KV Storage:Edit, Account Settings:Read
MUPOT_CF_ACCOUNT_ID and MUPOT_CF_API_TOKEN set in your environment
Step 1 — Get the plan (dry-run, default):
mupot_provision(slug="acme", brand="Acme Corp", cf_account_id="...", cf_api_token="...")
# Returns a plan showing what will be created. confirm defaults to False (dry-run).
# No CF API calls are made in dry-run mode.
Step 2 — Review the plan. The idempotent list-guard shows which D1/KV resources
already exist (SKIP) and which will be created (CREATE).
Step 3 — Apply (v0.2):
mupot_provision(
slug="acme", brand="Acme Corp", cf_account_id="...", cf_api_token="...",
confirm=True, dry_run=False
)
# Calls the CF REST API to create D1 + KV namespaces (skips any that already exist),
# then writes wrangler.acme.toml with the resolved resource IDs.
# Requires MUPOT_CF_API_TOKEN + MUPOT_CF_ACCOUNT_ID in the environment.
Step 4 — Deploy + migrate (follow next_steps exactly):
node scripts/deploy.mjs --config wrangler.acme.toml
npx wrangler d1 migrations apply mupot-acme --dry-run --config wrangler.acme.toml
npx wrangler d1 migrations apply mupot-acme --config wrangler.acme.toml
npx wrangler secret put OAUTH_CLIENT_ID --config wrangler.acme.toml
npx wrangler secret put OAUTH_CLIENT_SECRET --config wrangler.acme.toml
Step 5 — Verify:
mupot_status(url="https://mupot-acme.workers.dev")
# Returns {ok: true, tenant: "acme", url: "https://mupot-acme.workers.dev"}
Brain enable
The brain is an optional always-on DMN (Default Mode Network) prioritiser — a cheap
qwen3.7-plus Hermes session that scans your board every 15 minutes and ranks work.
mupot_brain_enable(slug="acme")
# Returns a plan with: config.yaml content, cron script content, cron entry, next_steps.
# Follow the next_steps to write the files and register the cron.
Then follow the next_steps in the result:
- Create
~/.hermes/profiles/mupot-acme-brain/config.yaml
- Write the cron script as a real file (not a symlink — see Pitfall 3)
- Register the cron entry in
~/.hermes/cron/jobs.json
- Set
MUMEGA_BRAIN_TOKEN_ACME to a scoped token (task:read + priority:write only)
— operator's responsibility: the plugin documents this requirement but cannot
enforce token scope (no token introspection available in the cron context)
- Hermes hotloads cron config without daemon restart
Pitfalls
Pitfall 1 — CF token on disk (Risk 1)
Your MUPOT_CF_API_TOKEN lives in Hermes .env.secrets in plaintext.
Mitigate: use the minimum-scope token (5 permission groups, not Edit-All). After
provisioning, consider rotating the token in the CF dashboard. CF OAuth (one-click, no
token on disk) is coming once Mumega's OAuth app passes CF public vetting.
Pitfall 2 — Migration drift landmine (Risk 2)
NEVER run npx wrangler d1 migrations apply --remote without --dry-run first.
The digid tenant learned this the hard way (migration 0026 → member_tokens table was
rebuilt OOB, live data in the way). IF NOT EXISTS does not protect you from future
destructive operations. Always:
--dry-run → read every line of output
- Only apply if you see no DROP, no destructive ALTER
Pitfall 3 — Cron symlink failure (Risk: silent non-execution)
Hermes cron scheduler reads the script path directly. A symlink to a missing target causes
a silent non-execution — no error, no log, the brain simply never runs. Always write
a real file for the cron script. mupot_brain_enable outputs a real-file template.
Pitfall 4 — Brain token scope (Risk 3 — operator responsibility)
MUMEGA_BRAIN_TOKEN_<SLUG> must carry ONLY task:read + priority:write.
Using mcp:* would grant full bus control to an always-on automated agent.
The cron script checks that the token is SET, but cannot verify its scope. The
Mumega bus does not expose token introspection to the cron context. The operator must
supply the correctly-scoped token — this is documented but not enforced by the plugin.
Pitfall 5 — Workers free-tier slot (Risk 5)
Each pot = one Workers slot. Free tier = 100 slots. If you're near the limit, the
mupot_provision tool will warn you. Workers-for-Platforms centralisation is explicitly
rejected (it breaks pot sovereignty) — each user must stay within their own slot budget.
v0.2 scope / deferred
In v0.2 (real CF provisioner):
- Real apply: CF REST API via pure stdlib urllib (no extra deps), idempotent D1 + KV creation
- Paginated list-guard: fetches all pages before create (no double-create on accounts with >100 resources)
wrangler.<slug>.toml written with resolved D1 + KV IDs after apply
- Optional stamped deploy via
scripts/deploy.mjs subprocess (version-check gate; token never in argv)
- Token security: never in argv, repr, error messages, or toml output
- Brain profile + cron plan emission
- Deploy-to-Cloudflare button (README)
Deferred to v0.3+:
- CF OAuth one-click (pending Mumega OAuth app public approval)
- Full SDK provisioner (no wrangler dep):
client.workers.scripts.update()
- OAuth secret automation (guided prompt + CF secrets API)
- R2 / Vectorize / Queues provisioning (add via re-run)
mupot_revoke_token post-provision (needs token ID stored at mint time)
pot_registry / pot_owners D1 migrations for the "Your Pots" console (G4)
hermes plugins install Mumega-com/mupot-plugin standalone repo (publish-time step)