Agentic patching, on the Max plan
Your AI agent upgrades the vulnerable dependencies. We tell it what to upgrade and check the result.
vulneraibility works out which packages in an app’s lockfile need a new version, keeps a record of every attempt to fix them, and rescans the lockfile afterwards. The change itself is made by your own agent or CI job, in your repository, with your credentials. You review the pull request and merge it.
We never get write access to your code. The server does not connect to your repository at all.
Who does what
vulneraibility
Knows what is vulnerable and keeps the record
- Matches the CVEs we analyse against the technologies you list, and checks each app’s lockfile against OSV.dev.
- Computes a remediation plan per lockfile: for each vulnerable package, the lowest version that clears every advisory with a published fix, and how to apply it.
- Orders the plan: packages with a CISA KEV advisory first, then by EPSS, then by severity.
- Stores the plan and every patch run, with an append-only history of each state change.
- Rescans the new lockfile your agent sends and gives the run one verdict.
Your agent or CI
Claude Code, Cursor, any MCP client, or a CI job with curl
- Reads the plan over MCP or the REST API, with an API key you created.
- Creates a branch, edits the manifest and lockfile, installs and runs your tests.
- Pushes the branch and opens the pull request with your credentials.
- Reports the pull request URL, branch and commit to the patch run.
- Sends the branch’s lockfile for verification.
You
Decide what gets merged
- Create the API key and choose which agent or CI job holds it.
- Upload each app’s lockfile, from the dashboard or from CI on the default branch. Plans start from that baseline.
- Review the pull request and merge it.
- Read the run history in the dashboard: who or what changed each run, and when.
The states of a patch run
A patch run is the record of one attempt to apply a plan. It moves through these states, and the server refuses any move that is not on the list. Two states cannot be set by hand: verified and verify_failed only come from a rescan of the lockfile, so a verified run always has a checked verdict.
Violet outline: set only by verification. Not drawn: the exits to failed and abandoned, and a few retries. Every legal move is in the table. On a small screen, scroll the diagram sideways.
Asking for verified directly returns 409 VERIFY_REQUIRED; any other illegal move returns 409 INVALID_TRANSITION with the allowed states. Every run also carries nextStates, so an agent does not need this table.
One run, from an MCP client
The MCP server is hosted, so there is nothing to install. You need a Max account, an API key from Settings, and a lockfile already uploaded for the app.
Connect Claude Code
claude mcp add --transport http vulneraibility \
https://www.vulneraibility.com/api/mcp \
--header "Authorization: Bearer vai_xxxxxxxx_yyyy"Then ask for the work in your own words, for example:
Fix the vulnerable dependencies of billing-api.
Follow the vulneraibility patching loop: one pull
request, and verify it before you stop.Or write the config by hand
{
"mcpServers": {
"vulneraibility": {
"type": "http",
"url": "https://www.vulneraibility.com/api/mcp",
"headers": {
"Authorization": "Bearer vai_xxxxxxxx_yyyy"
}
}
}
}This is .mcp.json for Claude Code. Cursor and other clients take the same URL and header in their own config format; each one is in the docs.
The calls the agent makes, in order
get_meYour plan and workspace role, so the agent knows what it may write.list_appsYour apps, each with its stack and versions.get_app_repoWhere the app’s code lives: provider, repository URL, default branch, and which manifest belongs to which lockfile. A note for the agent; the server never connects to it.get_remediation_planPreview of the plan for each lockfile, in priority order. Stores nothing.create_remediation_planStores one lockfile’s plan and returns its id. Calling it again for the same scan and items returns the same plan.create_patch_runStarts a run in state planned from that plan id. With an idempotencyKey, a retried call returns the same run.- The agent creates a branch, edits the manifest and lockfile, installs, runs the tests, pushes, and opens the pull request with your credentials. No vulneraibility call is involved.
update_patch_runMoves the run to pr_open and records prUrl, branch and commitSha.verify_patchSends the branch’s new lockfile. Verdict fixed moves the run to verified; anything else moves it to verify_failed and lists what is still open.update_patch_runMoves the run to merged after you merge, then to closed.
To pick up an earlier run instead of starting a new one, the agent calls list_patch_runs and get_patch_run.
The same loop from CI, over REST
Every tool is a thin wrapper over one endpoint. Send the API key as a Bearer token.
/api/v1/apps/{app}/dependenciesUpload a lockfile. A plain upload is the baseline. Add dryRun=1 to check a branch without moving it./api/v1/apps/{app}/remediationPreview the plan. Stores nothing./api/v1/apps/{app}/remediationStore the plan, get plan.id./api/v1/apps/{app}/patchesStart a run. Send an Idempotency-Key header./api/v1/patchesList runs across apps, to resume one./api/v1/patches/{runId}One run with its items, history and nextStates./api/v1/patches/{runId}Move the run, for example to pr_open, merged or closed./api/v1/patches/{runId}/verifySend the new lockfile, get the verdict./api/v1/apps/{app}/repoRead the repository note./api/v1/apps/{app}/repoReplace the repository note.# after your CI job has pushed the branch and opened the pull request
curl -sS -X PATCH -H "Authorization: Bearer $VAI_API_KEY" -H "Content-Type: application/json" \
-d '{"state":"pr_open","prUrl":"https://github.com/acme/billing-api/pull/42",
"branch":"vai/bump-lodash","commitSha":"3f9c2e1"}' \
https://www.vulneraibility.com/api/v1/patches/$RUN_ID
# verify the branch's lockfile
jq -n --rawfile text package-lock.json '{lockfile: {filename: "package-lock.json", text: $text}}' |
curl -sS -X POST -H "Authorization: Bearer $VAI_API_KEY" -H "Content-Type: application/json" \
--data-binary @- https://www.vulneraibility.com/api/v1/patches/$RUN_ID/verify
# -> { "success": true, "run": { "state": "verified", ... }, "verification": { "verdict": "fixed", ... }, ... }Request and response fields, error codes and a ready GitHub Actions workflow are in the patching section of the docs.
What it does not do
- It does not push code or open pull requests.The server has no access to your repository. It stores the URLs, branch and commit your agent reports, and does not check them.
- It does not run your tests.Your agent or CI does. “Verified” means the planned advisories are gone from the lockfile according to OSV.dev. It does not mean the application still works.
- It does not analyse reachability or exploitability.A package is listed because its version is in an advisory’s affected range, whether or not your code calls the vulnerable function.
- It does not scan OS packages, container images or source code.Plans come from lockfiles of six ecosystems: npm, PyPI, Go, crates.io, RubyGems and Packagist. Nothing is installed on your servers.
- It cannot fix what has no fixed version.An advisory with no published fix stays in the plan as open, with strategy no_fix. The plan never claims it.
- It is not on Free or Premium.The patch tools, the REST API and the keyed MCP server are on the Max plan. Accounts are invite-only during the beta.
Patching tools are part of Max
Together with the REST API, the keyed MCP server, and Slack and Telegram alerts.