> ## Documentation Index
> Fetch the complete documentation index at: https://midplane.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect Neon to your AI agent

> Point Cursor or Claude Code at Neon Postgres through Midplane — pooled vs direct endpoints, SNI routing, and giving an agent its own branch.

Neon connection strings are simpler than most: one hostname, one pooled variant, TLS always on. The parts worth knowing are how Neon routes connections (by TLS SNI, which changes what a broken client looks like), and the fact that Neon's branching makes it easy to give an agent a database that isn't production at all.

Once connected, your agent reaches Neon only through Midplane: every statement is parsed, checked against [policy](/docs/policies/overview), and written to the [audit trail](/docs/concepts/audit-trail) before it runs.

## Pooled or direct

Neon's pooled endpoint is the direct hostname with `-pooler` inserted after the endpoint ID:

```
# Direct
postgres://user:password@ep-cool-darkness-123456.eu-central-1.aws.neon.tech/dbname?sslmode=require

# Pooled
postgres://user:password@ep-cool-darkness-123456-pooler.eu-central-1.aws.neon.tech/dbname?sslmode=require
```

Either works with Midplane. **Pooled** is the better default — agent traffic is bursty and short-lived, which is exactly what PgBouncer is for. The one limitation to know: the pooled endpoint runs in transaction mode, so SQL-level `PREPARE` and `EXECUTE` statements aren't supported. Protocol-level prepared statements, which is what drivers actually use, work fine.

`sslmode=require` isn't optional — Neon refuses plaintext connections.

## SNI routing, and the error when it fails

The Postgres wire protocol doesn't carry the server hostname, so Neon reads it from the TLS **SNI** extension to decide which compute endpoint you meant. A client that doesn't send SNI gets:

```
ERROR: The endpoint ID is not specified. Either upgrade the Postgres client
library (libpq) for SNI support or pass the endpoint ID (the first part of the
domain name) as a parameter: '&options=endpoint='
```

Midplane sends SNI on every connection, including the **Test connection** probe, so you shouldn't hit this. If you do, name the endpoint explicitly:

```
postgres://user:password@ep-cool-darkness-123456.eu-central-1.aws.neon.tech/dbname?sslmode=require&options=endpoint%3Dep-cool-darkness-123456
```

The endpoint ID is the first label of the hostname.

## Create a least-privilege role

Don't reuse `neondb_owner`. Create a role for Midplane, from the SQL editor or any `psql` session:

```sql theme={null}
CREATE ROLE midplane LOGIN PASSWORD 'a-strong-password';
GRANT CONNECT ON DATABASE neondb TO midplane;
GRANT USAGE ON SCHEMA public TO midplane;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO midplane;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO midplane;
```

Neon's console also creates roles under **Roles** if you'd rather have it manage the password. Either way, paste the resulting connection string into **Connect Postgres** in the [dashboard](https://app.midplane.ai) and leave the default access level at `read`.

## Give the agent a branch

Neon branches are copy-on-write, so a branch of production costs almost nothing and carries real data. That makes a genuinely useful pattern available: point Midplane at a **branch**, not at `main`.

The agent gets production-shaped data to reason about, schema changes it makes are contained, and you still get the audit trail and [column masking](/docs/concepts/masking) on everything it reads. Each branch has its own endpoint hostname, so it's a separate connection string — add it as [another database](/docs/cloud/projects#manage-databases-on-a-project) on the same project, or a separate project if it should stay isolated.

Reach for `main` only when the agent's job actually requires live data.

## Two things to watch

**Autosuspend.** A Neon compute scales to zero when idle and takes a moment to wake. The first agent query after a quiet period pays that cold start; it's latency, not an error, but it can look like a hang in a client with a short timeout.

**IP Allow.** Neon's IP Allow feature restricts which addresses may connect. Midplane Cloud doesn't publish a fixed egress IP range, so there's no entry you can add that admits Midplane without admitting everything — which would defeat the feature. If you need IP Allow enforced, [self-host](/docs/self-host/deploy) Midplane and allow the address it runs from. See [connect your database](/docs/connect/overview#a-host-midplane-can-reach) if that isn't an option for your team.

## A note on Neon's MCP server

Neon ships its own [MCP server](https://neon.com/docs/ai/connect-mcp-clients-to-neon) for managing Neon itself — projects, branches, and the Neon API — and their documentation is explicit that it's "intended for local development and IDE integrations only," not for production environments.

That's a fair description of the difference in scope. Midplane fronts the *database* with a SQL parser, per-table access, and a durable audit trail, which is what makes pointing an agent at data you care about defensible. The two compose: Neon's server for infrastructure, Midplane for the rows.

## Next steps

<Columns cols={2}>
  <Card title="Write a policy" icon="shield-check" href="/docs/policies/overview" horizontal>
    Grant the reads and writes your agent actually needs.
  </Card>

  <Card title="Read the audit trail" icon="scroll-text" href="/docs/concepts/audit-trail" horizontal>
    Every attempt, decision, and result your agent produced.
  </Card>
</Columns>
