> For the complete documentation index, see [llms.txt](https://docs.prestd.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.prestd.com/releases/v2.5.1.md).

# v2.5.1

pREST v2.5.1 fixes MySQL bugs from v2.5.0: MCP, alias schema scope, exact large integers, and 503 responses that hide driver text.

Released: October 8, 2026

[GitHub tag](https://github.com/prest/prest/releases/tag/v2.5.1) · [Compare v2.5.0...v2.5.1](https://github.com/prest/prest/compare/v2.5.0...v2.5.1)

**v2.5.1** fixes MySQL behavior that shipped broken or incomplete in [v2.5.0](/releases/v2.5.0.md). One change: [#1056](https://github.com/prest/prest/pull/1056). It is a fix on that tag, not a new engine. Anyone who installed v2.5.0 for MySQL should move to v2.5.1. No new config key.

* **Docker:** `prest/prest:v2.5.1` (linux/amd64 and linux/arm64)
* **Go install:** `go install github.com/prest/prest/v2/cmd/prestd@v2.5.1`

***

## Highlights

### Registry and engine selection ([#1056](https://github.com/prest/prest/pull/1056))

A `[[databases]]` alias serves only the database named in its `url` or `database`. Any other `{schema}` is **404** on CRUD, `/show`, and `/{alias}/{schema}` table listing. One MySQL login can otherwise see every granted database, so this stops cross-database reads through the path.

In registry mode `/databases` returns `[{"datname": alias, "name": alias, "physical_name": database}]` instead of every database on the server.

With no `[[databases]]` block, the single connection still serves every granted database as `{schema}`.

Exception to “URLs are not sniffed”: a `[[databases]]` entry whose `url` starts with `mysql://` and has **no** `engine` is MySQL. Any other URL is not probed. Empty root `engine` stays PostgreSQL, including Timescale detection.

### Types, batch, errors, auth ([#1056](https://github.com/prest/prest/pull/1056))

Request bodies use `UseNumber`. Integers above 2^53 (example `9007199254740993`) are written exactly. This applies to MySQL and PostgreSQL.

MySQL JSON scan: integers, including `BIGINT UNSIGNED`, are JSON numbers with `interpolateParams` and with `prepare`. `DECIMAL` / `NUMERIC` stay strings, so `SUM` / `AVG` of an integer column is a string. An aggregate without an alias uses the Postgres key (`sum`, `avg`, `count`, `min`, `max`).

`BLOB` / `BINARY` / `VARBINARY` / `BIT` / `GEOMETRY` render as Postgres bytea `"\\x` plus lowercase hex, in REST and MCP. A `\x…` string written into a binary column is stored as those characters, not decoded.

`DATE` is `YYYY-MM-DD`. `DATETIME` has no zone (`2006-01-02T15:04:05.999999`) so it can be written back. `TIMESTAMP` is UTC with `+00:00`.

`_count` is `` COUNT(...) AS `count` `` so the response key matches Postgres.

Batch insert uses the union of keys. A missing key is SQL `DEFAULT` on MySQL and on PostgreSQL insert. PostgreSQL `COPY` still returns **400** when records differ, because `COPY` has no `DEFAULT`. `Prest-Batch-Method: copy` on MySQL remains a transactional multi-row `INSERT`, not `LOAD DATA`.

JSON objects and slices are bound as JSON text (utf8mb4), not `[]byte`, so `interpolateParams=true` does not send a `_binary` literal (MySQL error 3144). No per-alias `prepare` key is required.

Value-less operators (`$null`, `$notnull`, `$true`, `$nottrue`, `$false`, `$notfalse`) work with or without a trailing dot.

Numeric comparison of a non-number (`?n=$gt.abc`) follows MySQL: it compares with `0` and can match rows. Postgres still errors.

Connection failure (down, refused, timed out) is **503** `{"error":"database unavailable"}` with no driver text. MySQL 1146, 1142, 1044, and 1049 are **404**. For 1142, 1044, and 1049 the server text is dropped because it names the account (`'prest'@'host'`).

`/auth` on MySQL uses backticks and `?`. Unset `auth.schema` defaults to the connection database, because `public` does not exist.

### MCP on MySQL ([#1056](https://github.com/prest/prest/pull/1056))

Supported from v2.5.1. `select_table` quotes with backticks and binds filters as `?`. In a mixed registry each alias uses its own catalog, executor, and dialect. Read-only rules from the [MCP over HTTP](/get-started/mcp-over-http.md) guide still apply. MariaDB is still out of scope.

### Images and plugins ([#1056](https://github.com/prest/prest/pull/1056))

Docker tags are multi-arch **linux/amd64** and **linux/arm64**. The image binary is a separate GoReleaser build (`prestd-docker`) with `CGO_ENABLED=1`, `-mod=vendor`, and `-trimpath`, so `plugin.Open` still accepts `.so` files built the same way as [Middleware Plugin](/plugins/middleware-plugin.md). Release archives stay the portable (non-cgo) build.

***

## Changes since v2.5.0

| PR                                                | Summary                                                                                       |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [#1056](https://github.com/prest/prest/pull/1056) | MySQL v2.5.0 bugfix: MCP, registry scope, types, batch `DEFAULT`, and 503 without driver text |

Full detail: [compare v2.5.0...v2.5.1](https://github.com/prest/prest/compare/v2.5.0...v2.5.1). Commit list: [Changes since v2.5.0](/releases/main-since-v2.5.0.md).

***

## Upgrading from v2.5.0

1. Retag to `prest/prest:v2.5.1` or `go install github.com/prest/prest/v2/cmd/prestd@v2.5.1`. No new setting.
2. If you use `[[databases]]` with MySQL, expect `{schema}` to be only that alias’s database. A path that used another schema on the same login now 404s.
3. If you skipped [v2.4.2](/releases/v2.4.2.md), the HMAC `jwt.key` warning still applies. A short key does not stop startup — it disables `/auth`. See [v2.4.2 — Upgrading](/releases/v2.4.2.md#upgrading-from-v241).

***

## Related

* [MySQL](/databases/mysql.md)
* [Databases](/databases.md)
* [MCP over HTTP](/get-started/mcp-over-http.md)
* [v2.5.0 release notes](/releases/v2.5.0.md)
* [Middleware Plugin](/plugins/middleware-plugin.md)
* [Acronyms](/readme/acronyms.md) ([MCP](/readme/acronyms.md#mcp), [REST](/readme/acronyms.md#rest), [JWT](/readme/acronyms.md#jwt))


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.prestd.com/releases/v2.5.1.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
