Documentation · PostgreSQL
Release notes for Postgres
The Postgres image is published to the GitHub Container Registry and Docker Hub:
docker pull ghcr.io/srmadscience/mcpdbwizard-postgres:2.0.33
docker pull docker.io/srmadscience/mcpdbwizard-postgres:2.0.33
Both hold the same image, linux/amd64 and linux/arm64. Pin the version tag in anything that
matters: latest moves, and docker run never refreshes an image the machine already has. Each
release is also a GitHub Release
carrying the same notes.
The Postgres and Oracle products share version numbers but not every release: a version appears here only if a Postgres image was published for it. The Oracle notes are in Release notes.
2.0.33 — 4 November 2026
Generated output changes. Upgrade, and regenerate your servers. Pressing Start on the console regenerates a server from its config, so restarting each server after pulling the new image is enough.
docker pull ghcr.io/srmadscience/mcpdbwizard-postgres:2.0.33
docker pull docker.io/srmadscience/mcpdbwizard-postgres:2.0.33
Changes an MCP client will notice
- Some tool names change. A tool name may be 64 characters at most, and a longer one used to
be cut to its first 55 characters plus a hash. Postgres tool names carry the schema and
identifiers can be 63 bytes long, so the cut often fell inside the table name, and every tool
on a long-named table ended in the same
..._<table fragment>_<hash>. The descriptions were the only way to tell them apart. A long name is now its first 23 characters, the same 8-digit hash, and its last 31 characters, so the operation stays at the end:dbhell_longusernamexxxx_c1bc51b2_ablexxxxxxxxxxxxxxxxx_get_by_pk. Only names that 2.0.32 shortened change: a name of 64 characters or fewer is exactly as before. If a client, a prompt or an allow-list names a shortened tool, update it after regenerating. - Timestamps keep their microseconds. Over MCP a
timestampused to cross with milliseconds only, in both directions, so.123456came back as.123. Worse, a lookup keyed on a value thatget_by_pkhad just returned could miss the row. Timestamps now cross at full precision. They are written with every digit down to the last non-zero one, never fewer than three, and a timestamp parameter now accepts the JDBC form (2026-11-03 10:55:00.123456) as well as ISO. A value in whole milliseconds reads and writes exactly as before. - A row set holds at most 10,000 rows by default, as on Oracle. A routine returning a refcursor used to return every row. A tool returning a bigger cursor now returns its first 10,000.
- No
rowInserton a view that cannot take one. An aggregate view or a materialized view used to get an insert tool that could only fail. A tool is now generated only when Postgres says the relation accepts INSERT (pg_relation_is_updatable). A simple view keeps its insert tool. - Multi-row lookups come back in primary-key order, as on Oracle. Index and foreign-key child
lookups had no
ORDER BYbefore, so their rows came back in whatever order the server chose. - Errors from table and statement tools name the SQLSTATE, ending
(SQLSTATE 23502)as routine errors already did. - A statement parameter hinted with a Postgres type now gets that type. A hint such as
? /* pKey uuid */or/* pId bigint */used to be ignored, so the parameter was whatever the server inferred, often text. It now declares the type, and the server checks the statement against it when the server is generated. A hint that names no type, or one the statement cannot take, stops that statement being generated, with a warning, rather than failing on its first call. Hints using the Oracle words (STRING,NUMBER,DATE) behave as before.
New
- Lookups through expression indexes. A table indexed on
upper(name),date_trunc(...)or a field of a composite column now gets a lookup tool per such index. It used to get none for those indexes, and a table whose only indexes were expression indexes got no lookups at all. The tool’s arguments are named for the index’s columns (upper,building_no) and typed by the expression, and the query is written so that the index can serve it. A unique index returns one row, any other index an array. This adds tools to any schema that has an expression index.
Fixed
- Array subscripts survive a round trip. A Postgres array can start at 0, at a negative
subscript, or anywhere else (
[5:7]={...}). The generated collection classes and array fields in records used to drop the lower bound, so keys 0..2 came back as 1..3 and writing the value back moved them. Both now keep the lower bound in each direction. The JSON shape over MCP is unchanged. - An array of composites can be passed in. Its tool’s schema asked for an array of strings, which the server then refused, so the tool could not be called at all. It now takes an array of objects with the composite’s attributes. A timestamp attribute on the way out is its wall-clock value, not a UTC instant.
- A key read from a
timestamp(0)column finds its row again. A column with a declared precision rounds what it stores, so a row inserted with12:34:56.789(stored as12:34:57) could not be found, updated or deleted by the key it was inserted with. Keys are now rounded to the column’s own precision. - A null compared with a number works. A null parameter of unknown type was bound as text,
which Postgres refuses to compare with a numeric (
42883). It is now bound untyped. - Statements that stopped a config compiling:
- a statement with a quoted identifier or alias (
"Sequence Owner") was skipped; - DDL,
ANALYZEandSAVEPOINTstatements were skipped too, and now run as written; - a statement Postgres could not describe was skipped but still referenced, so the whole server failed to compile. It is now left out with a warning;
- a parameter named
1produced Java that did not compile; - a config with SQL statements but no routines generated a server that did not compile.
- a statement with a quoted identifier or alias (
- Two foreign keys of the same name pointing at one table, which Postgres allows because constraint names are unique per table, produced two methods and two tools of one name, and the server did not compile. The second is now named for its child table as well.
Upgrading. Pull 2.0.33 and restart each server from the console, which regenerates it. No config change and no database change. Supported Postgres versions are unchanged: 16, 17 and 18.
2.0.32 — 27 October 2026
The first release of MCPDBWizard for Postgres.
docker pull ghcr.io/srmadscience/mcpdbwizard-postgres:2.0.32
- Generates MCP servers from PostgreSQL 16, 17 and 18: tables, views, materialized views, foreign
and partitioned tables; functions and procedures, including composites, arrays,
VARIADIC, refcursors and set-returning functions; sequences; and your own SQL statements. - PostGIS
geometryandgeographycross as EWKT, and pgvector types as arrays of numbers. - Context Pinning reads the pinned value with
current_setting('mcp.<name>', true); nothing needs installing in the database. - The same console, proxy, accounts, access grid and audit as the Oracle product, in an image that carries no Oracle driver.
Known issues
jsonandjsonbcross as JSON text, a string holding the document, where Oracle’s native JSON crosses as an object. An agent must parse it, and must send a string back.- A NULL read from a table cannot be sent straight back to
update. A table tool’s column schema does not allownull, so a row fromget_by_pkholding a NULL is refused byupdateas it stands.updatereplaces the whole row and writes an omitted column as NULL, so leave such a column out. The Oracle product behaves the same way. - Names with non-ASCII letters (
café,naïve, a name in Cyrillic or CJK) are reduced to their ASCII letters and digits when Java class names are made from them. Two tables whose names differ only in those letters can collide, and a name with no ASCII letters at all can produce a server that does not compile. Tool names and their arguments keep the real names, and the SQL quotes them. Postgres allows these names unquoted, so they are more likely here than on Oracle. - In a SQL statement, a
?inside a string literal, or thejsonb?operator, is taken for a parameter placeholder. Usejsonb_exists(...)in place of the operator.
For what is not supported at all, see MCPDBWizard for Postgres.