v0.5.3
Breaking / Behaviour changes
-
A tool result's text content block is no longer bare JSON. Every result is now fenced
between<<<UNTRUSTED DATABASE DATA …>>>markers, sojson.loads(result.content[0].text)
will raise.structuredContentis unchanged and byte-identical, so clients that read it — the
spec-conforming path, and what all 23 tools declare an output schema for — are unaffected.
Only code parsing the text channel needs updating. Alist[dict]tool emits one text block
per item and each is fenced individually. -
A failed commit now consumes its dry-run grant. Previously the grant survived, letting
an agent retry the identical statement immediately. Because a commit can fail ambiguously —
a statement timeout, or a connection dropped duringCOMMIT, may still have applied the
write server-side — that retry could silently double-apply a non-idempotent statement such as
UPDATE t SET n = n + 1. One preview now authorises exactly one commit attempt, so a failed
commit requires a fresh dry-run that shows the agent the current state before it retries.This reverses a deliberate earlier choice that favoured retry ergonomics.
Added
-
Prompt-injection hardening (
guard.py). Database content is attacker-controllable: anyone
who can insert a row, or name a table or column, chooses text that lands verbatim in the
agent's context. Two layers, both advisory to the model:- Every tool result's text channel is fenced with an explicit "this is data, not
instructions" notice, applied at a single seam (GuardedFastMCP.call_tool) rather than in
each tool. - A standing policy travels in the server's
initializeinstructions — the durable half,
since a client reading onlystructuredContentnever sees the per-response fence.
Markers found inside a payload are defanged first, so hostile content cannot close the fence
early and appear to speak with the server's authority.This is mitigation, not a guarantee: a determined injection can still influence a model.
- Every tool result's text channel is fenced with an explicit "this is data, not
Changed
- Both raw-SQL tool descriptions now tell the agent to confirm table and column names with
get_table_schema(orlist_tables/find_columns) when they are not already in context,
and explicitly not to re-fetch a schema it already has. Guidance only — nothing is enforced
server-side and no call is mandatory.
Fixed
- The
doctorMCP tool re-checks the config file's existence per call, as the CLI already did.
A config deleted or made unreadable after the server started produced a hardfailreading
"connections.json exists but could not be read" instead of the intended skip, "no
configuration found — rundb-conn-mcp setup".
Full Changelog: v0.5.2...v0.5.3