REST API

Package intelligence API

MCP for agents, GET /api/npm/{package} for scripts. Same JSON: safe version picks (stable-preferred, prerelease when needed), policy, OSV, publisher, optional release notes.

Overview

Agents: add the MCP server + Cursor rule (below). The tool npm_package_suggest returns the same JSON as GET /api/npm/{package}: safe version picks with channel (stable or prerelease), publisher, policy, OSV batch metadata, warnings. Install the exact semver from the response. Never @latest before SafeVersion.

Getting started is copy-paste. Full HTTP reference and playground: Endpoint.

Getting started

Three things: MCP config → rule file → (optional) AGENTS.md. Restart Cursor after MCP changes.

1. MCP

Save as .cursor/mcp.json at the repo root (or merge safeversion into existing mcpServers).

Remove the whole headers object if you don’t use API keys. You can use Authorization: Bearer … instead of X-API-Key, same as the REST API.

{
  "mcpServers": {
    "safeversion": {
      "type": "streamableHttp",
      "url": "https://safeversion.com/api/mcp",
      "headers": {
        "X-API-Key": "YOUR_API_KEY"
      }
    }
  }
}

UI alternative: Settings → Tools & MCP → type streamableHttp → URL https://safeversion.com/api/mcp → same headers if needed.

Tool surface: npm_package_suggest with package, optional current, releaseNotes (matches REST query params).

2. Cursor rule

Download safeversion-dependencies.mdc → save as .cursor/rules/safeversion-dependencies.mdc. Keep alwaysApply: true in the frontmatter.

Or copy the same content from the block below.

---
description: MCP-first. Call SafeVersion before dependency adds/upgrades; no @latest
alwaysApply: true
---

# SafeVersion before dependency changes

## Workflow

1. **Call SafeVersion.** Use the MCP tool **`npm_package_suggest`** with the package name. For upgrades, pass **`current`** as the **exact** installed semver.
2. **Read the response.** Check **`warnings`** and **`security`** (`dataStatus` reflects OSV batch success, not a global "all clear") before editing `package.json` or running installs.
3. **Install the exact version.** Use the **exact** version the tool indicates (e.g. **`latestSafe`** for new deps; **`smallestSafeUpgrade`** or **`latestSafe`** when upgrading. Compare both when `current` is set). Prefer pinned versions over floating ranges when acting autonomously.
4. **No safe recommendation.** Stop and explain; do not invent a version.

## Do not

Do **not** run `npm install <pkg>@latest`, `pnpm add <pkg>@latest`, `yarn add <pkg>@latest`, `bun add <pkg>@latest`, or equivalent **before** calling SafeVersion.

If SafeVersion (MCP or API) errors or is unreachable, **do not** fall back to arbitrary installs.

## Without MCP

Use **`GET https://safeversion.com/api/npm/{package}`** with `Accept: application/json`. Encode scoped names (`encodeURIComponent`). Add **`?current=`** (exact semver) for upgrades. Fields match the MCP tool output.

**Scope:** Adding, removing, or bumping npm dependencies in `package.json` and lockfiles.

3. AGENTS.md (optional)

Repo root AGENTS.md; merge if you already have one.

# Dependencies (SafeVersion)

Before adding or upgrading npm packages, call the SafeVersion MCP tool **npm_package_suggest** (pass **current** with the exact installed semver when upgrading). Read **warnings** and **security** (field **dataStatus** is OSV batch health, not a global all-clear).

Do not run npm install <pkg>@latest, pnpm add <pkg>@latest, or equivalent before SafeVersion. Install the **exact** version from the response. If there is no safe recommendation, stop and explain why.

Setup: https://safeversion.com/docs#getting-started

Endpoint

GET /api/npm/{package}

Path

GET /api/npm/{package}

{package} is a single URL segment. Use percent-encoding for scoped names, e.g. @types/node%40types%2Fnode. The playground builds this for you.

Alternate name query

You may pass ?name= to override the path segment (decoded the same way). If both are empty after trim, the API returns 400.

Query parameters

