Quick takeaways

  • Use a dedicated, read-only Postgres role for the MCP server.
  • Store the connection string in claude_desktop_config.json, not in chat.
  • Start with schema inspection and SELECT queries before allowing any writes.
  • Run the server with --access-mode=restricted; the old npm reference server is deprecated and unsafe.

Building MCP servers

Anthropic's guide walks through building an MCP server, applicable to Postgres and other data sources.

What the Postgres MCP server does

The Postgres MCP server exposes database tools to Claude Desktop. With it, Claude can list tables, describe schemas, read sample rows, and run SQL queries through a structured interface rather than copying and pasting context into chat.

This is useful for exploring unfamiliar schemas, drafting queries, summarizing data patterns, and pairing on debugging. It is not a replacement for a database IDE, and it should never be given unrestricted write access without review.

Prerequisites

  • Claude Desktop installed on macOS, Windows, or Linux.
  • Python 3.12 or newer with uv installed (or Docker, if you prefer containers).
  • A PostgreSQL database you can connect to, with credentials that support role-based access.
  • Basic familiarity with SQL and JSON config files.

Install the server

Do not use the old reference server. The npm package @modelcontextprotocol/server-postgres was archived in 2025 and has an unpatched SQL-injection flaw that lets stacked queries escape its read-only mode. This guide uses Postgres MCP Pro instead, which enforces read-only access by parsing every statement. Run it with uvx so there is nothing to install globally:

uvx postgres-mcp --access-mode=restricted

The --access-mode=restricted flag is essential: the server defaults to unrestricted read/write, and restricted mode rejects any statement that is not a read. Alternatively, use pipx install postgres-mcp or the crystaldba/postgres-mcp Docker image. Verify the command starts without errors in a terminal before adding it to Claude Desktop; it will wait for the connection string, which the config below provides.

Claude Desktop config

Open claude_desktop_config.json. On macOS it lives at ~/Library/Application Support/Claude/claude_desktop_config.json. On Windows look in %APPDATA%/Claude. Add the Postgres server under mcpServers:

{
  "mcpServers": {
    "postgres": {
      "command": "uvx",
      "args": ["postgres-mcp", "--access-mode=restricted"],
      "env": {
        "DATABASE_URI": "postgresql://mcp_readonly:REPLACE_ME@localhost:5432/analytics"
      }
    }
  }
}

Replace REPLACE_ME with the actual password. The connection string goes in the env block, not in chat. For shared machines, point DATABASE_URI at a secrets-managed file or use the Docker variant with an env file instead of plain JSON.

Database permissions

Create a dedicated read-only role. Do not reuse an application role or superuser account. The principle is simple: the assistant should see only what it needs to see.

CREATE ROLE mcp_readonly WITH LOGIN PASSWORD 'a-strong-random-password';
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;

If you want to restrict access further, grant SELECT only on specific tables or create a separate schema with views that expose a sanitized subset of data.

Read-onlySchema inspection, SELECT queries, and data summarization. Safe starting point.
Draft queriesAssistant writes INSERT, UPDATE, or DELETE statements but does not execute them.
Write accessOnly for local or disposable databases. Requires human review and audit logging.

Test the connection

  1. Save the config file and restart Claude Desktop completely.
  2. Open a new conversation and look for the tools icon or server indicator.
  3. Ask Claude: "List the tables in my Postgres database."
  4. Then ask: "Describe the schema for the users table."

If Claude returns structured schema information, the connection is working. If it says no tools are available, check the logs.

Troubleshooting

Server not foundVerify the command path and that uvx is available in your system PATH (it ships with uv).
Connection refusedCheck the host, port, and that Postgres accepts network connections from your machine.
Permission deniedConfirm the role has USAGE on the schema and SELECT on the relevant tables.
Claude sees no toolsRestart Claude Desktop. Check the developer logs for MCP server stderr output.

On macOS, you can open the Claude Desktop logs from the Help menu. Look for error messages from the MCP server process; they usually point directly to a missing dependency or bad connection string.

Related: Read MCP guide for permission design, then see What is MCP? for the broader concept.

Without AI vs. with AI

TaskWithout AIWith AI
Schema explorationAnalysts run ​`​\d​`​ and describe tables manually to understand a database.Claude lists tables, describes columns, and shows sample rows through the Postgres MCP server.
Query draftingDevelopers write SQL from scratch and iterate in a separate editor.Claude drafts SELECT queries from natural-language questions, which the analyst reviews and runs.
Data summarizationTeams export CSVs and analyze them in spreadsheets.Claude runs aggregation queries and summarizes patterns directly against the database.
PermissionsDevelopers share superuser credentials with anyone who needs data.A dedicated read-only role limits the MCP server to schema inspection and SELECT queries.
Connection stringsCredentials are pasted into chat or shared in documents.The connection string is stored in claude_desktop_config.json, not in conversation logs.

FAQ

Can the Postgres MCP server modify data?

Only if you give it a database role with write permissions. Start with a read-only role.

Is the connection string secure?

It is stored in a local config file. Keep that file restricted and avoid committing it to version control.

Can I connect to a cloud Postgres instance?

Yes, as long as your machine can reach the host and the role has the correct network permissions. Use SSL when available.

Should I use this on production?

Use a read-only replica or a sanitized analytics database for production data exploration. Avoid direct write access.

What if Claude generates a slow query?

Set statement timeouts on the database role and limit access to small tables or materialized views.

What can the Postgres MCP server do?

It exposes database tools so Claude can list tables, describe schemas, read sample rows, and run SQL queries.

Should I give the Postgres MCP server write access?

No. Start with a dedicated read-only role and add write permissions only after strong review gates are in place.

How do I create a read-only Postgres role for MCP?

Create a user with CONNECT and USAGE privileges plus SELECT on the needed schemas; avoid superuser rights.

Where is the Postgres connection string stored?

In claude_desktop_config.json. Prefer environment variables or a secrets manager instead of plain text.

Can the Postgres MCP server run on a remote database?

Yes, as long as the host and port are reachable from the machine running Claude Desktop.