# OurCVEs — Agent Setup Guide

You are an AI coding agent reading this file because a human asked you to set them
up with OurCVEs. OurCVEs is a vulnerability triage service: it watches the user's
code dependencies and servers, surfaces CVEs that actually affect them, and helps
them decide what to do about each one.

Your job is to get the user onboarded, connect an MCP client to their account, and
then use the MCP server to do real work on their behalf. The whole setup involves
**one click in the user's email inbox**. Everything else happens through this file
and the OurCVEs HTTP API.

If at any point you are unsure whether a step succeeded, stop and ask the user
rather than guessing. Do not retry a request that returned a 4xx without explaining
the error to the user first.

---

## Prerequisites — collect from the user before starting

1. Their full name (used in emails, can be changed later).
2. Their email address.
3. (Optional) A name for their first team. If omitted, the default is the part of
   their email before the `@`, title-cased. They can rename it on the
   confirmation page.

Do not ask for a password. There isn't one — OurCVEs uses magic links.

---

## Step 1 — Start the onboarding session

Make this request:

```http
POST https://ourcves.com/api/v1/onboarding/start
Content-Type: application/json

{
  "email": "<user email>",
  "name": "<user name>",
  "team_name": "<optional team name>",
  "client": "<short identifier of your MCP client, e.g. 'claude-code', 'cursor', 'claude-desktop'>"
}
```

Successful response (HTTP 201):

```json
{
  "session_id": "ses_01HXYZ...",
  "poll_url": "https://ourcves.com/api/v1/onboarding/sessions/ses_01HXYZ...",
  "poll_interval_seconds": 5,
  "expires_at": "2026-05-21T18:00:00Z",
  "email_sent_to": "user@example.com",
  "verification_hint": "Check your inbox for a message from 'OurCVEs <hello@artisan.build>' with subject 'Confirm your OurCVEs setup'."
}
```

Tell the user, in your own words: a magic link is on its way to
`<email_sent_to>` and they should click it. The link takes them to a short
confirmation page where they can adjust their team name and click "Confirm
setup." After that they'll be redirected to a pricing page — they can pick a
paid plan or stay on the free tier and close the tab.

If the email or name fails validation you'll get HTTP 422 with
`{ "errors": { "email": ["..."], ... } }`. Show the validation error to the user
and ask them to fix it.

If the user already has an OurCVEs account, this endpoint still succeeds — the
magic link logs them in instead of creating a new account. Do not branch on this.

---

## Step 2 — Wait for the user to click and confirm

Poll the `poll_url` from Step 1 every `poll_interval_seconds`. Stop polling when
you reach `expires_at` (15 minutes from session start).

```http
GET https://ourcves.com/api/v1/onboarding/sessions/ses_01HXYZ...
Accept: application/json
```

Possible responses:

```json
{ "status": "pending_email" }
```

The user has not clicked the magic link yet. Keep polling. Do not nag the user
between polls.

```json
{ "status": "pending_confirmation" }
```

The user clicked the link and is on the confirmation page but has not yet
clicked "Confirm setup." Keep polling.

```json
{ "status": "expired" }
```

The 15-minute window elapsed. Tell the user, then offer to restart from Step 1.

```json
{
  "status": "ready",
  "token": "1|abcDEF...",
  "mcp_url": "https://ourcves.com/mcp/team",
  "user": {
    "id": "usr_01...",
    "email": "user@example.com",
    "name": "User Name"
  },
  "team": {
    "id": "team_01...",
    "slug": "user-name",
    "name": "User Name"
  },
  "next_steps": [
    { "id": "register-server", "label": "Monitor a Linux server", "kind": "mcp" },
    { "id": "connect-github",  "label": "Scan your GitHub repos", "kind": "browser",
      "url": "https://ourcves.com/github/install" }
  ]
}
```

The `token` field appears exactly once. Treat it as a secret. Do not echo it back
to the user in plain text — only show its last 4 characters when confirming.
Subsequent reads of this poll URL return `status: "consumed"` and will not
re-emit the token.

---

## Step 3 — Configure the user's MCP client

