From 190ed8f41e3fd2e4dcb0b1317cee5952c5804f65 Mon Sep 17 00:00:00 2001 From: Jim Vinson Date: Fri, 3 Jul 2026 11:36:54 -0700 Subject: [PATCH] release: prep v1.0.1 (privacy docs + registry mcpb package + CI auto-republish) Distribution and documentation release; no behavior change from 1.0.0. - Bump all package versions and the .mcpb manifest to 1.0.1 (via sync-version). - Add a Privacy Policy section to the README and a privacy_policies entry to the .mcpb manifest, covering BYO-key handling, provider calls, durable memory, and artifact storage (a Claude Connectors Directory prerequisite). - Add a publish-registry job to build-mcpb.yml so each mcpb-v* tag re-publishes the official MCP Registry entry. DNS-auth (us.limner is a DNS namespace, not io.github, so github-oidc does not apply); gated on the MCP_REGISTRY_DNS_KEY secret and tolerant of an already-published immutable version. - CHANGELOG: 1.0.1 section. server.json's mcpb package entry (version + asset URL + file_sha256) lands with the Tuesday tag, since the hash only exists after the mcpb-v1.0.1 build. Co-Authored-By: Claude Opus 4.8 Signed-off-by: Jim Vinson --- .github/workflows/build-mcpb.yml | 88 ++++++++++++++++++++++++ CHANGELOG.md | 20 +++++- README.md | 29 ++++++++ package.json | 2 +- packages/limner-cma-tools/package.json | 2 +- packages/limner-cma-tools/src/version.ts | 2 +- packages/limner-core/package.json | 2 +- packages/limner-mcp/manifest.json | 5 +- packages/limner-mcp/package.json | 2 +- packages/limner-mcp/src/version.ts | 2 +- 10 files changed, 146 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-mcpb.yml b/.github/workflows/build-mcpb.yml index f7245c6..2a4e76d 100644 --- a/.github/workflows/build-mcpb.yml +++ b/.github/workflows/build-mcpb.yml @@ -72,3 +72,91 @@ jobs: files: limner-mcp.mcpb name: ${{ github.ref_name }} generate_release_notes: true + + # Re-publish the official MCP Registry entry so it advertises this release's + # .mcpb package. Registry versions are immutable, so each release must carry a + # new version string (server.json / package.json bump); a re-run of an already + # published version is tolerated rather than failed. us.limner is a DNS-verified + # namespace, so this authenticates with the ECDSA-P384 DNS key (NOT github-oidc, + # which only covers io.github.* namespaces). + # + # Prereq (one-time, manual): store the DNS private key as a repo secret — + # gh secret set MCP_REGISTRY_DNS_KEY < ~/.secrets/limner/mcp-registry-dns.pem + # Until that secret exists this job runs green and no-ops. + # + # NB: confirm the `mcp-publisher` install asset name and `login dns` flag names + # against the installed CLI version during the first manual publish; adjust if + # the CLI surface has changed. + publish-registry: + name: Publish to MCP Registry + needs: pack + if: startsWith(github.ref, 'refs/tags/mcpb-v') + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Download packed bundle + uses: actions/download-artifact@v7 + with: + name: limner-mcp.mcpb + + - name: Gate on DNS key secret + id: gate + env: + MCP_REGISTRY_DNS_KEY: ${{ secrets.MCP_REGISTRY_DNS_KEY }} + run: | + if [ -n "$MCP_REGISTRY_DNS_KEY" ]; then + echo "has_key=true" >> "$GITHUB_OUTPUT" + else + echo "has_key=false" >> "$GITHUB_OUTPUT" + echo "::notice::MCP_REGISTRY_DNS_KEY not set; skipping registry publish." + fi + + - name: Install mcp-publisher + if: steps.gate.outputs.has_key == 'true' + run: | + set -euo pipefail + curl -fsSL -o mcp-publisher.tar.gz \ + "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz" + tar -xzf mcp-publisher.tar.gz mcp-publisher + sudo install -m 0755 mcp-publisher /usr/local/bin/mcp-publisher + + - name: Pin server.json to this release asset + if: steps.gate.outputs.has_key == 'true' + run: | + set -euo pipefail + VERSION="${GITHUB_REF_NAME#mcpb-v}" + SHA="$(shasum -a 256 limner-mcp.mcpb | cut -d' ' -f1)" + URL="https://github.com/${GITHUB_REPOSITORY}/releases/download/${GITHUB_REF_NAME}/limner-mcp.mcpb" + tmp="$(mktemp)" + jq --arg v "$VERSION" --arg url "$URL" --arg sha "$SHA" ' + .version = $v + | .packages = [ ((.packages[0] // {}) + { + registry_type: "mcpb", + identifier: $url, + file_sha256: $sha + }) ] + ' server.json > "$tmp" && mv "$tmp" server.json + echo "Prepared server.json for ${VERSION}:" + cat server.json + + - name: Authenticate (DNS) + if: steps.gate.outputs.has_key == 'true' + env: + MCP_REGISTRY_DNS_KEY: ${{ secrets.MCP_REGISTRY_DNS_KEY }} + run: | + set -euo pipefail + umask 077 + printf '%s' "$MCP_REGISTRY_DNS_KEY" > mcp-dns.pem + mcp-publisher login dns --domain limner.us --private-key mcp-dns.pem --algorithm ecdsap384 + + - name: Publish (tolerate already-published version) + if: steps.gate.outputs.has_key == 'true' + run: | + mcp-publisher publish || echo "::warning::mcp-publisher publish returned non-zero (version may already be published); continuing." + + - name: Scrub key + if: always() + run: rm -f mcp-dns.pem diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d1ec9..9f024aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [1.0.1] - 2026-07-07 + +Distribution and documentation release. Generation, composition, memory, and +transport behavior are unchanged from 1.0.0; the `.mcpb` bundle and Workers +surface are functionally identical. + +### Added +- Privacy Policy section in the README and a `privacy_policies` entry in the + `.mcpb` manifest, covering bring-your-own-key handling, provider calls, + durable memory, and artifact storage (a Claude Connectors Directory + prerequisite). +- The official MCP Registry entry now advertises the downloadable `.mcpb` + package alongside the hosted remote: `server.json` gains an `mcpb` package + pinned to the release asset by SHA-256. +- CI re-publishes the registry entry on each `mcpb-v*` tag, so registry metadata + tracks releases instead of drifting. + ## [1.0.0] - 2026-06-29 v1.0.0 is the first public release — the foundation (`rasa`) variant of the @@ -97,5 +114,6 @@ state (D-RA-04, D-RA-15), and the CMA→D1 memory migration. outside the test suite (Workers: modules now statically imported and attached to the bundle; stdio: loaded via `createRequire` at boot). (r1) -[Unreleased]: https://github.com/vinsonconsulting/limner/compare/v1.0.0...HEAD +[Unreleased]: https://github.com/vinsonconsulting/limner/compare/v1.0.1...HEAD +[1.0.1]: https://github.com/vinsonconsulting/limner/compare/v1.0.0...v1.0.1 [1.0.0]: https://github.com/vinsonconsulting/limner/releases/tag/v1.0.0 diff --git a/README.md b/README.md index a81f620..40951d5 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ family. You deploy rasa as your own instance: free as in beer, no strings or dat - [Tool Surface](#tool-surface) - [Memory](#memory) - [Security](#security) +- [Privacy Policy](#privacy-policy) - [Prerequisites](#prerequisites) - [Quickstart](#quickstart) - [Testing and feedback](#testing-and-feedback) @@ -160,6 +161,34 @@ own instance: and no credentials; only the generation tools and the five `cf*` ops reach outside the isolate, and only with the provider key you supplied. +## Privacy Policy + +Limner is bring-your-own-key software. It collects no analytics and sends no +telemetry to the author. Anything that leaves your machine leaves only because +a tool you called needs it: + +- **Provider calls.** When you run a generation tool, the prompt text and any + reference images you pass are sent to the provider that backs it: OpenAI for + `limner_generate_dalle`, Recraft for `limner_generate_recraft` and the + `limner_upscale` / `limner_vectorize` tools. Those providers process that data + under their own privacy terms. `limner_generate_midjourney` builds a prompt + string locally and calls nothing. In-isolate composition (`limner_compose`, + apart from the five `cf*` ops that use Cloudflare Images) needs no network and + no credentials. +- **Your keys.** OpenAI and Recraft API keys are read from your local + configuration (environment variables or the client's `user_config`) and used + only to authenticate those provider calls. They are never written to logs or + sent anywhere else. +- **Durable memory and projects.** Facts, decisions, and notes you save persist + in Cloudflare D1 on the Workers transport, or in a local SQLite file (default + `~/.limner/limner.db`) on the stdio and `.mcpb` builds. This data stays until + you remove it with `limner_forget` or delete the database. +- **Generated artifacts.** On the hosted Workers transport, images are stored in + Cloudflare R2 and served behind HMAC-signed capability URLs with a short TTL. + On local transports, artifacts stay on your machine. + +Questions or requests about data handling go to jim@vinson.org. + ## Prerequisites For a self-deployed Workers stack: diff --git a/package.json b/package.json index ec1b9c4..5e67507 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "limner", - "version": "1.0.0", + "version": "1.0.1", "description": "MCP image generation agent. Foundation of the Limner family.", "license": "Apache-2.0", "private": true, diff --git a/packages/limner-cma-tools/package.json b/packages/limner-cma-tools/package.json index a47b7ec..677ab7d 100644 --- a/packages/limner-cma-tools/package.json +++ b/packages/limner-cma-tools/package.json @@ -1,6 +1,6 @@ { "name": "@limner/cma-tools", - "version": "1.0.0", + "version": "1.0.1", "description": "Limner CMA sandbox custom tools (TS + zod) wrapping @limner/core pipelines.", "license": "Apache-2.0", "private": true, diff --git a/packages/limner-cma-tools/src/version.ts b/packages/limner-cma-tools/src/version.ts index b24b514..ddd584a 100644 --- a/packages/limner-cma-tools/src/version.ts +++ b/packages/limner-cma-tools/src/version.ts @@ -1,3 +1,3 @@ // GENERATED by scripts/sync-version.mjs — do not edit by hand. // Run `pnpm sync-version` after bumping the root package.json version. -export const VERSION = '1.0.0' as const; +export const VERSION = '1.0.1' as const; diff --git a/packages/limner-core/package.json b/packages/limner-core/package.json index f661de9..9cdc266 100644 --- a/packages/limner-core/package.json +++ b/packages/limner-core/package.json @@ -1,6 +1,6 @@ { "name": "@limner/core", - "version": "1.0.0", + "version": "1.0.1", "description": "Shared TypeScript foundation for Limner: types, bindings, memory and project stores (D1 + local SQLite).", "license": "Apache-2.0", "private": true, diff --git a/packages/limner-mcp/manifest.json b/packages/limner-mcp/manifest.json index 23de64b..4d252f7 100644 --- a/packages/limner-mcp/manifest.json +++ b/packages/limner-mcp/manifest.json @@ -2,7 +2,7 @@ "manifest_version": "0.3", "name": "limner-mcp", "display_name": "Limner — MCP image generation", - "version": "1.0.0", + "version": "1.0.1", "description": "Image generation pipelines (DALL·E, Recraft, Midjourney) plus a hybrid V8 composition stack — all behind the Model Context Protocol.", "long_description": "Limner exposes a single MCP surface that orchestrates third-party image generation APIs and composition primitives:\n\n- **Pipelines**: `limner_generate_dalle`, `limner_generate_midjourney` (prompt-only), `limner_generate_recraft` (composed via Recraft's first-party MCP).\n- **Composition**: `limner_compose` tool wraps a hybrid V8 stack — Photon, jSquash codecs, Satori + resvg-wasm, Cloudflare Images Transformations.\n- **Memory + projects**: durable storage of generation context, decisions, and notes (D1 on the Workers transport; local node:sqlite in this stdio bundle).\n- **Discovery**: `limner_list_pipelines`, `limner_pipeline_capabilities`, `limner_health`, `limner_version`.\n\nLimner is third-party software, independent of Anthropic and Cloudflare.", "author": { @@ -16,6 +16,9 @@ "homepage": "https://github.com/vinsonconsulting/limner#readme", "documentation": "https://github.com/vinsonconsulting/limner/blob/main/packages/limner-mcp/README.md", "support": "https://github.com/vinsonconsulting/limner/issues", + "privacy_policies": [ + "https://github.com/vinsonconsulting/limner/blob/main/README.md#privacy-policy" + ], "license": "Apache-2.0", "keywords": [ "mcp", diff --git a/packages/limner-mcp/package.json b/packages/limner-mcp/package.json index 704e29f..ff8372a 100644 --- a/packages/limner-mcp/package.json +++ b/packages/limner-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@limner/mcp", - "version": "1.0.0", + "version": "1.0.1", "description": "Limner MCP server: Workers Streamable HTTP + stdio + .mcpb bundle.", "license": "Apache-2.0", "private": true, diff --git a/packages/limner-mcp/src/version.ts b/packages/limner-mcp/src/version.ts index b24b514..ddd584a 100644 --- a/packages/limner-mcp/src/version.ts +++ b/packages/limner-mcp/src/version.ts @@ -1,3 +1,3 @@ // GENERATED by scripts/sync-version.mjs — do not edit by hand. // Run `pnpm sync-version` after bumping the root package.json version. -export const VERSION = '1.0.0' as const; +export const VERSION = '1.0.1' as const;