Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
uvx mcp-server-pgvector
MCP client config
{
"mcpServers": {
"pgvector": {
"command": "uvx",
"args": [
"mcp-server-pgvector"
]
}
}
}An MCP server that gives LLM agents first-class access to pgvector-backed embedding tables in PostgreSQL: similarity search, hybrid (vector + full-text) search, upserts, and HNSW/IVFFlat index management.
Generic Postgres MCP servers expose raw SQL or schema introspection; this one speaks pgvector specifically — nearest-neighbor search, distance metrics, and ANN index tuning are first-class tools, not something the model has to hand-write SQL for.
| Tool | Description |
|---|---|
list_vector_tables | Discover every vector column in the database, with its dimensionality |
describe_vector_table | Columns, indexes, and approximate row count for a table |
similarity_search | k-NN search over a vector column (cosine / L2 / inner product), with structured metadata filters |
hybrid_search | Weighted blend of vector similarity and Postgres full-text search (ts_rank_cd) |
upsert_embedding | Insert or update a row's embedding + metadata |
create_vector_index | Create an HNSW or IVFFlat index with tunable parameters |
explain_similarity_query | EXPLAIN ANALYZE a similarity query to confirm the ANN index is used |
information_schema / pg_catalog before being
interpolated into SQL — an LLM can only ever reference identifiers that already exist. Values are
always bound parameters.{column, op, value} allowlist, not a raw SQL fragment.MCP_PGVECTOR_READ_ONLY=true to disable upsert_embedding and create_vector_index,
leaving only read/search tools available — useful when pointing the server at a production
database.MCP_PGVECTOR_COMMAND_TIMEOUT_SECONDS, default
30s) so one expensive query can't occupy a pool connection — and stall every other caller —
indefinitely. Set it to 0 to disable.uvx mcp-server-pgvector
Or with pip:
pip install mcp-server-pgvector
python -m mcp_server_pgvector
The server reads its connection string from DATABASE_URL (or PGVECTOR_DATABASE_URL):
{
"mcpServers": {
"pgvector": {
"command": "uvx",
"args": ["mcp-server-pgvector"],
"env": {
"DATABASE_URL": "postgresql://user:password@localhost:5432/mydb",
"MCP_PGVECTOR_READ_ONLY": "false",
"MCP_PGVECTOR_COMMAND_TIMEOUT_SECONDS": "30"
}
}
}
}
Covered:
pg_catalog before use) and a closed
filter-operator allowlist — no path from tool arguments to raw SQL.twine check on the result.ConnectionRefusedError/asyncpg exceptions — verified
these don't leak the DSN's credentials into error text.Known limitations, honestly:
DATABASE_URL can
do. If you need different agents to have different permissions, give them different
connection strings backed by different Postgres roles, not different server instances of this
same DSN.hybrid_search's full-text side is hardcoded to Postgres's 'english' text search
configuration; there's no parameter to change it yet.uv sync --dev
# Bring up an isolated pgvector instance for local testing
docker compose -f docker-compose.dev.yml up -d
export DATABASE_URL=postgresql://postgres:postgres@localhost:5434/postgres
uv run pytest
uv run ruff check .
uv run pyright
See CONTRIBUTING.md. See CHANGELOG.md for release history.
MIT — see LICENSE.