MCP PostgreSQL Server
Connects an agent to PostgreSQL and exposes tools for connection management, schema inspection, SQL reads/validation/writes, trigram mention resolution, and optional pgvector embedding search/write.
Open or replace a PostgreSQL connection with
connect_db.Inspect schemas, tables, and table structures, including primary keys, defaults, PostGIS geometry/geography, and vector/halfvec types.
Run read queries (
SELECT,WITH,EXPLAIN) with parameters, validate SQL viaEXPLAIN, and executeINSERT/UPDATE/DELETEwith row counts.Resolve entity mentions with trigram/word similarity against a text column.
List vector tables and perform dense or hybrid pgvector nearest-neighbor search using text queries, cosine/L2/IP metrics, FTS/trigram fusion, multi-query grouping, JSON/markdown output, and optional scores.
Insert/update vector columns by embedding text, optionally persisting text and other fields.
Support stdio and Streamable HTTP transports, with HTTP sessions supplying per-session database credentials via
X-PG-*headers and process-wide embedding settings.
Allows using Ollama as an OpenAI-compatible embeddings endpoint for vector search and vector_execute tools, enabling text-to-embedding conversion for pgvector-backed columns.
Provides tools for connecting to and interacting with a PostgreSQL database, including schema inspection, running SELECT/WITH/EXPLAIN queries, executing INSERT/UPDATE/DELETE, validating SQL, and resolving mentions via trigram search. Also supports pgvector for vector search and embedding-based operations when the vector extension is available.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP PostgreSQL Server show me the schema of the users table"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP PostgreSQL Server
MCP server that gives an agent a PostgreSQL connection and a fixed set of tools. The server holds the connection, runs the SQL, and returns rows. The agent does not open pg itself.
The primary purpose is normal database work: connect, inspect the schema, run reads, check SQL, and run writes. Search and embedding tools are a second layer. They run when the database has pgvector.
What it does
PostgreSQL. connect_db opens the connection. list_schemas, list_tables, and describe_tables show the agent what it can query. describe_tables includes primary keys, defaults, PostGIS geometry(type, srid) and geography(type, srid), and vector / halfvec types when those catalogs exist. query runs SELECT, WITH, and EXPLAIN. execute runs INSERT, UPDATE, and DELETE. validate_sql runs EXPLAIN and returns true or the error. resolve_mentions ranks name matches with pg_trgm (similarity or word_similarity). Parameters use $1 or ?.
pgvector. list_vector_tables finds vector and halfvec columns. vector_search sends the query text to an OpenAI-compatible /v1/embeddings endpoint (vLLM, Ollama, or a hosted API), then ranks rows in PostgreSQL with cosine, L2, or inner product. Pass text_column to fuse that ranking with English full text or trigrams. The fused score keeps a closer embedding ahead of a weak keyword hit. vector_execute embeds text and inserts or updates the vector column. The agent passes text. The server fetches the embedding, checks its length against the column, and binds it as a query parameter.
PostgreSQL tools need only a database connection. list_vector_tables needs the vector extension. vector_search and vector_execute also need EMBEDDING_URL and EMBEDDING_MODEL.
Related MCP server: PostgreSQL MCP Server
Why this shape
queryaccepts onlySELECT,WITH, andEXPLAIN.executeaccepts onlyINSERT,UPDATE, andDELETE. A read-only database role still blocks writes ifexecuteis called.Schema output includes GIS and vector types, so the agent can write SQL that matches the column.
Vector tools take text. The agent does not build or paste embedding arrays.
One search call accepts up to 20 strings and can return JSON or one markdown table per string.
stdio serves a local MCP client. Streamable HTTP serves a remote client, and each session can name its own database in
X-PG-*headers. Embedding settings stay process-wide.
Requirements
Node.js 20 or newer
PostgreSQL, for every tool
pg_trgm, forresolve_mentionsand for hybrid search withlexical: "trgm"vectorextension forlist_vector_tablesvectorextension, plusEMBEDDING_URLandEMBEDDING_MODEL, forvector_searchandvector_execute
pgvector HNSW indexes on vector support at most 2000 dimensions. For a 2560-dimension model such as Qwen3-Embedding-4B, store the column as halfvec(2560).
Install
From a clone:
npm install
npm run buildOr, once published:
npx -y mcp-postgres-serverConfiguration
Database credentials and embedding settings are not interchangeable. Put each group in the file below and leave it out of the other.
What | Where | Variables |
Database, stdio | MCP client |
|
Database, HTTP |
|
|
Embeddings |
|
|
On startup the server loads .env and fills only variables the process does not already have. The stdio client starts the process with PG_* already set, so those values stay. .env then supplies the embedding endpoint. Several stdio entries can point at different databases and still share one .env.
connect_db can replace the database connection after startup. It does not read .env, and it does not change the embedding endpoint.
EMBEDDING_TIMEOUT_MS (default 30000), EMBEDDING_MAX_RESPONSE_BYTES (default 52428800), PORT (default 3000), and TRANSPORT (http or stdio) have defaults. They are not in the example files. Set them in the process environment only when you need a different value.
Local files and git
Committed files use placeholders. Copy them and put real hosts, passwords, and URLs only in the gitignored copies.
Commit this | Keep local (gitignored) | What to put in it |
|
| Embedding endpoint only |
|
| Database credentials for |
|
| HTTP Inspector client: URL plus |
grants.sql is site-specific and gitignored. It is not part of the server.
cp .env.example .env
cp config-stdio.example.json config-stdio.json
cp config.example.json config.jsonOn Windows PowerShell:
Copy-Item .env.example .env
Copy-Item config-stdio.example.json config-stdio.json
Copy-Item config.example.json config.jsonEdit the copies. Do not put hosts, passwords, API keys, or internal URLs in the example files.
Environment
Variable | Set in | Required | Purpose |
| stdio | yes, unless | Database host |
| stdio | no | Default |
| stdio | yes, same as host | Database user |
| stdio | yes, same as host | Database password |
| stdio | yes, same as host | Database name |
|
| vector tools only | OpenAI-compatible endpoint, for example |
|
| vector tools only | Model name sent to that endpoint |
|
| no | Reject a response whose length does not match. Not sent to the API |
|
| no | Sent as |
| process env | no | Default |
| process env | no | Default |
| process env | no | HTTP listen port. Default |
| process env | no |
|
stdio
Default transport. Put only PG_* in the client env. Leave EMBEDDING_* in .env.
{
"mcpServers": {
"postgres": {
"command": "node",
"args": ["build/index.js"],
"env": {
"PG_HOST": "localhost",
"PG_PORT": "5432",
"PG_USER": "postgres",
"PG_PASSWORD": "postgres",
"PG_DATABASE": "postgres"
}
}
}
}Use the absolute path to build/index.js when the client does not start in this directory.
Streamable HTTP
npm startThat builds and runs node build/index.js --http. TRANSPORT=http does the same.
Method | Path | Role |
|
| Initialize and tool calls |
|
| Server-to-client stream |
|
| End the session |
|
|
|
Send database credentials on the initialize request. Later calls in that session reuse them. If the headers are absent, the server uses PG_* from the process environment. Embedding settings still come from .env. config.example.json is an Inspector client config for this transport: it has the server URL and the X-PG-* headers, not the embedding variables.
Inspector
npm run inspectorThat reads config-stdio.json. Copy it from config-stdio.example.json first.
Tools
PostgreSQL
These run against the connected database. pgvector is not required.
Tool | What it does |
| Connect with |
| Run |
| Run |
| Run |
| List schema names. |
| List tables. Optional |
| Structure for a comma-separated |
| Trigram search. |
pgvector
These need the vector extension and EMBEDDING_URL plus EMBEDDING_MODEL in .env. list_vector_tables only needs the extension.
Tool | What it does |
| Tables that have a |
| Embed each string in |
| Embed text and |
SQL
{
"sql": "SELECT id, name FROM places WHERE id = $1",
"params": [1]
}execute uses the same sql and params shape. Use query for SELECT.
Mentions
{
"table": "places",
"text_column": "name",
"mentions": ["harbour", "old town"],
"operator": "trgm",
"limit": 5,
"response_format": "markdown"
}operator is trgm (default) or word. where is a SQL fragment without the WHERE keyword. include_scores defaults to true.
Vector search
One string returns rows. Several strings run the same search once per string and return a group per string.
{
"table": "documents",
"embedding_column": "embedding",
"query": ["permits near the river"],
"where": "status = 'active'",
"columns": ["id", "content"],
"limit": 10
}Hybrid search: set text_column. lexical is fts (default) or trgm.
ftsuses English full text. It stems, drops stop words, keeps Arabic, drops query terms that appear in more than 40% of rows, and ranks the rest by inverse document frequency. Use it on a passage column.trgmusesword_similarity()abovepg_trgm.word_similarity_threshold. Use it on a short name column that has a trigram index.
{
"schema": "catalog",
"table": "documents",
"embedding_column": "embedding",
"text_column": "body",
"lexical": "fts",
"query": ["archaeological sites", "district boundaries"],
"response_format": "markdown",
"limit": 10
}metric is cosine (default), l2, or ip. It must match the HNSW operator class for the index to be used. A where clause sets hnsw.iterative_scan=strict_order for that query. The default payload omits the embedding column and columns named hash or ending in _hash. include_scores defaults to true and adds distance, plus rrf, dense_rank, and lexical_rank on hybrid search. rrf is the sort score: for cosine, similarity plus at most 0.05 for the strongest lexical hit.
Vector write
vector_execute writes the vector column only. Delete rows, or change other columns, with execute.
Insert embeds text. text_column also stores that text. fields sets other columns.
{
"operation": "insert",
"table": "documents",
"embedding_column": "embedding",
"text": "River permit application",
"text_column": "content",
"fields": { "status": "active" }
}Update with text must match one row (id, or a where that returns a single row). Update with text_column embeds that varchar on each matched row. id_column defaults to id. limit defaults to 10 and caps at 100.
{
"operation": "update",
"schema": "catalog",
"table": "documents",
"embedding_column": "embedding",
"text_column": "body",
"where": "body IS NOT NULL AND embedding IS NULL",
"limit": 10
}Development
npm install
npm run watch
npm run inspector
npm run start:httpnpm start builds, then starts the HTTP transport.
Security
Queries use parameters. Identifiers passed to the vector and mention tools are restricted to simple names. where is a SQL fragment, so give the database role only the rights the agent should have. Prefer a read-only role when the agent does not need to write.
Do not commit .env, config.json, or config-stdio.json.
License
Available Tools
11 toolsconnect_dbC
Connect to PostgreSQL database.
Inputs: host (required), user (required), database (required), password (required), +1 more.
describe_tablesC
Get table structure for single or multiple tables
Inputs: tables (required), schema.
executeB
Execute an INSERT, UPDATE, or DELETE query
Inputs: sql (required), params.
list_schemasA
List all schemas in the database
Inputs: no named parameters.
list_tablesC
List tables in the database
Inputs: schema.
list_vector_tablesA
List tables that have pgvector columns (vector or halfvec), with schema, column, and data type.
Inputs: no named parameters.
queryC
Execute a SELECT query
Inputs: sql (required), params.
resolve_mentionsC
Trigram search. Resolve mentioned entities to database matches. Returned rows are candidates, not confirmed matches.
Inputs: table (required), mentions (required), text_column (required), limit, +6 more.
validate_sqlB
Validate SQL. Returns the string 'true' if the SQL is valid, or an error message string if invalid.
Inputs: sql (required).
vector_executeA
Insert or update a vector/halfvec column by embedding text. insert: embed text (optional fields, optional persist via text_column). update: write only the vector. Source is text (single row: id, or where that matches one row) or text_column (embed each matched row, where/id, optional limit). Use execute for delete and non-vector columns.
Inputs: table (required), operation (required), embedding_column (required), id, +7 more.
vector_searchA
Nearest-neighbor search. Embeds each query string and ranks with pgvector. query is an array: one element runs one search; multiple elements run the same search (same table, where, columns, limit) once per element and return grouped results. Pass text_column to fuse each ranking with a lexical list using reciprocal rank fusion (k=60). lexical=fts (default) uses English full text: stems, drops stop words, keeps Arabic, and drops query terms that appear in more than 40% of rows. lexical=trgm uses pg_trgm word_similarity above pg_trgm.word_similarity_threshold. Omit text_column for dense search only. A where clause sets hnsw.iterative_scan=strict_order for that query. hnsw.ef_search is raised when the candidate limit is above 40. Default payload omits embedding and *hash. include_scores defaults to true and adds distance, plus rrf, dense_rank, and lexical_rank when hybrid. Set include_scores false to omit those columns. response_format=markdown returns one markdown table per query element.
Inputs: query (required), table (required), embedding_column (required), limit, +8 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Most tools are clearly distinct: query (SELECT) vs execute (DML), list_* vs describe_*, and vector_search vs resolve_mentions have different modalities. Minor overlap exists between query and execute (both run SQL, split by statement type) and between vector_search and resolve_mentions (both search), but descriptions help disambiguate.
Most tools follow a verb_noun or verb_noun_phrase pattern (connect_db, validate_sql, list_schemas, describe_tables, vector_search). However, 'query' and 'execute' are bare verbs that break the pattern, and 'resolve_mentions' is more descriptive than action-oriented. The mix is readable but not fully consistent.
11 tools is well within the ideal range for a database server and each tool covers a distinct capability (connection, querying, validation, schema introspection, vector operations). No tool feels redundant or excessive.
Core row-level CRUD is covered (query for SELECT, execute for INSERT/UPDATE/DELETE) and schema introspection plus vector features are present. However, there is no DDL support (CREATE/ALTER/DROP), no transaction control, and no explicit disconnect, which are notable gaps for a general PostgreSQL server.
Related MCP Connectors
PostgreSQL, MySQL, OpenAPI/Swagger, and shared Agent Memory with scoped access.
Supabase-compatible Postgres for agents: projects, branches, SQL, auth, storage, email.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Store, query, and update structured data from any AI agent
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables secure, AI-driven PostgreSQL database administration, observability, and querying with support for extensions like PostGIS and pgvector, connection pooling, and advanced tool filtering.119 npm12MIT
- AlicenseNot gradedqualityNot gradedmaintenanceProvides AI assistants with safe, controlled access to PostgreSQL databases with read-only defaults, granular permissions, query safety features, and schema introspection capabilities.1-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with PostgreSQL databases through schema intelligence, query execution, and DBA tooling including index analysis and health monitoring. Features configurable access levels and audit logging for secure database operations.432 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with PostgreSQL databases through natural language queries, schema inspection, and safe SQL execution.4 npm1ISC