diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 1dbcad6..d0e314e 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -13,7 +13,7 @@ body: attributes: label: Version description: Output of `postgresql-sharp-mcp --version`, or the commit SHA when running from source. - placeholder: 0.4.0 + placeholder: 0.5.0 validations: required: true - type: dropdown diff --git a/CHANGELOG.md b/CHANGELOG.md index 729167d..6ccabeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +## 0.5.0 + +Upgrade notes: a locked configuration whose login can execute server-file functions is now refused at startup, and npm installs that omit optional dependencies now fail (both below). Existing tool names, parameters, environment variables, CLI flags and the targets-file format remain compatible; additions such as the `parameters` input of `execute_sql`/`explain_query` are optional. - npm: the 177 MB package that bundled all five platform runtimes is split into a main package of about 140 KB and five platform packages of 35–39 MB each (`@codegiveness/postgresql-sharp-mcp-win32-x64`, `-linux-x64`, `-linux-arm64`, `-darwin-x64`, `-darwin-arm64`). The main package lists them as `optionalDependencies`, so npm, npx and global installs download only the package matching the machine's OS, CPU and (on Linux) glibc. The install command, `--allow-scripts` approval, `bin` name and installed native server are unchanged. The upstream `run-script-os` runner and the installation-time `uname` call are no longer used. An install that omits optional dependencies (`--omit=optional`) or runs on an unsupported platform such as Alpine/musl now fails with `postgresql-sharp-mcp-npm-install: not found`, where the old installer printed the supported-platform list; see the README troubleshooting table. Releases stage the platform packages before the main package. Each new package name needs a one-time npm trusted-publisher setup; see CONTRIBUTING. - Security: the database lock check now also refuses startup when the login, or any role it can `SET ROLE` to (including through `NOINHERIT` or `INHERIT FALSE` memberships), holds `EXECUTE` on a server-file function (`pg_read_file`, `pg_read_binary_file`, `pg_ls_dir`, server-side `lo_import`/`lo_export`, adminpack `pg_file_write`/`pg_file_unlink`/`pg_file_rename`) in any reachable locked database. Such a grant needs no `pg_read_server_files` membership, and `pg_read_binary_file` can read other databases' relation files from the data directory, bypassing the lock. Existing locked configurations with such grants are now refused; revoke the grant as described in the [hardening guide](SECURITY.md#database-lock-hardening). - Fix: a connection-string database lock (`POSTGRES_DATABASES`) with more than 32 names, or with names × `POSTGRES_POOL_SIZE` above 256, was refused at startup with "Configure 1..32 database targets." Lock names are `target` aliases of one connection-string login profile; the 32-profile and profiles × pool-size limits now count only targets JSON/file profiles (a connection string counts as one). The runtime pool cache bound (`floor(256 / POSTGRES_POOL_SIZE)` data sources) is unchanged. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7cf5250..2eff8d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -263,17 +263,17 @@ Enter the username at the prompt rather than copying a sibling secret. GitHub OI #### Dispatch the exact existing release -Merge the reviewed release-tool/workflow changes to `main` before using them. Only dispatch after the account permissions, matching policies and the `v` tag (for example `v0.4.0`) are ready. **Actions → Release → Run workflow** must select **main**. The equivalent commands below are alternatives; run only the intended target: +Merge the reviewed release-tool/workflow changes to `main` before using them. Only dispatch after the account permissions, matching policies and the `v` tag (for example `v0.5.0`) are ready. **Actions → Release → Run workflow** must select **main**. The equivalent commands below are alternatives; run only the intended target: ```powershell # Default all: GitHub Release + npm staging + NuGet publication. -gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.4.0 -f target=all +gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.5.0 -f target=all # npm staging only; no GitHub Release or NuGet publication. -gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.4.0 -f target=npm +gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.5.0 -f target=npm # NuGet publication only; no GitHub Release or npm staging. -gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.4.0 -f target=nuget +gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.5.0 -f target=nuget # GitHub Release only; no registry staging/publication. -gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.4.0 -f target=github +gh workflow run release.yml --repo codegiveness/postgresql-sharp-mcp --ref main -f tag=v0.5.0 -f target=github ``` `target` choices are `all`, `github`, `npm` and `nuget`, defaulting to `all`. Every target retains common preflight, package/installed-distribution verification and attestation. npm-only and NuGet-only jobs tolerate an intentionally skipped GitHub Release job **only for their dedicated target**; failed/canceled prerequisites cannot reach a publisher. In `all` mode both registry jobs require successful GitHub Release publication. The npm command stages the exact attested tarball using `npm stage publish`, never approves it or calls direct `npm publish`. Its successful summary means **staged, pending Windows 2FA approval**, not published. @@ -284,21 +284,21 @@ For a failed current main-dispatched workflow, `gh run rerun --failed - After the npm staging job succeeds, review each stage ID and intended `latest` tag. The job stages the five platform packages before the main package. Approve them in the same order, **platform packages first**, so the public main package never points at unpublished optional dependencies. Every public npm publication requires the maintainer's Windows 2FA approval. A successful dispatch, login, OIDC exchange or staging response is not approval. -Repeat this review for each package, setting `$Package` and its tarball name `$Tarball` in turn: `@codegiveness/postgresql-sharp-mcp--` with `codegiveness-postgresql-sharp-mcp---0.4.0.tgz` for the five platforms, and finally `@codegiveness/postgresql-sharp-mcp` with `codegiveness-postgresql-sharp-mcp-0.4.0.tgz`: +Repeat this review for each package, setting `$Package` and its tarball name `$Tarball` in turn: `@codegiveness/postgresql-sharp-mcp--` with `codegiveness-postgresql-sharp-mcp---0.5.0.tgz` for the five platforms, and finally `@codegiveness/postgresql-sharp-mcp` with `codegiveness-postgresql-sharp-mcp-0.5.0.tgz`: ```powershell $Package = '@codegiveness/postgresql-sharp-mcp-win32-x64' -$Tarball = 'codegiveness-postgresql-sharp-mcp-win32-x64-0.4.0.tgz' +$Tarball = 'codegiveness-postgresql-sharp-mcp-win32-x64-0.5.0.tgz' npm.cmd stage list $Package --registry https://registry.npmjs.org/ -$StageId = Read-Host "Stage ID for $Package 0.4.0" +$StageId = Read-Host "Stage ID for $Package 0.5.0" npm.cmd stage view $StageId --registry https://registry.npmjs.org/ npm.cmd stage download $StageId --registry https://registry.npmjs.org/ ``` -Confirm the stage is **`$Package@0.4.0`**, comes from the intended run and uses the intended dist-tag. Compare the downloaded staged tarball's SHA-256 against the attested release tarball before approval. For the 0.4.0 GitHub release: +Confirm the stage is **`$Package@0.5.0`**, comes from the intended run and uses the intended dist-tag. Compare the downloaded staged tarball's SHA-256 against the attested release tarball before approval. For the 0.5.0 GitHub release: ```powershell -gh release download v0.4.0 --repo codegiveness/postgresql-sharp-mcp --pattern $Tarball --dir release-verification +gh release download v0.5.0 --repo codegiveness/postgresql-sharp-mcp --pattern $Tarball --dir release-verification gh attestation verify ./release-verification/$Tarball --repo codegiveness/postgresql-sharp-mcp --signer-workflow codegiveness/postgresql-sharp-mcp/.github/workflows/release.yml Get-FileHash ./release-verification/$Tarball -Algorithm SHA256 $StagedTarball = Read-Host 'Path printed by npm stage download' @@ -311,16 +311,15 @@ Only after that review, approve the exact stage: ```powershell npm.cmd stage approve $StageId --registry https://registry.npmjs.org/ -npm.cmd view "$Package@0.4.0" version dist.integrity dist.tarball --registry https://registry.npmjs.org/ +npm.cmd view "$Package@0.5.0" version dist.integrity dist.tarball --registry https://registry.npmjs.org/ npm.cmd view $Package dist-tags --registry https://registry.npmjs.org/ ``` After approving the main package last, check the public installation: ```powershell -npx.cmd --yes --allow-scripts=@codegiveness/postgresql-sharp-mcp --cache ./release-verification/npm-cache-0.4.0 '@codegiveness/postgresql-sharp-mcp@0.4.0' --version +npx.cmd --yes --allow-scripts=@codegiveness/postgresql-sharp-mcp --cache ./release-verification/npm-cache-0.5.0 '@codegiveness/postgresql-sharp-mcp@0.5.0' --version ``` - Complete the command's **2FA/browser challenge on Windows** promptly; an expired or canceled challenge does not publish. npmjs.com's **Staged Packages → Approve** is an alternative with the same required 2FA, not an automated bypass. Approval cannot use workflow OIDC. Check public version, integrity/tarball equality and fresh-cache execution before announcing availability; check actual provenance evidence separately. A workstation-staged recovery must use the exact verified tarball with `npm.cmd stage publish ./release-verification/$Tarball --ignore-scripts --access public --tag latest --registry https://registry.npmjs.org/` and the same review/2FA approval; it does not gain CI provenance. Do not restage a version already pending approval or already published. #### Recorded publication evidence diff --git a/README.md b/README.md index ab23667..6d19211 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ SQL calls are read-only by default, but the server's default access mode permits explicitly requested writes. Use a least-privileged database login, never a superuser. Keep an existing explicit `restricted` setting; [access boundaries](#access-and-resource-boundaries) explain how to refuse writes entirely. -**Fastest start:** Node.js 22+ and npm are enough, because npm installs the .NET runtime with the server. This downloads and runs version 0.4.0: +**Fastest start:** Node.js 22+ and npm are enough, because npm installs the .NET runtime with the server. This downloads and runs version 0.5.0: ```sh -npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.4.0 --version +npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.5.0 --version ``` -It should print `postgresql-sharp-mcp 0.4.0.0`. Then register it with your MCP client and enter your connection string: the [quick start](#quick-start) has three steps. Prefer a .NET tool or a standalone archive for Linux, macOS or Windows? See [step 1](#1-install-or-run). To build and run a container image from the Dockerfile, see [CONTRIBUTING.md](CONTRIBUTING.md#self-contained-executable-and-container). +It should print `postgresql-sharp-mcp 0.5.0.0`. Then register it with your MCP client and enter your connection string: the [quick start](#quick-start) has three steps. Prefer a .NET tool or a standalone archive for Linux, macOS or Windows? See [step 1](#1-install-or-run). To build and run a container image from the Dockerfile, see [CONTRIBUTING.md](CONTRIBUTING.md#self-contained-executable-and-container). **What you can ask once it is connected:** @@ -41,12 +41,12 @@ Every result is a row- and byte-bounded page that the assistant can continue wit Choose **npx** for on-demand execution or a **.NET tool** for a persistent command. Starting with **0.3.3**, npm bundles the .NET runtime: npx requires only Node.js 22+ and npm, not an installed .NET runtime or SDK. The .NET tool still requires the [.NET 10 runtime](https://dotnet.microsoft.com/download/dotnet/10.0), and installing it requires the .NET 10 SDK. -This guide targets **0.4.0**. Registry commands require the corresponding published version; if it is unavailable, [build and install the local npm artifact](CONTRIBUTING.md#build-and-install-package-artifacts). npm **0.3.2** still requires .NET; installing it globally does not remove that prerequisite. +This guide targets **0.5.0**. Registry commands require the corresponding published version; if it is unavailable, [build and install the local npm artifact](CONTRIBUTING.md#build-and-install-package-artifacts). npm **0.3.2** still requires .NET; installing it globally does not remove that prerequisite. **npx — run without a global install:** ```sh -npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.4.0 --version +npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.5.0 --version ``` The package-specific `--allow-scripts` approves installation on npm 12. Do not use `--ignore-scripts` for automatic setup. npm downloads only the platform package matching your OS/CPU (about 35–39 MB; the main package is under 1 MB). Its self-contained C# installer then installs the server and runtime. Starting with 0.5.0, npm no longer downloads all five platform runtimes. The installer downloads nothing itself. The installed server command is native; it needs neither Node.js nor `dotnet` to run. @@ -54,18 +54,18 @@ The package-specific `--allow-scripts` approves installation on npm 12. Do not u **.NET tool — install once, then run by name:** ```sh -dotnet tool install --global codegiveness.postgresql-sharp-mcp --version 0.4.0 +dotnet tool install --global codegiveness.postgresql-sharp-mcp --version 0.5.0 postgresql-sharp-mcp --version ``` If the command is not found, add the .NET tools directory to your PATH (`$HOME/.dotnet/tools` on Linux/macOS; `%USERPROFILE%\.dotnet\tools` on Windows), or use its absolute executable path. Do not reinstall to fix PATH. -The command should report **0.4.0** (or assembly version **0.4.0.0**). Continue with registration below, then prepare your connection environment in step 2. Package versions are immutable; a published release archive is an alternative if your registry is unavailable. +The command should report **0.5.0** (or assembly version **0.5.0.0**). Continue with registration below, then prepare your connection environment in step 2. Package versions are immutable; a published release archive is an alternative if your registry is unavailable.
Standalone archives — no .NET, Node.js or npm installation needed -Download **one archive** and `SHA256SUMS` from [release 0.4.0](https://github.com/codegiveness/postgresql-sharp-mcp/releases/tag/v0.4.0). These archives include the .NET runtime: you do not need the .NET SDK, npm, Node.js or Docker for this installation. +Download **one archive** and `SHA256SUMS` from [release 0.5.0](https://github.com/codegiveness/postgresql-sharp-mcp/releases/tag/v0.5.0). These archives include the .NET runtime: you do not need the .NET SDK, npm, Node.js or Docker for this installation. | Your computer | Archive | |---|---| @@ -128,7 +128,7 @@ Expand-Archive -Path "$HOME\Downloads\postgresql-sharp-mcp-win-x64.zip" -Destina
-The executable should report **0.4.0**. If you already have an older installation, read [upgrade notes](#upgrading-an-existing-installation) before reusing its configuration. +The executable should report **0.5.0**. If you already have an older installation, read [upgrade notes](#upgrading-an-existing-installation) before reusing its configuration. @@ -142,7 +142,7 @@ For **npx**, use this JSON for a new file. If the file already has other servers "postgresql": { "type": "stdio", "command": "npx", - "args": ["-y", "--allow-scripts=@codegiveness/postgresql-sharp-mcp", "@codegiveness/postgresql-sharp-mcp@0.4.0"] + "args": ["-y", "--allow-scripts=@codegiveness/postgresql-sharp-mcp", "@codegiveness/postgresql-sharp-mcp@0.5.0"] } } } @@ -201,7 +201,7 @@ Use the command for your installation method. If you use a standalone archive, r **npx, Linux/macOS:** ```sh -npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.4.0 --validate && omp +npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.5.0 --validate && omp ``` **.NET tool, Linux/macOS:** @@ -221,7 +221,7 @@ if ($LASTEXITCODE -eq 0) { } ``` -For npx in PowerShell, replace the first line with `npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.4.0 --validate`; keep the `$LASTEXITCODE` check and launch block. +For npx in PowerShell, replace the first line with `npx -y --allow-scripts=@codegiveness/postgresql-sharp-mcp @codegiveness/postgresql-sharp-mcp@0.5.0 --validate`; keep the `$LASTEXITCODE` check and launch block. Validation is read-only and exits; its successful stderr output includes your database name, so keep it private. Empty input is rejected before OMP starts. If it fails, fix your connection details and repeat step 2; [troubleshooting](#if-setup-does-not-work) covers common failures. @@ -248,9 +248,9 @@ For a remote server needing a provider CA certificate, retain `SSL Mode=VerifyFu ### Upgrading an existing installation -Automatic discovery and the unrestricted default require **0.3.1 or newer**: the contract was developed under source version 0.3.0, which was never tagged or released, so 0.3.1 is the first release that contains it. npm runtime bundling requires **0.3.3 or newer**. This guide targets **0.4.0**, which adds the [database lock](#database-lock): an existing `POSTGRES_DATABASES` configuration now refuses to start unless PostgreSQL grants match the list (see the [hardening guide](SECURITY.md#database-lock-hardening)). Older 0.2.0 executables use configured database aliases and a restricted default. Changing configuration does not upgrade an old executable. +Automatic discovery and the unrestricted default require **0.3.1 or newer**: the contract was developed under source version 0.3.0, which was never tagged or released, so 0.3.1 is the first release that contains it. npm runtime bundling requires **0.3.3 or newer**. **0.4.0** added the [database lock](#database-lock): an existing `POSTGRES_DATABASES` configuration refuses to start unless PostgreSQL grants match the list (see the [hardening guide](SECURITY.md#database-lock-hardening)). This guide targets **0.5.0**, whose lock check also refuses a login that can execute server-file functions such as `pg_read_binary_file` in a locked database; revoke such grants before upgrading a locked configuration. Older 0.2.0 executables use configured database aliases and a restricted default. Changing configuration does not upgrade an old executable. -After publication, update an existing global .NET tool with `dotnet tool update --global codegiveness.postgresql-sharp-mcp --version 0.4.0`. For npx, update the version in your client's `args` to `@codegiveness/postgresql-sharp-mcp@0.4.0`; retain package-specific script approval. For archives, fully quit the client/server and replace the extracted files together. Recheck `--version` before reconnecting. +After publication, update an existing global .NET tool with `dotnet tool update --global codegiveness.postgresql-sharp-mcp --version 0.5.0`. For npx, update the version in your client's `args` to `@codegiveness/postgresql-sharp-mcp@0.5.0`; retain package-specific script approval. For archives, fully quit the client/server and replace the extracted files together. Recheck `--version` before reconnecting. **Breaking behavior:** a targets-file entry is now a host/login connection profile, not a database allowlist. The same credentials can select other physical databases on that PostgreSQL server. Omitted access mode means `unrestricted`; `list_databases` returns live databases rather than configured aliases. Preserve an existing explicit `POSTGRES_ACCESS_MODE=restricted` and review PostgreSQL grants before upgrading. diff --git a/npm/package.json b/npm/package.json index 26a1a9e..391a543 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "@codegiveness/postgresql-sharp-mcp", - "version": "0.4.0", + "version": "0.5.0", "description": "Database-agnostic PostgreSQL MCP server with live discovery and bounded per-call selection. Installs one platform package with the .NET runtime bundled; no .NET installation or runtime downloads required.", "license": "MIT", "author": "codegiveness", @@ -22,11 +22,11 @@ "postinstall": "postgresql-sharp-mcp-npm-install" }, "optionalDependencies": { - "@codegiveness/postgresql-sharp-mcp-darwin-arm64": "0.4.0", - "@codegiveness/postgresql-sharp-mcp-darwin-x64": "0.4.0", - "@codegiveness/postgresql-sharp-mcp-linux-arm64": "0.4.0", - "@codegiveness/postgresql-sharp-mcp-linux-x64": "0.4.0", - "@codegiveness/postgresql-sharp-mcp-win32-x64": "0.4.0" + "@codegiveness/postgresql-sharp-mcp-darwin-arm64": "0.5.0", + "@codegiveness/postgresql-sharp-mcp-darwin-x64": "0.5.0", + "@codegiveness/postgresql-sharp-mcp-linux-arm64": "0.5.0", + "@codegiveness/postgresql-sharp-mcp-linux-x64": "0.5.0", + "@codegiveness/postgresql-sharp-mcp-win32-x64": "0.5.0" }, "publishConfig": { "access": "public", diff --git a/src/PostgreSqlMcp/PostgreSqlMcp.csproj b/src/PostgreSqlMcp/PostgreSqlMcp.csproj index fe65389..315f9b1 100644 --- a/src/PostgreSqlMcp/PostgreSqlMcp.csproj +++ b/src/PostgreSqlMcp/PostgreSqlMcp.csproj @@ -1,7 +1,7 @@ Exe - 0.4.0 + 0.5.0 true codegiveness.postgresql-sharp-mcp postgresql-sharp-mcp