For the complete documentation index, see llms.txt. This page is also available as Markdown.

v2.4.1

pREST v2.4.1 β€” the MCP endpoint now honours [expose], closing a catalog discovery bypass, plus a SQL-keyword screen on custom query script values.

Released: July 28, 2026

GitHub tag Β· Compare v2.4.0...v2.4.1

v2.4.1 is a security release with a single commit (#1016). It makes the MCP endpoint honour the [expose] settings β€” previously /_mcp could enumerate the full catalog even when the REST listing routes were denied β€” and adds a SQL-keyword screen to values that custom query scripts interpolate into SQL.

  • Docker: prest/prest:v2.4.1

  • Go install: go install github.com/prest/prest/v2/cmd/prestd@v2.4.1

No configuration keys were added or renamed, and no defaults changed.


Highlights

MCP honours [expose] (#1016)

/_mcp was never routed through the exposure middleware, so an operator who disabled the /databases, /schemas, or /tables REST routes was still serving the entire catalog to any MCP client. The MCP handler now checks the same settings before answering.

When a listing is denied, the corresponding tool returns HTTP 400 with a JSON-RPC error:

{"jsonrpc":"2.0","id":1,"error":{"code":400,"message":"unauthorized listing"}}

The REST routes keep returning 401 with {"error": "unauthorized listing"} β€” same message, different status, because the two surfaces report errors differently.

Discovery (GET /_mcp, tools/list) is pruned rather than blocked:

Tool
Behaviour when its listing is denied

prest.list_databases

Not advertised; tools/call returns 400

prest.list_schemas

Not advertised; tools/call returns 400

prest.list_tables

Not advertised; tools/call returns 400

prest.select.{database}.{schema}.{table}

Not enumerated at all if any listing is denied

prest.describe_table, prest.select_table

Always advertised

The per-table tools are withheld because their names embed database, schema, and table names and their descriptions embed column names β€” enumerating them made GET /_mcp a full catalog dump with no tools/call required.

[expose] governs discovery; [access] governs reads. A client that already knows a table name can still read it through prest.select_table subject to permissions. See MCP over HTTP β€” Tools reference and Configuring pREST β€” Expose Data.

Clarified [expose] semantics

The three listing flags only take effect while enabled = true. The check is "allowed unless exposure control is on and this listing is off", so hiding a listing takes both keys:

This also means a deployment on the default enabled = false is unaffected by this release.

SQL-keyword screen on script values (#1016)

Values that a /_QUERIES script template interpolates become part of the SQL text. The pre-existing character allow-list was not enough: 0 UNION SELECT passwd FROM pg_shadow needs no quote, comma, or parenthesis, so it passed through into an unquoted comparison such as WHERE 1 = {{.field1}}.

Values are now also rejected when they contain --, ::, or a SQL keyword token (58 keywords, matched case-insensitively, with leading digits stripped so 0union is caught as union).


Changes since v2.4.0

PR
Summary

MCP endpoint honours [expose]; listing tools refused and per-table tools withheld when exposure control is active; SQL-keyword screen on custom query script values

Full detail: compare v2.4.0...v2.4.1.


Upgrading from v2.4.0

Upgrade to v2.4.2 instead β€” it contains this release plus the fix for the over-broad script screen. If you do deploy v2.4.1:

  1. Deploy prest/prest:v2.4.1, the matching binary, or go install …@v2.4.1.

  2. On the default [expose] enabled = false, nothing changes. MCP behaviour only shifts for deployments that actively restrict listings.

  3. If you restrict listings, MCP clients relying on auto-discovered prest.select.{database}.{schema}.{table} tools must switch to the generic prest.select_table tool.

  4. Audit custom query scripts. Any script parameter or header whose value contains a SQL keyword, --, or :: is silently blanked. Rewrite templates to bind values instead of interpolating them β€” see Custom Queries.


Last updated