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.