Skip to content

Releases: srmadscience/mcpdbwizard-open

2.0.14 — stop promising a notification we never send

Choose a tag to compare

@srmadscience srmadscience released this 29 Aug 07:27

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.14; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.14
docker pull docker.io/srmadscience/mcpdbwizard:2.0.14

The image is now published to Docker Hub as well as ghcr.io, from one build tagged for both, so
the two are the same manifest digest by construction rather than by two builds. Prefer ghcr.io where
you have no reason not to: Docker Hub rate-limits pulls per source IP, so a CI runner or an office
NAT can exhaust the allowance without any one person pulling much.

What is new in 2.0.14

Generated MCP servers no longer advertise tools/list_changed, a notification they have never
been able to send.

The boolean in .capabilities(...tools(x)) is listChangedToolCapabilities is a record whose
single component is listChanged() — so every generated server answered initialize with
"tools":{"listChanged":true} and had no code path able to send one: the tool list is a fixed
Arrays.asList built once at construction. A client that believes listChanged has no reason to
poll tools/list again, because it expects to be told.

False is the true answer rather than a retreat from a feature: curation happens at generation time,
and an operation you did not select has no tool-spec method emitted at all, so a server's tool set is
fixed for the life of its process by design. Changing it means regenerate-and-restart, which a client
re-initializes against.

Also included: 2.0.13

2.0.13 was released as an image but its source was never exported, so this drop carries both.

Two writers could fill the config volume. The audit trail's MCP_AUDIT_FILE_MAX_BYTES caps one
directory, and a trail directory takes exactly one writer — so every generated server got its own and
each independently took the 512 MB default. The advertised cap was 512 MB per config, roughly
10.5 GB across the default port range. MCP_AUDIT_TRAIL_MAX_BYTES is now a budget for the whole
trail, divided among its writers.

Retention could not hold it back, and the reason matters: at a few hundred calls a second a directory
reaches its cap in hours rather than days, and the oldest segment is then evicted regardless of age
and counted as dropped. Filling the volume was the visible half; losing audit records inside the
promised window was the other. Watch the drop counters on Admin → Audit, not just the disk gauge.

Separately, server.log had no cap at all — one MCP-CALL line per tool call, growing for the life
of the process. It now rolls at 8 MB keeping one previous generation.

2.0.12 — RAW and DATE inside a record

Choose a tag to compare

@srmadscience srmadscience released this 29 Aug 07:27

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.12; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.12

What is new in 2.0.12

A RAW or DATE field inside a record now tells a caller how it crosses.

Both were published as a bare {"type":"string"} — true, and useless. It does not say "send
base64", and it does not say the T is required, so the only way to learn either was to be
rejected. A scalar parameter of the same Oracle type has always said so, so this is the existing
contract reaching one level further in rather than a new one.

The RAW case was worse than a rejection, which is what makes it more than a schema nicety. Hex
is the spelling a person reaches for with RAW, and hex and base64 are both plain strings — so
sending hex was not refused. It decoded into different bytes and the procedure ran. The note
therefore says "base64, NOT hex" with an example, rather than just "base64".

Also in this release: each test class gets its own config directory, RUN_ON_START is documented,
and the undocumented MCPDBWIZARD_RUN_THIS_FILE escape hatch is withdrawn.

2.0.11 — upload is a save, and discovery without credentials

Choose a tag to compare

@srmadscience srmadscience released this 29 Aug 07:27

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.11; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.11

What is new in 2.0.11

Uploading a config now saves it, and a deployment can adopt one from a file at boot.

Upload used to load the JSON into the editor and say "Use Save to keep it". So an uploaded config
was invisible on the Runtime page, absent from the access matrix, and gone at the next restart —
while the Design page showed it as the current config, so it looked present in the one place anybody
was looking. Somebody uploading a config file is stating that they want that config here. The save
path also does more than write the file: it copies the SQL library into the config's own scope and
stamps the deployment's Oracle connection.

