Vulnify MCP server
The Vulnify MCP server gives AI assistants and IDEs tools to check an action, read a decision, and test policies. Cursor, Claude, Grok, or your own code connect to it. It does not run your agent’s tools, and it does not sit between the agent and another MCP server.
Vulnify is available in Claude’s connector directory.
That production path is the MCP gateway. The gateway decides an agent’s MCP tool call and, when the decision allows it, forwards the call to a registered upstream MCP server.
| Vulnify MCP server | MCP gateway | |
|---|---|---|
| Role | Tools for an AI assistant or an IDE | Enforce the decision in the agent’s production tool path |
| Callers | Cursor, Claude, Grok, VS Code, or your own code | Your agent, on the way to another MCP server |
| Address | https://mcp.vulnify.io/mcp |
POST /v1/gateway/mcp on https://api.vulnify.io |
Sign in with Vulnify
Section titled “Sign in with Vulnify”The primary path is Sign in with Vulnify (OAuth 2.1). The hosted server is https://mcp.vulnify.io/mcp. It speaks Streamable HTTP and keeps no session.
Add that URL in the client. Leave API-key and OAuth client fields empty. The client receives HTTP 401 and this challenge:
WWW-Authenticate: Bearer realm="https://mcp.vulnify.io/mcp", resource_metadata="https://mcp.vulnify.io/.well-known/oauth-protected-resource/mcp", scope="decisions:read decisions:write policies:read policies:test"The body is {"error":"unauthorized","message":"Sign in with Vulnify, or send an API key as Authorization: Bearer <key> or X-Vulnify-Key: <key>."}.
The client opens Vulnify. You choose an organization and allow the scopes it requests:
| Scope | Tools |
|---|---|
decisions:read |
get_decision |
decisions:write |
decide_action |
policies:read |
list_policies |
policies:test |
check_action, test_policies |
After you allow access, the hosted server offers those five tools. plan_policy_changes and check_mcp_tool_call are not in that list. They need an API key, through a manual config or local npx -y @vulnify/mcp. See API key or local npx.
A missing scope comes back as a tool error that names the scope. That error is not an ALLOW. This server has no approve tool and no deny tool. A person resolves a REVIEW in Vulnify.
Revoke the connection in the app under Settings > Connected apps: app.vulnify.io/settings/connected-apps.
Claude
Section titled “Claude”Vulnify is available in Claude’s connector directory.
On a personal account, open Customize > Connectors. Open the Discover tab, or click + next to Connectors. Search for Vulnify, open the listing, and select Connect. Sign in with Vulnify, choose the organization, and allow the scopes.
From a chat, click + or type /, then choose Connectors > Manage connectors. Search for Vulnify there and select Connect.
On Team and Enterprise plans, an Owner or Primary Owner adds Vulnify under Organization settings > Connectors. Click Browse connectors, select Vulnify, and click Add to your team. Each member then connects with their own Vulnify account.
To add a custom connector by URL instead, open Customize > Connectors, then Add custom connector (or Add, then Custom > Web). Set the URL to https://mcp.vulnify.io/mcp. Do not paste an API key.
Add Vulnify in Claude opens that dialog with the name and URL filled in. Claude then starts Sign in with Vulnify.
Cursor
Section titled “Cursor”Install in Cursor adds the hosted server and starts sign-in.
The same server in .cursor/mcp.json, or in ~/.cursor/mcp.json, is the URL with no header:
{ "mcpServers": { "vulnify": { "url": "https://mcp.vulnify.io/mcp" } }}Open grok.com/connectors, then New Connector > Custom. Name it Vulnify. Set the URL to https://mcp.vulnify.io/mcp. Leave the OAuth fields empty. Grok starts Sign in with Vulnify.
Claude Code
Section titled “Claude Code”claude mcp add --transport http vulnify https://mcp.vulnify.io/mcpClaude Code then signs in. Do not pass an API key on this command.
API key or local npx
Section titled “API key or local npx”Use an API key when you need plan_policy_changes or check_mcp_tool_call, when the client cannot open a browser, or when the key has an IP allowlist. The local process is @vulnify/mcp 0.1.2. It needs Node.js 20 or newer and reads VULNIFY_API_KEY. It does not open the OAuth consent page.
npx -y @vulnify/mcpVULNIFY_API_KEY=vln_live_... npx -y @vulnify/mcpThe key is the same secret as the API: vln_live_… or vln_test_…. A TEST key stores sandbox events. Those stay out of the main dashboards.
On the hosted server, send the key on every request. Either header works:
Authorization: Bearer <api key>X-Vulnify-Key: <api key>An API-key session lists all seven tools.
Cursor
Section titled “Cursor”{ "mcpServers": { "vulnify": { "url": "https://mcp.vulnify.io/mcp", "headers": { "Authorization": "Bearer vln_live_..." } } }}{ "mcpServers": { "vulnify": { "command": "npx", "args": ["-y", "@vulnify/mcp"], "env": { "VULNIFY_API_KEY": "vln_live_..." } } }}X-Vulnify-Key works in place of Authorization on the hosted server.
Claude Code with an API key
Section titled “Claude Code with an API key”claude mcp add --transport http vulnify https://mcp.vulnify.io/mcp --header "Authorization: Bearer vln_test_your_key"Prefer an environment variable over a key written into the shell history. For sign-in, use the Claude Code command with no header.
Claude Desktop can run the local process. On macOS the file is ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows it is %APPDATA%\Claude\claude_desktop_config.json. Restart the app after saving.
{ "mcpServers": { "vulnify": { "command": "npx", "args": ["-y", "@vulnify/mcp"], "env": { "VULNIFY_API_KEY": "vln_live_..." } } }}VS Code
Section titled “VS Code”.vscode/mcp.json:
{ "servers": { "vulnify": { "type": "http", "url": "https://mcp.vulnify.io/mcp", "headers": { "Authorization": "Bearer ${input:vulnify-api-key}" } } }}{ "servers": { "vulnify": { "type": "stdio", "command": "npx", "args": ["-y", "@vulnify/mcp"], "env": { "VULNIFY_API_KEY": "${input:vulnify-api-key}" } } }}Your own code
Section titled “Your own code”An MCP client that speaks Streamable HTTP can use https://mcp.vulnify.io/mcp with no key and complete Sign in with Vulnify, or send Authorization: Bearer <api key> or X-Vulnify-Key.
Application code that decides inside your own process uses the SDK, not this server. See the Node.js SDK and the Python SDK.
Seven tools. With OAuth the hosted server offers the five that match the consent scopes. decide_action and check_mcp_tool_call record a security event and an audit entry. The others do not. check_mcp_tool_call is API-key only, so an OAuth session does not record through that tool.
| Tool | Records an event | OAuth | What it does |
|---|---|---|---|
check_action |
No | Yes, policies:test |
Dry run of one action against the stored policies (POST /v1/policies/test, one case). Skips the PII scan. Records nothing: no security event, no audit entry, no event id, and no finalDecision. Use decide_action when the decision must be recorded. |
decide_action |
Yes | Yes, decisions:write |
Record a real decision (POST /v1/events). Writes a security event and an audit entry. Obey finalDecision. REVIEW or BLOCK means do not run the action. This tool does not approve the review. |
get_decision |
No | Yes, decisions:read |
Read one recorded decision (GET /v1/events/{id}). Optional waitMs polls a REVIEW until ALLOW or BLOCK, or until the wait ends (30 seconds maximum). Does not approve or deny the review. |
list_policies |
No | Yes, policies:read |
List policies as code (GET /v1/policies), sorted by name. Read-only. |
test_policies |
No | Yes, policies:test |
Evaluate up to 200 cases (POST /v1/policies/test). Writes no security event and no audit entry. Skips the PII scan. Proposed policies are not saved. |
plan_policy_changes |
No | API key | Dry run of creates, updates, and deletes (POST /v1/policies/apply). dryRun is forced to true and cannot be turned off. Writes nothing and does not apply the plan. Needs an org-wide LIVE key. A TEST key or an agent-bound key is 403. |
check_mcp_tool_call |
Yes | API key | Decide a downstream MCP tool call and record it (POST /v1/gateway/mcp). Maps the tool name to an action by substring and returns the same recorded decision as decide_action, including an id. Arguments are not executed. Obey finalDecision. REVIEW or BLOCK means do not run the downstream tool. |
decide_action and check_mcp_tool_call append a decision the way the API does. Pass idempotencyKey so a retry returns that same event. A later read is get_decision. check_action does not create an event to read. plan_policy_changes never writes a policy. prune only marks missing policies for deletion in the plan.
IP allowlists
Section titled “IP allowlists”An API key can list allowed source IPs. See API keys. Calls through the hosted server with that key come from the server’s egress address, not from the machine where Cursor or VS Code is running. An allowlist that only contains your office or laptop address will reject the hosted server.
Use npx -y @vulnify/mcp over stdio for an allowlisted key, on a host whose address is on the list. The key stays in that process’s environment. Sign in with Vulnify does not send that API key.

