MCP PostgreSQL Server
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 Servershow 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 (reciprocal rank fusion, k = 60). 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, and drops query terms that appear in more than 40% of rows. 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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | Database host | |
| port | No | Database port (default: 5432) | |
| user | Yes | Database user | |
| database | Yes | Database name | |
| password | Yes | Database password |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, and it discloses almost nothing. It does not say whether the connection is persistent or per-call, whether credentials are stored, how failures surface, or what the tool returns (there is no output schema either).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence, front-loaded with the verb and resource, with zero filler. Its brevity is efficient, though it is arguably terse to the point of under-informing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a credential-bearing connection tool with no annotations and no output schema, the description is incomplete: no return value, no error behavior, no lifecycle semantics, and no relation to the sibling execution tools. The fully documented schema is the only reason this is not a 1.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including the port default of 5432, so the schema fully documents all five parameters. The description adds no syntax, format, or connection-string semantics beyond that, making the baseline 3 correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Connect) and resource (PostgreSQL database), which is unambiguous on its own. It does not, however, distinguish itself from siblings like execute, query, or validate_sql, so an agent cannot tell from the description whether a connection must be established first or is implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus the many sibling database tools (query, execute, list_schemas). No mention of prerequisites, whether this must precede other calls, or how long the connection persists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_tablesC
Get table structure for single or multiple tables
| Name | Required | Description | Default |
|---|---|---|---|
| schema | No | Schema name (default: public) | |
| tables | Yes | Table name(s) (comma separated list) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, yet it says nothing about the tool being read-only, the return content (columns, types, constraints, keys?), or behavior for unknown/mixed-case tables. Only the mutation-free nature can be inferred from the verb 'Get'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is efficiently sized, though it is arguably too terse given the tool's moderately complex return behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description should ideally clarify what 'structure' entails and whether results are per-table or aggregated. Parameters are fully covered by the schema, which keeps this at a minimum-viable level rather than a failing one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the 'schema' default and the comma-separated 'tables' format are already documented in the schema. The description's 'single or multiple tables' lightly reinforces the multi-table capability but adds no syntax or format detail beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get table structure') that is immediately distinguishable from list_tables and list_schemas, which return names rather than structure. It does not, however, explicitly name the sibling it supersedes, so the differentiation is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisite (e.g., must be connected first), and no routing to alternatives such as list_tables or query. The agent must infer all usage conditions from the tool name and the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
executeB
Execute an INSERT, UPDATE, or DELETE query
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL query (INSERT, UPDATE, DELETE) (use $1, $2, etc. for parameters) | |
| params | No | Query parameters (optional) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states the tool executes queries but doesn't disclose critical behavioral traits: whether it requires authentication, what permissions are needed, if changes are reversible, transaction behavior, error handling, or what happens on success/failure. For a mutation tool with zero annotation coverage, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise (one sentence) with zero waste. It's front-loaded with the core purpose and includes essential parameter syntax guidance. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given this is a mutation tool with no annotations and no output schema, the description is incomplete. It doesn't explain what happens after execution (e.g., returns row count, success/failure, error messages), security implications, or transactional behavior. For a tool that modifies data, this leaves critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (sql and params) with their types and purposes. The description adds minimal value beyond what the schema provides, mentioning the same query types and parameter placeholders ($1, $2). Baseline 3 is appropriate when schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool executes SQL queries (INSERT, UPDATE, DELETE), providing specific verb+resource. It distinguishes from the 'query' sibling tool by specifying the types of queries it handles (data manipulation vs. likely SELECT queries). However, it doesn't explicitly mention database operations or contrast with all siblings like 'connect_db'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for data modification queries (INSERT/UPDATE/DELETE) versus the 'query' tool likely for SELECT queries, but doesn't explicitly state when to use this tool versus alternatives. No guidance on prerequisites (like needing an established connection) or exclusions is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_schemasA
List all schemas in the database
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. The verb 'List' indicates a read-only operation, but the description does not disclose permissions, return format, or any potential side effects. It is minimally adequate but lacks extra behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no filler. Every word earns its place, and it is front-loaded with the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema), the description is largely complete. It clearly states the tool lists all schemas in the database, which is sufficient for an agent to understand the tool's scope, though it does not mention details like whether system schemas are included.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters, the schema already fully covers parameter semantics. The baseline of 4 applies, and the description adds no unnecessary parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('all schemas in the database'), making the tool's purpose clear. It also implicitly distinguishes from siblings like list_tables (tables vs schemas) and describe_programmable_object.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance on when to use this tool versus alternatives such as list_tables or describe_table. It only states what the tool does, leaving the agent to infer usage context without explicit comparisons or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesC
List tables in the database
| Name | Required | Description | Default |
|---|---|---|---|
| schema | No | Schema name (default: public) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool lists tables, implying a read-only operation, but doesn't specify whether it returns all tables, includes system tables, requires specific permissions, or handles errors. This leaves significant gaps in understanding the tool's behavior beyond the basic action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise—a single, clear sentence that directly states the tool's purpose without any unnecessary words. It is front-loaded and efficiently communicates the core functionality, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is incomplete for a tool that interacts with a database. It doesn't address key contextual aspects like what the output looks like (e.g., a list of table names, metadata), error conditions, or dependencies on other tools (e.g., 'connect_db'). This leaves the agent with insufficient information to use the tool effectively in complex scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with the single parameter 'schema' documented as 'Schema name (default: public)'. The description adds no additional meaning about parameters beyond what the schema provides, such as explaining the significance of the schema parameter or how it affects the listing. With high schema coverage, the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and resource ('tables in the database'), making the tool's purpose immediately understandable. However, it doesn't differentiate from sibling tools like 'list_schemas' or 'describe_table', which would require specifying what makes this listing operation unique.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing a database connection via 'connect_db'), nor does it explain how it differs from 'list_schemas' (which might list schemas instead of tables) or 'describe_table' (which might provide detailed metadata).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_vector_tablesA
List tables that have pgvector columns (vector or halfvec), with schema, column, and data type.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses the return shape (schema, column, data type), which is genuinely useful, but says nothing about whether it is read-only (implied by 'List'), pagination, cost on large catalogs, or permission requirements. For a zero-parameter listing tool the risk is low, so partial credit is warranted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and the filtering scope, with the return contents trailing. No filler and nothing to trim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must hint at what comes back – it does, listing schema, column, and data type. Combined with zero parameters and a simple read, this is nearly sufficient; only the absence of any pagination/volume note keeps it short of complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies; the description correctly avoids inventing parameter talk.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and a precisely scoped resource (tables containing pgvector vector/halfvec columns), plus what each row reports (schema, column, data type). That scope distinguishes it from the generic sibling list_tables, though it never names the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the scope: an agent can infer this is the right call when hunting for vector-enabled tables before vector_search or vector_execute. However, it gives no explicit when-to-use versus list_tables/describe_tables and no prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queryC
Execute a SELECT query
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL SELECT query (use $1, $2, etc. for parameters) | |
| params | No | Query parameters (optional) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Execute a SELECT query') but doesn't describe what happens: whether it returns results, error handling, performance implications, or security constraints (e.g., read-only access). For a query execution tool, this leaves critical behavioral traits unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero waste. It's front-loaded with the core action and resource, making it immediately understandable without unnecessary elaboration. Every word earns its place by directly conveying the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of a database query tool with no annotations and no output schema, the description is incomplete. It doesn't explain return values (e.g., result sets, error formats), usage context (e.g., requires prior connection), or limitations (e.g., query timeout, row limits). For a tool that executes arbitrary SQL, this leaves significant gaps for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters ('sql' and 'params') with clear descriptions. The description adds no additional meaning beyond what the schema provides, such as examples of valid SQL syntax or parameter binding details. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Execute') and resource ('SELECT query'), making the purpose unambiguous. It distinguishes from siblings like 'connect_db' or 'list_tables' by focusing on query execution rather than connection or metadata listing. However, it doesn't explicitly differentiate from 'execute' which might handle non-SELECT queries, leaving some ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'execute' (which might handle INSERT/UPDATE) or 'describe_table' (for schema inspection). It lacks context about prerequisites (e.g., requires an established database connection) or exclusions (e.g., only for SELECT queries, not data modification).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_mentionsC
Trigram search. Resolve mentioned entities to database matches. Returned rows are candidates, not confirmed matches.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows per query string (default 5, max 100) | |
| table | Yes | Table name | |
| where | No | SQL WHERE fragment applied with the trigram predicate (no WHERE keyword) | |
| schema | No | Schema (default: public) | |
| columns | No | Payload columns. Omit for all. score is added unless include_scores is false. | |
| mentions | Yes | Search strings (max 20). A single string is accepted as one element. | |
| operator | No | operator=trgm (default) uses % and similarity(). operator=word uses %> and word_similarity(). | |
| text_column | Yes | Text column to match. A trigram index on this column is optional. | |
| include_scores | No | Default true. When false, omit the score column. Ranking is unchanged. | |
| response_format | No | Empty for JSON. "markdown" returns one table per query string, headed Results for {text}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It usefully warns that results are candidates rather than confirmed matches, but omits whether the operation is read-only, what happens with no trigram index, and any performance or permission considerations for a 10-parameter database tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with the mechanism front-loaded and the most decision-relevant caveat placed last. Nothing is padded, though the sentences are terse enough that some explanatory value is left on the table.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description does the minimum: it hints at the matching mechanism and result semantics. It does not describe the returned row structure, scoring behavior, or multi-mention result grouping, leaving the agent to infer these from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents limit, operator, include_scores, and the rest. The description's mention of trigram matching and the optional index marginally aids interpretation of operator and text_column, but adds no new parameter-level detail. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific mechanism (trigram search) and a concrete verb+resource (resolve mentioned entities to database matches). It is distinguishable from siblings like vector_search and query, though it never states the operation is a fuzzy string match against a single text column, which would sharpen the contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to prefer this over query, vector_search, or execute. The only contextual hint is the caveat that returned rows are candidates, which tells the agent how to interpret results but not when to reach for this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_sqlB
Validate SQL. Returns the string 'true' if the SQL is valid, or an error message string if invalid.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL query to validate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a non-obvious behavioral trait: the return is the literal string 'true' on success or an error message string on failure. However, it says nothing about whether validation merely parses syntax or executes/resolves against a connection, what dialect is assumed, or whether any permissions/state are touched -- significant gaps for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the purpose and then the exact return contract. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since no output schema exists, the description helpfully explains the return values, which is the key missing piece it covers. But it omits dialect assumptions, what 'valid' means semantically (parse-only vs. plan/resolve), and any workflow guidance, leaving the definition adequate but incomplete for a no-annotation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single 'sql' parameter, so the schema already documents it. The description adds no syntax, dialect, or format detail beyond what the schema provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource -- 'Validate SQL' -- which is unambiguous and clearly distinct from siblings like execute, query, or execute. It stops short of naming an alternative or scope (e.g., syntax-only vs. semantic/plan validation), so it does not fully differentiate the role from the sibling execution tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus execute/query, no mention of a validate-before-execute workflow, and no exclusions or prerequisites. The usage is only inferable from the tool name, which is minimal guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | update: single row | |
| text | No | Literal to embed. Required for insert. For update, exactly one of text or text_column. | |
| limit | No | update + text_column: max rows (default 10, max 100) | |
| table | Yes | ||
| where | No | update: SQL WHERE fragment (no WHERE keyword) | |
| fields | No | insert only: other column values | |
| schema | No | Default: public | |
| id_column | No | Default: id | |
| operation | Yes | insert or update | |
| text_column | No | insert: also store `text` in this varchar. update: read this column per row and embed it. | |
| embedding_column | Yes | vector or halfvec column to write |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It usefully discloses the single-row constraint for id/where and that update overwrites the vector column, but says nothing about reversibility, permission requirements, what happens when where matches multiple rows in insert mode, or the return shape. Adequate but leaves real operational risk undocumented.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, then dispatches insert vs update in compact clauses. The telegraphic style is efficient but occasionally cryptic ('update: write only the vector'), trading readability for density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters, no annotations, and no output schema, the description must cover behavior and results. It handles operation modes and source selection well, but omits the return/effect signal (rows affected) and error behavior, leaving gaps for a mutation tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 91%, so the baseline is 3, and the description adds genuine value beyond it by explaining parameter interactions: exactly one of text/text_column for update, and the id-vs-where single-row rule. It does not add much on `fields`, `schema`, or `id_column`, which remain schema-only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (insert/update) and resource (vector/halfvec column) and the mechanism (embedding text). It explicitly carves out the sibling boundary: 'Use execute for delete and non-vector columns', so an agent can distinguish it from execute and query without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear mode-selection guidance: insert requires `text` and optionally persists via `text_column`; update reads from `text` (single row via id or where) or `text_column` (per-row, with optional limit). It also names the alternative tool for out-of-scope operations. No explicit exclusions or prerequisites (permissions, row-count safety) beyond the tool routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows (default 10, max 100) | |
| query | Yes | Search strings (max 20). One element searches that text. Multiple elements each return their own group, tagged Results for {text}. A single string is accepted as one element. | |
| table | Yes | Table name | |
| where | No | SQL WHERE fragment applied before ranking (no WHERE keyword) | |
| metric | No | cosine (default), l2, or ip. Must match the HNSW opclass to use the index. | |
| schema | No | Schema (default: public) | |
| columns | No | Payload columns. Omit for all except embedding and *hash. | |
| lexical | No | fts (default) or trgm. Requires text_column. fts for passages. trgm for short names that have a trigram index. | |
| text_column | No | Text column for hybrid search. Use the passage column for fts, or the short name column for trgm. Omit for dense search only. | |
| include_scores | No | Default true. When false, omit distance, and omit rrf, dense_rank, and lexical_rank on hybrid search. Ranking is unchanged. | |
| response_format | No | Empty for JSON. "markdown" returns one table per query element, headed Results for {text}, using the same columns as the JSON rows. | |
| embedding_column | Yes | vector or halfvec column |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it discloses that a where clause forces hnsw.iterative_scan=strict_order, that ef_search is raised above a 40-candidate limit, that the default payload omits embedding and *hash, and how include_scores toggles output columns without changing ranking. It stops short of stating auth requirements, cost/latency, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is dense and front-loaded, but it reads as an undifferentiated wall of parameter behavior with no grouping or structure, which makes it hard to scan for the one fact needed at call time. Most sentences earn their place individually, but the lack of structure costs it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, no-annotation tool with no output schema, the description is largely sufficient: it covers return shape (default payload, score columns, markdown format), the array grouping model, and the tuning side effects. Minor gaps remain around failure modes and resource limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: it explains the query-array semantics (one element = one search; N elements = N grouped results), the RRF fusion behavior when text_column is set, and the exact columns include_scores adds. This goes past restating parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Nearest-neighbor search') and immediately names the mechanism (embeds query strings, ranks with pgvector), so an agent knows exactly what the tool produces. It does not, however, distinguish itself from siblings like vector_execute or query, leaving the agent to infer which retrieval tool applies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is meaningful parameter-level guidance ('Omit text_column for dense search only', 'fts for passages. trgm for short names that have a trigram index'), which tells the agent when to choose each mode. But there is no tool-level when-to-use guidance or exclusion relative to alternatives such as vector_execute, so routing between siblings is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.1.3- First observed
connect_db - First observed
describe_tables - First observed
execute - First observed
list_schemas - First observed
list_tables - First observed
list_vector_tables - First observed
query - First observed
resolve_mentions - First observed
validate_sql - First observed
vector_execute - First observed
vector_search
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.
Maintenance
Related MCP Connectors
PostgreSQL, MySQL, OpenAPI/Swagger, and shared Agent Memory with scoped access.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
- HutchDBOAuthcom.hutchdb
Store, query, and update structured data from any AI agent
Database for your AI agent. Turn its output into data, docs, skills, and apps you can actually use.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables secure, AI-driven PostgreSQL database administration, observability, and querying with support for extensions like PostGIS and pgvector, connection pooling, and advanced tool filtering.77 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.531 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with PostgreSQL databases through natural language queries, schema inspection, and safe SQL execution.6 npm1-