The OurCVEs MCP server uses **HTTP transport with a Bearer token**. The URL is
the `mcp_url` from Step 2 (`https://ourcves.com/mcp/team`) and the auth header is
`Authorization: Bearer <token>`.

Pick the configuration path that matches the client you are running inside.

### Claude Code

Prefer the CLI — it handles escaping and validates the config:

```bash
claude mcp add --transport http --scope user ourcves \
  https://ourcves.com/mcp/team \
  --header "Authorization: Bearer <token>"
```

If the CLI is unavailable, edit `~/.claude.json` and add an entry under
`mcpServers`:

```json
{
  "mcpServers": {
    "ourcves": {
      "type": "http",
      "url": "https://ourcves.com/mcp/team",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}
```

### Cursor

Edit `~/.cursor/mcp.json` (create if it doesn't exist):

```json
{
  "mcpServers": {
    "ourcves": {
      "url": "https://ourcves.com/mcp/team",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}
```

### Claude Desktop

Claude Desktop does not yet speak remote MCP natively. Use the `mcp-remote`
bridge. Edit
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or
`%APPDATA%\Claude\claude_desktop_config.json` on Windows:

```json
{
  "mcpServers": {
    "ourcves": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://ourcves.com/mcp/team",
        "--header",
        "Authorization: Bearer <token>"
      ]
    }
  }
}
```

The user must restart Claude Desktop after editing this file.

### Other clients

If the client speaks the MCP `streamable-http` transport, point it at
`https://ourcves.com/mcp/team` with `Authorization: Bearer <token>`. If it only
speaks stdio, wrap the URL with `npx -y mcp-remote ...` as shown above.

---

## Step 4 — Verify the connection

Call the `list-my-teams-tool` tool on the newly configured server. The response should
include the team that was created during onboarding.

Success looks like:

```json
{
  "teams": [
    { "id": "team_01...", "slug": "user-name", "name": "User Name", "role": "owner" }
  ]
}
```

If you cannot call MCP tools yet (because the client needs a restart), tell the
user exactly what to do: restart their MCP client, then say "list my OurCVEs
teams" to you.

Once verification passes, the setup is complete. Tell the user briefly:

- They are signed in as `<user.email>`.
- Their team is `<team.name>` (slug `<team.slug>`).
- They can manage billing at any time at `https://ourcves.com/billing`.

---

## Step 5 — Offer the next moves

Use the `next_steps` array from Step 2 as the menu. Adapt the phrasing — don't
read them verbatim. For each step:

- **`kind: "mcp"`** — you can drive this entirely through MCP tool calls. Offer
  to do it now.
- **`kind: "browser"`** — give the user the `url` and explain why a browser is
  required (vendor OAuth, payment forms, etc).

The most common follow-ups, in rough priority order:

1. **`register-server`** (MCP) — Install the OurCVEs Linux agent on a server to
   start receiving CVE alerts for its installed packages. There is an MCP tool
   for this; it returns a one-line install command (`curl ... | sh`) bound to a
   single-use installation token.
2. **`connect-github`** (browser) — The GitHub App is the only way to get repo
   scanning. The user must approve installation on github.com.

After the user has done at least one of these, call `summarize-my-risk-tool` and walk
them through the findings.

---

## What you can and cannot do with this token

Agent-issued tokens have **read access to everything the user can read** and
can perform a small, scoped set of **non-destructive mutations**: changing
finding status, recording notes and mitigation plans, acknowledging risk, and
registering monitored servers.

They **cannot** delete teams, remove members, manage billing, rotate or revoke
tokens, or perform any other destructive operation. Those live in the browser
at `https://ourcves.com`.

The mutating tools you have access to are listed below under "Mutations."
Before calling any of them you **must** confirm with the user in the same
turn. Quote the specific resource — finding ID, server name, team slug — back
to them and wait for an explicit yes. Every mutation is logged against your
token with the `client` field and a timestamp; the user can review or revoke
the token from `https://ourcves.com/settings/security`.

---

## Tool inventory

After Step 4 you have access to the `OurCVEs Team` MCP server.

**Read-only tools** — no confirmation needed; use freely:

| Tool                  | Purpose                                                       |
|-----------------------|---------------------------------------------------------------|
| `list-my-teams-tool`       | Enumerate teams the user belongs to (cross-team).             |
| `find-my-exposures-tool`   | List vulnerable findings across all the user's teams.         |
| `summarize-my-risk-tool`   | Weekly-report rollup: new vs. resolved, current open.         |
| `list-team-assets-tool`    | What's being monitored for one team: servers, repos.          |
| `list-open-findings-tool`  | Open findings for one team.                                   |
| `get-finding-detail-tool`  | Full finding record incl. package version, severity, fix.     |
| `get-cve-detail-tool`      | Underlying CVE record — references, CVSS, ecosystems.         |
| `list-finding-notes-tool`  | Notes left by the user, teammates, or OurCVEs editorial.      |

**Mutations** — confirm with the user before each call:

| Tool                              | Purpose                                                    |
|-----------------------------------|------------------------------------------------------------|
| `mark-finding-resolved-tool`           | Close a finding once patched.                              |
| `reopen-finding-tool`                  | Undo a resolution.                                         |
| `record-mitigation-plan-tool`          | Capture how the user plans to address a finding.           |
| `record-resolution-instructions-tool`  | Capture the steps that worked (helps teammates).           |
| `acknowledge-finding-risk-tool`        | Explicitly accept a finding's residual risk.               |
| `retract-finding-note-tool`            | Remove a note the user wrote earlier.                      |
| `register-server-tool`                 | Mint an install command for a new monitored Linux server.  |

Cross-team tools (`list-my-teams-tool`, `find-my-exposures-tool`, `summarize-my-risk-tool`)
infer scope from the authenticated user. Team-scoped tools require a `team_slug`
argument and refuse calls for teams the user doesn't belong to.

When the user is on more than one team, prefer the cross-team tools first and
ask "which team do you want to focus on?" before chaining mutations.

---

## Failure modes worth handling explicitly

- **HTTP 429 from any endpoint** — you've been rate-limited. Wait at least 30s
  and tell the user; do not silently retry in a tight loop.
- **HTTP 401 from MCP after setup** — the token was revoked. Restart from
  Step 1; do not try to recover.
- **`status: "expired"` on the polling endpoint** — the 15-minute window
  passed. Restart from Step 1 with the same email; the second magic link
  supersedes the first.
- **`status: "consumed"` on the polling endpoint** — the token was already
  emitted on an earlier read. The token is gone; restart from Step 1.
- **MCP tool returns `error.code = "team_not_found"`** — the user typed a slug
  for a team they aren't a member of. Show the result of `list-my-teams-tool` and
  ask them to pick from that list.
- **MCP tool returns `error.code = "forbidden_for_agent_token"`** — you tried
  to call something outside the agent-token scope (e.g. team deletion). Send
  the user to `https://ourcves.com` to do it in the browser.
- **User asks to "delete my account" or "rotate my token"** — these are not
  exposed via MCP. Send them to
  `https://ourcves.com/settings/security`.

---

## What you should never do

- Don't call any mutation tool without explicit confirmation from the user in
  the same turn. Quote the resource ID back to them; wait for a clear yes.
- Don't store the token anywhere outside the MCP client config the user is
  aware of. No env files, no shell rc edits, no copying into chat history.
- Don't invent CVE identifiers, severity scores, or fix versions. If a tool
  doesn't return a field, say so; do not synthesize.
- Don't bypass the magic link by asking the user for a password. There isn't
  one.
- Don't attempt destructive operations through the MCP server. They will be
  rejected; route the user to the browser for those.

---

## Versioning

This guide describes **v1** of the OurCVEs onboarding and MCP surface. The base
URL for the lifetime of v1 is `https://ourcves.com/api/v1/` and the MCP server URL is
`https://ourcves.com/mcp/team`. Breaking changes will live at `/api/v2/...` and this
file will be updated to point there.

Last updated: 2026-05-21.
