← MCP server and skill grades

mcp-server-neon

neondatabase/mcp-server-neon

B
Type
MCP server
Scanned
Oct 29, 2026
Version
cd24cc172f7e
Files read
207

This project is the official remote MCP server for managing Neon Postgres projects, branches, and databases via the Neon Management API and serverless SQL driver. The primary risks are that destructive SQL and infrastructure operations can be triggered through prompt injection in write mode, and that OAuth tokens returned to clients carry full upstream Neon API privileges regardless of consent-screen scope restrictions.

What it can reach

Network
Connects to the Neon Management API (console.neon.tech), Neon OAuth (oauth2.neon.tech), user Neon Postgres databases, neon.com documentation/search endpoints, feedback.neon.tech, Upstash Redis (KV_URL), and Segment/Sentry telemetry endpoints.
Secrets
Reads Neon API keys, OAuth client credentials, Redis and Postgres token-store URLs from environment variables, and retrieves database connection strings and Neon Auth/Realtime secrets on behalf of authenticated users.
Other
Can create, modify, and delete Neon projects, branches, compute endpoints, databases, roles, functions, storage buckets, and execute arbitrary SQL queries on user databases.

Findings

2 medium3 low
  1. MediumDownstream OAuth clients receive raw upstream Neon tokens with full account privileges

    app/api/token/route.ts:739

    During OAuth login, the server always requests full read/write/delete scopes (urn:neoncloud:projects:* and urn:neoncloud:orgs:*) from Neon's upstream OAuth provider and returns the resulting upstream access_token directly to the MCP client. Even when a user restricts a client on the consent page to read-only mode, a single project, specific tool categories, or a pinned Postgres role, those restrictions are only enforced when calling through this MCP server—the bearer token itself can be used directly against https://console.neon.tech/api/v2 with full account access. Additionally, /api/revoke only deletes the token from the local database without revoking it upstream.

    Fix: Issue an opaque MCP-server-minted token to downstream OAuth clients and keep the upstream Neon OAuth access and refresh tokens server-side in the token store, or request narrowed upstream scopes and forward revocation requests to the upstream OAuth server.

  2. MediumQuery tuning tools silently ignore the role_name parameter and run as database owner

    mcp/tools/tools.ts:1256

    Both prepare_query_tuning and complete_query_tuning advertise an optional role_name input parameter in their schemas to execute SQL under a specific Postgres role, but the handlers omit params.role_name when calling handleQueryTuning and handleCompleteTuning. On connections that do not have a grant-level role pin (?roleName=), SQL statements in these tools silently run as the privileged database owner instead of the requested role.

    Fix: Pass roleName: params.role_name into handleQueryTuning and handleCompleteTuning, and forward it to handleExplainSqlStatement, handleDescribeTableSchema, and handleRunSqlTransaction.

  3. Lowdescribe_branch creates and drops a function in public even in read-only mode

    mcp/tools/handlers/describe-branch.ts:68

    Although describe_branch (also reachable via the fetch tool) is marked readOnlySafe: true and exposed in read-only mode, it runs CREATE OR REPLACE FUNCTION public.show_db_tree() and DROP FUNCTION IF EXISTS public.show_db_tree() outside of a READ ONLY transaction. Calling this tool performs DDL writes in the target database and will overwrite and delete any existing user function named public.show_db_tree.

    Fix: Replace the temporary PL/pgSQL function in DESCRIBE_DATABASE_STATEMENTS with a pure SELECT query using UNION ALL and WITH RECURSIVE inside a readOnly: true transaction.

  4. LowOAuth protected resource metadata trusts X-Forwarded-Host and Host headers

    lib/oauth/protected-resource-metadata.ts:40

    resolveRequestOrigin constructs the OAuth authorization_servers origin and WWW-Authenticate resource_metadata URL from the incoming x-forwarded-host or host header rather than SERVER_HOST. In self-hosted deployments where a reverse proxy does not strip or validate these headers, an attacker can spoof the host header to direct MCP clients to an attacker-controlled authorization server.

    Fix: Derive the origin from the trusted SERVER_HOST configuration value (or an explicit allowlist of hosts) rather than unvalidated request headers.

  5. LowSegment analytics and Sentry PII collection are enabled by default with hardcoded keys

    lib/config.ts:42

    The configuration defaults to hardcoded production keys for Segment (track.neon.tech) and Sentry, and mcp/sentry/instrument.ts enables sendDefaultPii: true. Anyone self-hosting this server will send user account details, tool invocation events, IP addresses, and error traces to Neon's telemetry endpoints unless NEON_MCP_DISABLE_ANALYTICS=1 is set and SENTRY_DSN is overridden.

    Fix: Default ANALYTICS_WRITE_KEY and SENTRY_DSN to empty strings so telemetry is opt-in via environment variables on self-hosted deployments.