JSPM

@percent20/mist-plugin

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15
  • Score
    100M100P100Q69041F
  • License MIT

Mist — MFA for agentic AI. Claude Code plugin.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@percent20/mist-plugin) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    Mist

    MFA for agentic AI. Mist scores every prompt and tool call in Claude Code on a 7-axis risk vector (overall, financial, destruction, comms, access, production, scale). High-risk actions get gated. Approval happens silently when you're at a bound location anchor — otherwise it falls through to Claude Code's native terminal prompt with the risk score attached.

    Install

    From this repo (dev / pre-release)

    git clone https://github.com/percent-20/mist-plugin
    cd mist-plugin
    npm install

    Then point Claude Code at the directory:

    claude plugin install /absolute/path/to/mist-plugin

    Or, if you've cloned next to your ~/.claude/plugins/ directory, symlink it in:

    ln -s "$PWD" ~/.claude/plugins/mist

    Restart Claude Code. The hooks will register from settings.json automatically.

    Future: from the marketplace

    /plugin install mist

    (Coming soon — once published.)

    That's it. Mist is now active. No keys, no pairing, no setup. The plugin uses your existing ANTHROPIC_API_KEY to run a tiny Haiku classifier on each request, and surfaces high-risk ones through Claude Code's built-in approval prompt with the risk score attached.

    Smoke-test without installing

    Once npm install is done, you can pipe a fake hook event in to see the score:

    echo '{"prompt":"buy 50000 macbook pros"}' | node hooks/user-prompt-submit.js
    # → {"hookSpecificOutput":{"permissionDecision":"ask","reason":"Mist gate (overall=9, financial=9, scale=9): buy 50000 macbook pros"}}
    
    node bin/classify.js "transfer 50000 dollars to account 1234567890"
    # → vector: [9,9,0,0,0,0,9]   gate: FIRES (overall>=7, financial>=5, scale>=8)

    Bind a Mist bubble — a vault tied to a physical location — and Mist will auto-approve silently whenever you're inside it. No prompt, no notification, sub-second.

    /mist init        ← first-time setup (API key + initial bubble bind)
    /mist bind        ← re-bind to a different bubble later

    The SafeRoom app maintains the location signal that determines bubble membership. You install SafeRoom once, set the anchor, and forget about it. When Claude Code does something risky and you're at the bound location, the gate disappears.

    If you're outside the bubble, the gate denies by default. Run /mist rules policy ask to fall back to the native terminal prompt instead — useful for developers who travel; not recommended for headless / cloud Claude Code instances where there's no human at the terminal to ask.

    What gets gated

    The classifier outputs seven integers 0–9:

    overall, financial, destruction, comms, access, production, scale

    A challenge fires when ANY axis crosses its threshold. Defaults:

    overall      >= 7
    financial    >= 5
    destruction  >= 3
    comms        >= 8
    access       >= 7
    production   >= 6
    scale        >= 8

    Tune via /mist rules set <category> <threshold>.

    Examples of what scores trigger:

    • "explain typescript generics" → 0,0,0,0,0,0,0 — silent
    • "rm -rf node_modules" → 4,0,5,0,0,0,1 — gate fires (destruction>=3)
    • "buy 50000 macbook pros" → 9,9,0,0,0,0,9 — gate fires
    • "git push --force origin main" → 7,0,5,0,0,8,2 — gate fires
    • "delete the production database" → 9,0,9,0,0,9,4 — gate fires
    • "clean up the warehouse inventory db" → 3,0,3,0,0,0,2 — gate fires (destruction>=3, the borderline case)

    How approval works

    When the classifier crosses a threshold:

    1. No vault bound? Hook returns permissionDecision: "ask" and Claude Code's native terminal prompt appears with the Mist score as the reason.
    2. Vault bound, inside the bubble? Hook posts a single synchronous challenge to POST /api/v2/mfa_vaults/:vault_uid/challenge (the same endpoint the OpenClaw plugin already uses). Server runs VisitTracker.is_user_in_bubble? and returns status: "approved". Action proceeds silently.
    3. Vault bound, outside the bubble? Server returns status: "denied". Default: hook denies the action. Opt in to outside_bubble_policy: "ask" (via /mist rules policy ask) to fall back to the terminal prompt instead.
    4. Anything fails (network down, API unreachable): hook returns "ask" so Claude Code never silently locks you out.

    No polling, no async challenge waiting. The classifier runs locally; the API call sends only { instance_id } — no prompt content, no score vector, no tool name ever leave your machine.

    Commands

    • /mist init — first-time setup
    • /mist bind — re-bind to a different bubble
    • /mist status — show binding, recent decisions
    • /mist rules — view/edit thresholds and outside_bubble_policy

    Privacy

    Prompts are scored locally via the Anthropic API using your own key — they don't leave your machine en route to Mist's servers. The Mist API request body contains only your instance_id — no prompt content, no score vector, no tool name. If no vault is bound, the Mist API is never contacted at all.