scrumer-cli
Command-line client + MCP server for scrumer. Covers the day-to-day app surface: teams (roster + invites), sprints, tasks (including agent verify/implement runs), a terminal board view, codebase scans, agent PR pipelines, CI runs, owner-only repository/log operations, MPoints, the team Key Vault, and support signals — all against the scrumer-api HTTP service using bearer-token auth.
Install (local)
From the repo root:
bun install
cd scrumer-cli && bun link # registers the `scrumer` bin
Requires Bun (the bin runs TypeScript directly via #!/usr/bin/env bun). For an npm-publishable Node build later: bun run build (bundles to dist/ with --target=node).
Login
scrumer login # prompts for email + password
scrumer login --email me@x.com --api-url http://localhost:8091
Login stores the session token (from the API's set-auth-token header) plus your default team in ~/.config/scrumer/config.json (0600). Env overrides: SCRUMER_TOKEN, SCRUMER_API_URL.
Note: accounts that only sign in with Google can't log in from the CLI yet — email/password only.
Commands
Global flags on every command: --team <idOrName>, --json, --api-url <url>.
scrumer whoami # GET /api/me
scrumer logout # revoke session + clear token
scrumer teams list
scrumer teams use <id|name> # set the default team
scrumer teams create "New Crew"
scrumer teams rename "Better Name" # owner only
scrumer teams delete <id> # owner only; cascades tasks/sprints/invites
scrumer teams members # roster (userId, name, email, role)
scrumer teams role <userId> editor|viewer # change a member's role (owner only)
scrumer teams remove <userId> # remove a member (owner) or leave (self)
scrumer teams invites list
scrumer teams invites create [--email me@x.com] # mint a 7-day invite link token
scrumer teams invites revoke <inviteId>
scrumer teams invites show <token> # preview before joining
scrumer teams invites accept <token> # join the team
scrumer sprints list
scrumer sprints create "Sprint 12" --goal "Ship v2" --starts 2026-07-14 --ends 2026-07-28
scrumer sprints update <id> --name "Sprint 12b"
scrumer sprints start <id>
scrumer sprints complete <id> # reports rolled-back task count
scrumer sprints delete <id> # tasks survive, sprint unset
scrumer tasks list [--status todo] [--sprint <id>] [--backlog] [--mine]
scrumer tasks create "Fix login bug" --type bug --priority p1 --desc "..."
scrumer tasks show <id>
scrumer tasks update <id> --status in_progress --assignee <userId>
scrumer tasks move <id> --status done # appends to bottom of column
scrumer tasks move <id> --status backlog # detaches from sprint too
scrumer tasks move <id> --status todo --sprint <sprintId>
scrumer tasks delete <id...> # 1 id = DELETE, many = batch
scrumer tasks verify <id> # enqueue a "verify now" fix-verification scan
scrumer tasks implement <id> [--base main] [--draft] [--instructions "..."]
# START a coding-agent run: implement + open PR
scrumer tasks cancel-pr <id> # cancel the in-flight implement run
scrumer board [--sprint <id>] # terminal board, columns from the team config
scrumer columns list # board column config (labels/order/visibility)
scrumer columns set in_review --label "Review" --position 3 --hide|--show
scrumer prs list [--active] [--task <id>] # agent PR runs, newest first
scrumer ci runs [--repo <owner/name>] [--limit 5] # recent CI pipeline runs
scrumer ci show <id> --repo <owner/name> [--logs] # one run + steps + logs
scrumer scans list [--purpose backlog|verify|custom] [--team-scans]
scrumer scans show <id> # poll while queued/active
scrumer scans report <id> [--kind report|result|map]
scrumer scans tickets <id> # parsed backlog-ticket proposals
scrumer scans import <id> --keys T-1,T-2 [--sprint <id>] [--no-monitoring]
scrumer scans run <owner/name> [--depth quick] [--instructions "..."] [--max-items 10]
# START a backlog-generation scan
scrumer points # my MPoints: total, per-kind, recent events
scrumer points leaderboard # team ranking
scrumer points claim <github-login> # credit my pushes/CI runs (first come, first served)
scrumer points unclaim
scrumer vault list [--project <owner/name>] [--env development|production]
scrumer vault search <query...> [--project ...] [--env ...] [--limit 20]
# fuzzy key finder — typo-tolerant ("stirpe key" finds STRIPE_KEY)
scrumer vault set NAME value --env development [--project <owner/name>] [--sensitive]
scrumer vault import .env --env production [--project <owner/name>] [--skip-empty] [--sensitive] [--dry-run]
# bulk-store a whole .env file (dotenv or Fly triple-quoted snapshots)
scrumer vault sensitive <id...> [--off] # owner-only: hide keys from editors (bulk); --off reverses
scrumer vault reveal <id> # plaintext value, explicit ask only
scrumer vault export --env production [--project <owner/name>] # dotenv text
scrumer vault delete <id>
scrumer signals send "message" [--reaction love|idea|broken|...] # direct line to the operator
scrumer signals log
Vault owners may create or replace same-scope keys and use all value/sensitivity commands. Editors may add unique, non-sensitive keys, but cannot replace, reveal, export, delete, or recover values after submission. Viewers have no vault access. Key-name uniqueness is scoped by team, environment, and project, so development/production and shared/project-specific entries may reuse names.
Backlog semantics mirror the web board: "in the backlog" = status backlog AND no sprint; moving to backlog always detaches the sprint; moves append to the bottom of the target column.
Write commands that start real agent/worker runs (tasks implement, tasks verify, scans run) do NOT ask for confirmation — they enqueue immediately.
MCP server
scrumer mcp # stdio MCP server
Registered for this repo in .cursor/mcp.json (server name scrumer, command scrumer mcp — requires bun link first). Auth comes from the config file or SCRUMER_TOKEN.
Tools (every team-scoped tool takes an optional teamId, defaulting to the configured team):
- Reads:
list_teams,list_sprints,list_tasks,get_task,get_board,list_pr_runs,list_ci_runs,get_ci_run,list_scans,get_scan,get_scan_report,get_scan_tickets,list_team_members,list_team_invites,get_my_points,get_points_leaderboard,list_vault_secrets(metadata only — values are CLI-only) - Owner-only operations reads:
list_team_repositories,list_log_subscriptions,get_log_findings,get_recent_logs. The API enforces the owner role server-side for both hosted OAuth and local stdio MCP clients; editors and viewers cannot call these tools. Provider credentials and ingest tokens are never returned. - Writes:
create_sprint,update_sprint,start_sprint,complete_sprint,delete_sprint,create_task,update_task,move_task,delete_tasks,import_scan_tickets,create_team_invite,revoke_team_invite - Agent actions (consequential; annotated so hosts ask first):
run_backlog_scan,verify_task,implement_task,cancel_task_pr
Hosted MCP (Claude and ChatGPT)
The production Streamable HTTP endpoint is:
https://scrumer.ai/mcp
It uses OAuth 2.1 authorization code + PKCE. Discovery, authorization, token,
dynamic registration, and JWKS URLs are all advertised on https://scrumer.ai;
the Fly backend domain is an implementation detail hidden behind the frontend
proxy. Every teammate connects separately, signs in to their own Scrumer
account, and approves scrumer:read and/or scrumer:write; tool calls retain
that user's existing team permissions. Access and refresh tokens are revocable;
JWT access tokens are resource-bound to the URL above, while opaque tokens are
accepted only by the MCP-scoped server path and API allowlist. The endpoint can list vault key metadata,
but it never exposes reveal, export, set, or delete operations and never returns
vault values.
Clients that send the RFC 8707 resource parameter receive a resource-bound
JWT access token. Clients that omit it may receive the OAuth provider's
revocable opaque access-token format; the hosted endpoint accepts both while
keeping CLI bearer-session tokens on their separate authentication path.
For Claude, an organization owner first enables custom connectors and adds the URL above in the organization's connector settings. Each teammate then selects the Scrumer connector, chooses Connect, signs in to Scrumer, and approves the requested scopes.
For ChatGPT, a workspace owner first enables custom MCP apps/connectors and adds the URL above in workspace settings. Each teammate then connects the Scrumer app from their own account and completes the same Scrumer sign-in and consent flow. Admin labels differ between ChatGPT workspace plans, but the server URL is unchanged.
To revoke access, disconnect or remove Scrumer from the Claude/ChatGPT connector settings. The host calls the OAuth revocation endpoint for its token; removing the organization-level connector also prevents new connections. Reconnecting starts a fresh consent flow.
Authorization and consent links are short-lived. If a browser flow is interrupted or reports that the request expired, return to Claude/ChatGPT and choose Connect again instead of reloading or reusing the old consent URL. Removing and re-adding the organization-level connector is only necessary when the host cannot start a fresh flow at all.
The local path remains unchanged: scrumer mcp still runs over stdio and authenticates from the CLI config file or SCRUMER_TOKEN. It does not use browser OAuth.
Hermes and other OAuth-capable remote agents can connect with:
mcp_servers:
scrumer:
url: "https://scrumer.ai/mcp"
auth: oauth
sampling:
enabled: false
Run hermes mcp login scrumer once on the remote host to complete consent and persist the refreshable token.
Development
bun run test— focused MCP registry regressionbun run type-check—tsc --noEmit- Types in
src/api/types.tsmirrorscrumer/lib/api.ts+ the scrumer-api routes; update them from those sources of truth when the API changes.