NameTypeRequiredDescription
namestringNoOptional override for the package name (instead of the path segment only).
currentstringNoInstalled version as exact semver. When valid, the response includes smallestSafeUpgrade: the lowest safe version strictly greater than current. Invalid semver → 400.
releaseNotesflagNoWhen 1, true, or yes (case-insensitive), the response may include a releaseNotes object with summaries fetched from GitHub for tags matching latestSafe and smallestSafeUpgrade. Expect slower responses; entries may be missing if the repo has no matching release.

Response body

On success you get a JSON object with the fields below. Omitted keys mean “not applicable” (for example smallestSafeUpgrade appears only when you passed current).

FieldMeaning
packageDisplay name from the packument (fallback: requested name).
requestedCurrentEcho of normalized current when supplied.
latestSafeNewest safe version, preferring stable over prerelease. Each version object includes channel ("stable" or "prerelease"),satisfies (policy checks passed), and publisher when known. null if no safe version exists.
smallestSafeUpgradeWith current: lowest safe version > current, or null if none. Omitted entirely without current.
policyminAgeDays tells you how many days after publish a version must be before it can qualify as “safe” for this API.
securityprovider: "osv", assessedAt ISO timestamp, dataStatus available when the OSV batch succeeded or unavailable if it failed. This describes data availability only. Use warnings and each version's satisfies for actionable context.
linksnpm URL, optional repository, and when GitHub is known + current is set: compareToLatestSafe / compareToSmallestSafeUpgrade compare URLs.
identityCanonical package name and packument-level author when present. Per-version publisher data lives on each latestSafe / smallestSafeUpgrade object directly.
releaseNotesPresent when requested: optional entries for latestSafe and smallestSafeUpgrade with tag, summary, and URL.
warningsHuman-readable issues: empty age window, OSV failure, no clean versions, etc.

Each safe version includes version, publishedAt (ISO), channel ("stable" or "prerelease"), satisfies (e.g. ["ageWindow", "osvClean"]), and publisher when known.

Errors

StatusBodyWhen
400{ "error": "Missing package name" }No usable name from path or query.
400{ "error": "Invalid semver for query parameter current" }Malformed current.
404{ "error": "Package not found" }Registry returned 404.
502{ "error": "Could not read package metadata" }Oversized or invalid packument JSON.
502{ "error": "Registry request failed" }Non-OK response from npm registry.
504{ "error": "Upstream request timed out" }The request did not finish in time (upstream work exceeded the timeout).
500{ "error": "Internal server error" }Unexpected failure.

Interactive examples

Each playground runs a real fetch to the same host you opened the docs on. Use the sidebar under Interactive examples to jump between recipes.

Baseline: latest safe

When to use: You only need the newest “safe” version and general policy / security context. Omit current so smallestSafeUpgrade is not computed.

RequestGET

Must be a valid semver string when set.

/api/npm/react

Response
Run a request to see status, timing, and JSON here.

With current version

When to use: You know what is installed and want the next safe bump (e.g. for PR bots or dashboards). Pass a valid semver as current to populate smallestSafeUpgrade and compare links when a GitHub repo exists on the packument.

RequestGET

Must be a valid semver string when set.

/api/npm/react?current=18.0.0

Response
Run a request to see status, timing, and JSON here.

Scoped package

When to use: Scoped packages must occupy a single path segment; the playground encodes @scope/name automatically for the request URL.

RequestGET

Must be a valid semver string when set.

/api/npm/%40types%2Fnode?current=20.0.0

Response
Run a request to see status, timing, and JSON here.

Release notes

When to use:You want human-readable release text alongside version picks. Responses are slower and release bodies may be absent depending on the package's GitHub tags and rate limits.

RequestGET

Must be a valid semver string when set.

/api/npm/semver?current=7.5.0&releaseNotes=1

Response
Run a request to see status, timing, and JSON here.

Beta-only package fallback

When to use: Packages that only publish prereleases. The API prefers stable but when none exist, latestSafe will have channel: "prerelease".

RequestGET

Must be a valid semver string when set.

/api/npm/workflow

Response
Run a request to see status, timing, and JSON here.