BoundBench

Neon MCP

MCP server for Neon Management API and databases

github.com/neondatabase/mcp-server-neon · 2026-10-03 · 00d82d4

Defense-in-depth score

4.6 / 10

Minimal

Neon MCP gives an AI client full write and delete authority over a user's whole Neon account by default: arbitrary SQL as the database owner, project and branch deletion, function deploys and auth changes. Read-only, category and project restrictions exist and are enforced in code, but they are opt-in, and credential handling in the OAuth flow is not strictly scoped. The server also routinely returns database passwords to the model. Use a readonly=true or projectId-scoped URL.

Key gaps (3)

  1. A hijacked session or stolen token has write and delete authority over the user's whole Neon account, including organizations and every database. C1 · Identity & least privilege
  2. Worst case under prompt injection: a hijacked default session can exfiltrate data and secrets and run irreversible SQL and deletions with no server-side human step. C5 · Untrusted input blast radius
  3. Database owner-role passwords are routinely returned to the model through get_connection_string, which the create tools tell the model to call. C8 · Secrets & sensitive-data protection

Criteria

C1 Identity & least privilege

Minimal 0.23 / 1.00

The server acts on Neon with the user's own authority. In the OAuth flow it requests broad project and organization scopes (create, update, delete, org permissions); in the API-key flow it forwards the user's Neon API key. Read-only, category and project restrictions are enforced inside the server by filtering tools and pinning project_id; handling of the issued credential is not strictly scoped. The default grant is read-write across every project and organization the user can reach.

C2 Approval gates

Minimal 0.38 / 1.00

As a hosted tool server, Neon MCP leaves approval to the MCP client and contributes risk signalling. Every tool carries readOnly/destructive hints, deletes and updates are marked destructive, and the descriptions of dangerous tools tell the model to ask first; but run_sql and run_sql_transaction mix reads and writes in one tool, and there is no server-side confirmation step. Migrations and query tuning use a prepare-on-temporary-branch, then complete pattern that works as a preview, but project and branch deletion, raw SQL, function deploys and auth changes have none. A server-enforced read-only mode exists but is off by default.

C3 Tool & action scoping

Minimal 0.33 / 1.00

Most of the roughly 110 tools are narrow, typed Neon API operations with strict schemas, and a project-scoped grant pins project_id in code. The tools that matter most are raw passthroughs, though: run_sql, run_sql_transaction and explain_sql_statement send any SQL the model writes, as the database owner role, and deploy_function uploads arbitrary code. By default every category is enabled, including writes, across every project; category and project filters are opt-in. SQL has no row or statement limit.

C4 Code-execution isolation

Minimal 0.47 / 1.00

Nothing the model writes runs on the server: SQL goes to Neon's managed Postgres over HTTPS, and deployed functions run on Neon's platform. That is a real separation from the MCP host, but SQL runs as the database owner role (a neon_superuser member) directly on the chosen branch, usually the main one. The opt-in read-only mode wraps SQL in a read-only transaction using the same owner role rather than a read-only role. Only the migration and tuning flows use a throwaway branch first.

C5 Untrusted input blast radius

Minimal 0.07 / 1.00

Database rows, column comments, logs and function code can all hold attacker-written text, and the server returns them to the model as plain JSON with no provenance or untrusted marking. If the model is hijacked by that content, the same session can run any SQL, delete projects and branches, fetch connection strings with passwords, and deploy functions with outbound network access, with nothing in the server asking a human. The read-only and project-scoped modes would cut most of that but are off by default.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

The server keeps no memory the model can write and loads no workspace or instruction files. Its persistent state is OAuth tokens, grants and session bindings, which the model cannot influence. Data written into a database can be read in a later session, but that is untrusted input (C5), not server memory.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads or launches no third-party code at runtime: no plugins, no subprocesses, no dynamic imports, and it does not connect to other MCP servers. Its tools call the Neon API, Neon Postgres and neon.com docs only. Its @neon/tools dependency is a build-time package and out of scope here.

C8 Secrets & sensitive-data protection

Minimal 0.25 / 1.00

The server deliberately puts database secrets into the model's context: get_connection_string returns the full Postgres URI including the owner role's password, and tool descriptions tell the model to call it after creating a project or branch; role creation and password reset also return passwords. It does strip connection URIs and client secrets from other Management API results and redacts Neon Auth secrets. Token storage and logging do not fully protect credentials. Segment analytics (with user email) and Sentry with default PII and 100% tracing are on by default.

C9 Audit & traceability

Minimal 0.38 / 1.00

Every tool call passes through one wrapper that writes a log line (tool name, read-only and project-scope flags, client, trace id) before running, and sends a matching analytics event with the account id. Arguments are not recorded, so after an incident you can see that run_sql or delete_project was called but not on what or with which SQL. Logs go to the console, which Vercel collects off-host, beyond the model's reach. There is no tamper-evident audit trail or record of results.

C10 Limits & kill switch

Minimal 0.45 / 1.00

The server bounds some of its own work: each request is capped by the 800-second Vercel function limit, create operations wait at most 120 seconds, docs fetches time out after 10 seconds, and inspection queries cap their row limit. Generated Management API calls receive the client's cancellation signal. But SQL has no statement timeout or row cap, and there are no rate limits on SQL, deletions, or creating projects, branches and computes, all of which keep running in Neon after a request ends.