Install with one command. Extend with four surfaces.

Config lives in your repo, reviewable in a PR. Nothing about Peeve is configured in a dashboard you can't diff.

CLIthree commands, that's the surface
$ npx peeve init
$ npx peeve verify
$ npx peeve killswitch
SDKidentify signed server-side
import { Peeve } from '@peeve/sdk'
Peeve.init({ workspaceKey: 'pk_live_…' })
Peeve.identify({ userId, token })
Peeve.setContext({ plan, seats })
Peeve.open({ intent: 'invite a teammate' })
APIsessions, capabilities, routes
GET /v1/sessions?since=…
GET /v1/routes/coverage
POST /v1/capabilities
POST /v1/killswitch
MCPyour users' agents connect here
# workspace endpoint
mcp.peeve.ai/northwind
# per-user, revocable
mcp.peeve.ai/northwind/u/8f2a
Passive signals · billing & churn intent

Read intent from markup you already have.

Add a few data-peeve-* attributes to your cancel button and your pricing cards, and Peeve reads them straight from the DOM. No extra JS, no events to wire. These signals fire passively: on a plain pricing-page view or a click toward cancellation, even if the visitor never opens the assistant.

AttributeOnCaptures
data-peeve-cancela cancel / downgrade controlPresence alone marks it a cancel/downgrade control and emits a passive cancel_intent signal. No value needed.
data-peeve-plan="<name>"a pricing plan card / rowPlan display name, e.g. "Growth".
data-peeve-amount="<amount>"a pricing plan card / rowPrice, e.g. "99" or "$99.00".
data-peeve-currency="<ISO 4217>"a pricing plan card / rowOptional. ISO 4217 code for the amount (USD/EUR/GBP…). Inferred from the amount's currency symbol when present, else defaults to USD. Only meaningful alongside an amount.
data-peeve-interval="<monthly|quarterly|yearly>"a pricing plan card / rowBilling cycle. Write annual as yearly.
Example
<!-- Cancel control → emits a passive cancel_intent signal -->
<button data-peeve-cancel>Cancel subscription</button>

<!-- Pricing card → tags pricing views with plan / amount / currency / interval -->
<div
  data-peeve-plan="Growth"
  data-peeve-amount="$99.00"
  data-peeve-currency="USD"
  data-peeve-interval="yearly">
  <h3>Growth</h3>
  <p class="price">$99<span>/yr</span></p>
  <button>Upgrade to Growth</button>
</div>
Install with the CLI
npx @peeve/cli init auto-detects your framework (Next.js App/Pages, React/Vite/CRA, Vue, Angular, SvelteKit, Astro, Nuxt, static HTML) and installs the widget snippet, with --dry-run, --framework, and confirm-before-write.
Or the SDK
@peeve/sdk. Peeve.init() plus framework snippets (React/Next, Vue, Angular, Svelte/vanilla). The SDK README documents the full attribute reference above.
From install to live

Four steps, one afternoon. Nothing your users see changes until you say so.

01
Install
npx peeve init detects your framework, adds the snippet, and writes peeve.config.json at your repo root, reviewable in a PR.
02
Identify users
Pass a token signed on your server so Peeve knows who the user is and what they may do. It's never derived in the client.
03
Run the guided crawl
Use your own product once (about 20 minutes) while Peeve records the routes and builds the Brain from what's actually shipped.
04
Verify and go live
npx peeve verify names what it found and what it can't reach. Peeve stays read-only until you flip it on; the kill switch is one command.
Quick answers
How do I install Peeve?
One snippet or the CLI.
How do I identify users securely?
Signed token, server-side.
What does the config file control?
Routes, masks, capabilities.
How do agents connect?
Scoped MCP endpoint.
What's in the API?
Everything the dashboard shows.
Why teams choose Peeve
No selectors to break
Semantic fingerprints survive re-renders and restyles; drift is detected and healed automatically, not re-authored every release.
Reviewable in a PR
peeve.config.json lives in your repo: routes, masks and capabilities, all diffable, with a CI deploy-hook to keep it in step.
An afternoon, not a project
npx peeve init, a guided crawl, read-only until you go live, and a kill switch in one command.
14-day trial, no cardInstalls in an afternoonRead-only until you widen itKill switch in one commandCancel anytime, no lock-in

One snippet, config in your repo. 14 days free. No card. No call.