---
title: "How to connect Claude to Postgres via MCP"
slug: "connect-claude-to-postgres-via-mcp"
category: "howto"
tags: ["howto", "mcp", "postgres", "claude-code", "tutorial", "ai-agents", "database"]
status: "stable"
last_updated: 2026-08-14
summary: "Install the MCP postgres server, configure credentials safely, connect from Claude Code, and run a test query to confirm the integration works."
related: ["[[ai-agents/mcp-servers]]", "[[ai-agents/mcp-protocol]]", "[[backend/postgres]]", "[[howto/run-claude-code-with-mcp]]", "[[howto/build-an-mcp-server]]", "[[howto/set-up-postgres-locally]]", "[[ai-agents/mcp-security]]", "[[tooling/claude-code-workflow]]"]
---

## Overview

The official MCP Postgres server exposes SQL query tools that Claude Code can call during a session, letting you ask questions about schema, data, and query plans in natural language. This guide installs the server, wires credentials without hardcoding them, and runs a verification query. The MCP permission model is in [[ai-agents/mcp-servers]]; security considerations are in [[ai-agents/mcp-security]].

## Prerequisites

- Claude Code installed and authenticated. If not, follow [[howto/run-claude-code-with-mcp]] first.
- Node 22 on the path.
- A running Postgres instance. For local setup, see [[howto/set-up-postgres-locally]].
- A database user with read-only access. Never use a superuser account for MCP.

Create a read-only user if one does not exist:

```sql
CREATE ROLE mcp_readonly LOGIN PASSWORD 'strong-password-here';
GRANT CONNECT ON DATABASE mydb TO mcp_readonly;
GRANT USAGE ON SCHEMA public TO mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO mcp_readonly;
```

## Steps

### 1. Install the MCP Postgres server

The server is published as `@modelcontextprotocol/server-postgres`. Use `npx -y` in the Claude Code settings so the package is fetched on demand; no global install is needed.

Test the package resolves without errors:

```bash
npx -y @modelcontextprotocol/server-postgres --help
```

If the command prints usage, the package is reachable. If it fails with a network error, check your npm registry settings.

### 2. Store credentials safely

Never put the database password in `.claude/settings.json` directly, since that file is typically committed. Use environment variable substitution.

Export the connection string in your shell profile:

```bash
# ~/.zshrc or ~/.bashrc
export PG_MCP_URL="postgresql://mcp_readonly:strong-password-here@localhost:5432/mydb"
```

For team projects, document the expected variable name in `README.md` and add the variable to `.env.example` with a placeholder value. Add `.env` to `.gitignore`.

### 3. Configure the MCP server in `.mcp.json`

Add the Postgres server to `.mcp.json` at the project root. This is the project-scoped, shared MCP registry that Claude Code reads on startup; `.claude/settings.json` holds permissions and hooks, not server definitions.

```json
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "${PG_MCP_URL}"]
    }
  }
}
```

The `${PG_MCP_URL}` syntax reads from the environment at Claude Code startup. The connection string is never written to disk in plain text. `.mcp.json` is meant to be committed; a project-scoped server that isn't yours yet shows as "Pending approval" until you run `claude` and accept it.

### 4. Restrict permissions to read-only tools

Limit which tools Claude Code may call without prompting. Add an `allow` list to `.claude/settings.json` (not `.mcp.json`); the Postgres MCP server exposes query and schema-reading tools, so restrict to those.

```json
{
  "permissions": {
    "allow": [
      "mcp__postgres__query",
      "mcp__postgres__list_tables",
      "mcp__postgres__describe_table"
    ]
  }
}
```

Any write tool (if the server exposes one) requires manual confirmation. Pair this with the read-only database user for defense in depth. See [[ai-agents/mcp-security]] for the rationale.

### 5. Start Claude Code and verify connection

```bash
claude
```

Inside the Claude Code session:

```
/mcp
```

Expected output:

```
postgres: connected (3 tools available)
```

If the server shows "disconnected", check the troubleshooting section below.

### 6. Run a test query

Ask Claude Code to describe the schema:

```
List the tables in the database and show the columns of the users table.
```

Claude Code calls `mcp__postgres__list_tables` and `mcp__postgres__describe_table`. The response should show the real table names and column definitions.

Then run a data query:

```
How many users were created in the last 7 days?
```

Claude calls `mcp__postgres__query` with a `SELECT count(*)` statement. Verify the count matches a direct psql query.

## Verify it worked

```bash
# Confirm the connection string is set
echo $PG_MCP_URL
# postgresql://mcp_readonly:...@localhost:5432/mydb

# Confirm the user has SELECT access
psql $PG_MCP_URL -c "SELECT count(*) FROM users;"
# Returns a row count without permission errors.

# Inside claude session: /mcp shows postgres: connected
```

## Common errors

- **`postgres: disconnected` in /mcp**. The `${PG_MCP_URL}` variable is not exported in the shell that started `claude`. Add `export PG_MCP_URL=...` to your shell profile and restart the terminal.
- **`role "mcp_readonly" does not exist`**. Run the `CREATE ROLE` statement in psql connected to the target database as a superuser.
- **`permission denied for table users`**. The `GRANT SELECT` was run before the table existed. Re-run the grant after creating the table, or use `ALTER DEFAULT PRIVILEGES`.
- **Claude generates a destructive SQL query**. The `permissions.allow` list does not prevent Claude from constructing a DELETE query and asking for confirmation; the read-only database role prevents it from executing. Both layers are necessary.
- **Connection string is logged in Claude Code output**. Use the environment variable substitution syntax, not a hardcoded string. Check `.mcp.json` for any plain-text credentials and rotate them immediately.

## Related

- [[ai-agents/mcp-servers]]
- [[ai-agents/mcp-protocol]]
- [[backend/postgres]]
- [[howto/run-claude-code-with-mcp]]
- [[howto/build-an-mcp-server]]
- [[howto/set-up-postgres-locally]]
- [[ai-agents/mcp-security]]
- [[tooling/claude-code-workflow]]