/.well-known/** answers without credentials.

Discovery happens before a client has credentials, by construction: /.well-known/* is where an MCP
client looks to find out how it is meant to authenticate (RFC 9728 protected-resource metadata, RFC
8414 authorization-server metadata), so putting it behind authentication is circular.

The failure this prevents is worse than a 401. Under form login the entry point answered a probe
with a 302 to /login; the client followed it, got a page of HTML with 200 OK, and reported a
parse error — so "this deployment does not offer OAuth" arrived as a malformed-response bug
several layers from its cause.

2.0.10 — a metrics port a scrape can reach

Choose a tag to compare

@srmadscience srmadscience released this 29 Aug 07:27

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.10; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.10

What is new in 2.0.10

A container could be entirely healthy and still refuse every Prometheus scrape.

The port was published, docker ps showed 0.0.0.0:9464->9464/tcp, the child had
MCP_METRICS_PORT in its environment — and nothing answered, with no line in any log saying why.
The exporter was listening on 127.0.0.1 inside the container, and Docker forwards a published
port to the container's bridge address, not its loopback.

The fix is in RuntimeManager rather than in the exporter's default, and the asymmetry is
deliberate: that default is right for the case it was written for, because the same class runs as a
plain library in somebody's own JVM on a real host, where switching metrics on must not be the act
that puts a server on a network.

Note this is the opposite of what the same code does for the MCP port, where loopback does not deny
access but channels it through the /mcp/{config} proxy — the only component that knows who is
calling.

The three metrics settings are also now documented where a Docker user will actually find them.

2.0.9 — sparse index-by collections

Choose a tag to compare

@srmadscience srmadscience released this 27 Aug 12:50

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.9; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.9

What is new in 2.0.9

A sparse index-by OUT collection no longer fails with ORA-01403. This affects generated DAO
code, not just MCP — regenerate to pick it up.

An index-by table is sparse by nature: PL/SQL lets a routine assign element 1 and element 7 and
nothing between. The generated code walked such a parameter from first to last index, so a gap made
it read an index that is not there — an error raised from inside the emitted block, naming neither
the parameter nor the gap.

Only parameters whose values are converted on the way out were affected. In practice that means
a high-precision NUMBER collection (one that does not fit the numeric slot, such as
number(30,15)) and RAW, which was fixed in 2.0.6. DATE and the TIMESTAMP family were already
correct; VARCHAR2 and a numerically-bound NUMBER never took that path at all.

Positions are preserved — values come back at the indexes the routine set them at, with the gaps
empty, not compacted to the front. Verified on Oracle 12c through 26ai.

How it was found, since it says something about the rest. The RAW case was fixed by comparing
the code against its neighbours, with no test that failed without the fix — nothing in the test
schema returned a sparse collection. Adding a fixture that does turned up a second unguarded type,
and now holds both in place across five Oracle releases: guard removed, the error reproduces; guard
restored, it does not.

What this repository is

The generator, its runtime library, the MCP emitter and a database-free test suite that passes on a
clean checkout. No test schema ships. You point it at your own Oracle database;
Scripts/check_provisioning.sh will tell you which objects a config expects.
examples/generated-output/ holds 107 generated .java files so you can see what the generator
emits without an Oracle instance to hand.

Honest limits

The image is not signed — no cosign or Sigstore signature, so nothing here identifies the
publisher. It carries a BuildKit provenance record and an SPDX SBOM, both self-attested by the same
party that publishes the image: useful for what is in it, not evidence of who built it.

Known issues, with a workaround for each: https://mcpdbwizard.com/docs/known-issues/

2.0.8 — the console names its own version

Choose a tag to compare

@srmadscience srmadscience released this 27 Aug 08:19

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.8; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.8

What is new in 2.0.8

The console shows which version it is running — on the login screen, and on the right of the
banner once you are signed in.

Two places, because they answer for two different people. The banner tells whoever is already
working here which build they are on. The login screen tells somebody handed a URL who is deciding
whether that box has a fix in it — and that person may not have an account, so putting it only
behind a login makes "what is deployed here?" require one, which is backwards for a fact the
image tag already discloses.

The number is read from the build itself, so it cannot drift from the release. A console that
confidently names the wrong version is worse than one naming none, because the only reason to read
it is to decide whether a fix is present. A build that stamped no version shows dev rather than
guessing something release-shaped.

Nothing else changed — no generator, no generated server, no proxy. If you are on 2.0.7 and not
troubled by not knowing it, there is no reason to move.

What this repository is

The generator, its runtime library, the MCP emitter and a database-free test suite that passes on a
clean checkout. No test schema ships. You point it at your own Oracle database;
Scripts/check_provisioning.sh will tell you which objects a config expects.
examples/generated-output/ holds 107 generated .java files so you can see what the generator
emits without an Oracle instance to hand.

Honest limits

The image is not signed — no cosign or Sigstore signature, so nothing here identifies the
publisher. It carries a BuildKit provenance record and an SPDX SBOM, both self-attested by the same
party that publishes the image: useful for what is in it, not evidence of who built it.

Known issues, with a workaround for each: https://mcpdbwizard.com/docs/known-issues/

2.0.7 — the console says what it needs

Choose a tag to compare

@srmadscience srmadscience released this 27 Aug 07:53

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.7; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.7

What is new in 2.0.7

A console release. Nothing in the generator, a generated server or the proxy changed — the tools
your configs publish are identical to 2.0.6. What changed is what the console tells you when
something is not configured.

The setup instructions now show a command that works. The documented docker run had no Oracle
settings and pointed at another page for them, which held a bare -e fragment with no command
around it. Following either produced a console that starts, passes its healthcheck, and refuses
every Design page. The minimum is now the whole command.

"Oracle is not configured" names the password. It listed host, SID and user and said nothing
about DB_PASS, so an operator who set exactly the three things they were told to set got a login
failure — which reads as a wrong password rather than as one nobody asked for.

Start-up warns once per missing variable, each line naming the variable, what it is for and an
example, so a line can be read on its own:

WARN  Oracle is not configured: 4 required setting(s) are not set.
WARN    MCPDBWIZARD_ORACLE_HOST is not set - the database host, e.g. db.example.com
WARN    MCPDBWIZARD_ORACLE_SID is not set - the SID, or /SERVICE for a pluggable database, e.g. /FREEPDB1
WARN    MCPDBWIZARD_ORACLE_USER is not set - the Oracle account to connect as
WARN    DB_PASS is not set - the password for that account, or DB_PASS_FILE naming a file that holds it

Admin → Audit stops understating what it protects. The page said flatly that the write-ahead
spool is not encrypted. It has been optional since 2.0.5 — set MCP_AUDIT_SPOOL_KEY and it is
AES-256-GCM — and the page now reports what your deployment actually does.

What this repository is

The generator, its runtime library, the MCP emitter and a database-free test suite that passes on a
clean checkout. No test schema ships. You point it at your own Oracle database;
Scripts/check_provisioning.sh will tell you which objects a config expects.
examples/generated-output/ holds 107 generated .java files so you can see what the generator
emits without an Oracle instance to hand.

Honest limits

The image is not signed — no cosign or Sigstore signature, so nothing here identifies the
publisher. It carries a BuildKit provenance record and an SPDX SBOM, both self-attested by the same
party that publishes the image: useful for what is in it, not evidence of who built it.

Known issues, with a workaround for each: https://mcpdbwizard.com/docs/known-issues/

2.0.6 — index-by collections cross MCP

Choose a tag to compare

@srmadscience srmadscience released this 27 Aug 06:30

Generates Oracle DAO, SOAP and MCP server code from a config file. This is the source drop for
2.0.6; the running article is the container image.

docker pull ghcr.io/srmadscience/mcpdbwizard:2.0.6

What is new in 2.0.6

Every Oracle scalar type now crosses an index-by collection. DATE, TIMESTAMP and RAW
elements of a PL/SQL index-by table used to remove the entire routine from the tool list — the
gate is per routine rather than per parameter, so one such argument silently hid every operation
that routine would have had. TIMESTAMP WITH [LOCAL] TIME ZONE came out of that gate in 2.0.1; the
remaining three follow here.

If you selected a routine and could not find its tool, this was the likeliest reason. Re-read
tools/list after upgrading — the tools appear with no change to your config.

Element Crosses as Example
DATE ISO-8601, time optional 1990-01-01
TIMESTAMP ISO-8601, up to 8 fractional digits 2019-03-01T14:25:36.123456
RAW base64, not hex 3q2+7w== for DE AD BE EF

Two caveats the tool descriptions now state rather than leaving you to discover: an Oracle DATE
has no sub-second precision, so fractional seconds are dropped — neither honoured nor an error.
And a RAW is shown in hex by SQL*Plus and by most tools you will have met one in, but MCP has
no binary type, so it crosses as base64. Hex is not rejected, because it cannot be: DEADBEEF
is also valid base64 and decodes to four completely different bytes.

A sparse index-by of RAW no longer risks NO_DATA_FOUND. The generated PL/SQL walked such a
collection from first to last index without checking each one exists, where the DATE and
TIMESTAMP paths always had. This affects generated DAO code as well as MCP tools, so
regenerate to pick it up.

What this repository is

The generator, its runtime library, the MCP emitter and a database-free test suite that passes on a
clean checkout. No test schema ships — not its DDL, not the configs that introspect it. You
point it at your own Oracle database. Scripts/check_provisioning.sh will tell you which objects a
config expects.

examples/generated-output/ holds 107 generated .java files so you can see what the generator
emits without an Oracle instance to hand.

Honest limits

The image is not signed — no cosign or Sigstore signature, so nothing here identifies the
publisher. It does carry a BuildKit provenance record and an SPDX SBOM, both self-attested by the
same party that publishes the image: useful for what is in it, not evidence of who built it.

Known issues, with a workaround for each, are listed at
https://mcpdbwizard.com/docs/known-issues/