Repository navigation
foundations-of-join-and-array-responses - #11
Merged
Merged
Conversation
jeffreyaven
added a commit
that referenced
this pull request
Jul 18, 2026
* Add OCI image and npm wrapper install vectors Two new distribution channels alongside the .mcpb bundles, both gated by the same smoke test (now supporting --docker <image> and --cmd '<command>' modes in addition to bundle mode): OCI (docker.io/stackql/stackql-mcp): - oci/Dockerfile: debian-slim, non-root, binary from the release zips staged by 'make oci-stage' (COPY --chmod=0755 - host-independent), io.modelcontextprotocol.server.name label for registry validation, CMD with the cwd-safe approot/audit args - make oci (local amd64 build) / make oci-push (multi-arch push) - build.yml: build + in-container smoke at PR time - publish.yml: multi-arch push, soft-skipped without DOCKERHUB_* secrets npm (@stackql/mcp-server): - npx-able launcher: downloads the platform's published .mcpb on first run, verifies sha256 against pins baked into the package, caches under ~/.stackql/mcp-server-bin/, spawns with cwd-safe args; extra args pass through; diagnostics on stderr only - scripts/render-npm-manifest.sh: pins from PUBLISHED .sha256 files (post-publish step, same ordering rule as server-json) - make npm-manifest / make npm-pack; npm publish stays manual (2FA) - build.yml: wrapper smoke via STACKQL_MCP_BUNDLE override (published pins do not exist at PR time for a new version) - publish.yml: renders real pins post-upload, attaches tarball artifact registry/server.template.json gains oci and npm package entries (schema validated against the live registry). mcpName in package.json and the image label satisfy the registry's namespace ownership checks. Verified locally: docker build + smoke (amd64 container, full MCP exercise), npm wrapper end-to-end against published 0.10.500 assets (download, sha verify, extract, cache, spawn, full MCP exercise, cache reuse on second run), npm pack contents (4 files, 3.4kB). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add PyPI wrapper install vector (stackql-mcp-server) Same launcher pattern as the npm wrapper, in stdlib-only Python (zero dependencies): downloads the platform's published .mcpb on first run, verifies sha256 against pins baked into the package, caches under ~/.stackql/mcp-server-bin/ (shared with the npm wrapper), execs the binary with the cwd-safe args (os.execv on posix, subprocess on Windows). Console scripts: stackql-mcp and stackql-mcp-server (the latter so 'uvx stackql-mcp-server' resolves directly). - pypi/: hatchling pyproject, package module, README with the 'mcp-name: io.github.stackql/stackql-mcp' marker the MCP Registry requires for pypi namespace validation - scripts/render-pypi-manifest.sh + make pypi-manifest / pypi-build (same post-publish ordering rule as npm; twine upload stays manual for 2FA) - build.yml: pypi-wrapper smoke job (venv install, STACKQL_MCP_BUNDLE override); publish.yml: pypi-dist artifact job - registry template: pypi package entry (schema-validated) - docs: install.md section 5 (uvx/pip), README/CLAUDE.md/npm README Verified locally: full smoke via the installed console script against published 0.10.500 assets (download, sha verify, extract, spawn, full MCP exercise), sdist+wheel build, wheel contains platforms.json + entry points + mcp-name marker in METADATA. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add setup-stackql-mcp GitHub Action Composite action: installs the signed stackql binary (sha256-verified against the release .sha256, or from a local bundle via bundle-path for CI/testing), defaults to read_only server mode, and emits: - binary-path output + PATH entry - mcp-config output (mcpServers JSON) that plugs directly into anthropics/claude-code-action's mcp_config input - STACKQL_MCP_BIN env (the npm/pypi wrappers detect it and skip their own download) build.yml gains an action-test job that installs via the action from a locally built bundle and smokes the server using the action's own emitted config. Lives under action/ for development; GitHub Marketplace listing requires extraction to a public repo with action.yml at the root (planned: stackql/setup-stackql-mcp). Verified locally on Windows: download + sha verify against published pin, extraction, JSON-escaped paths in mcp-config, and a full MCP smoke driven by the emitted config in read_only mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
jeffreyaven
added a commit
that referenced
this pull request
Jul 18, 2026
…tials tool (#688) (#689) * initial commit * updates * v0.10.500 * Set executable bit on shell scripts for Linux/macOS runners Committed from Windows, the scripts lacked +x in the git index, so CI failed with 'Permission denied' on every runner. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Invoke scripts via bash so a lost exec bit cannot break the build Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add make sign target and optional envelope signing in publish workflow - scripts/sign.sh: sign dist/*.mcpb in place and regenerate .sha256 (signature is appended to the bundle, so checksums must be recomputed); soft-skips when no signing material is configured so CI can call it unconditionally - publish.yml: sign bundles before upload when MCPB_SIGNING_CERT / MCPB_SIGNING_KEY (PEM content) secrets are set - work around broken 'mcpb verify' (upstream CLI calls node-forge p7.verify which is unimplemented, so every signed bundle reports as unsigned): treat verify as advisory, assert the MCPB_SIG_END block Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add append-signature.py for externally-produced CMS signatures Frames a detached DER SignedData (e.g. from OpenSSL via PKCS#11 against a hardware token) in the MCPB signature layout and regenerates the .sha256. Round-trip verified against mcpb's own extractSignatureBlock. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add workflow_dispatch re-publish path to publish.yml Re-publishes the release pinned in release.yaml from current main without moving the tag. The confirm_release input must match the pin exactly; uploads clobber the existing assets. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add StackQL icon to bundle manifest Packs assets/icon.png (stackql.io favicon art, 180x180 png) into every bundle root and references it from the manifest, so Claude Desktop shows the logo as the extension avatar. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix server.json template for registry validation rules - description must be <= 100 chars - mcpb packages must not have registryBaseUrl (full URL in identifier) Both surfaced on the first live publish of 0.10.500, which succeeded after these changes. Also gitignore .tools/ (local mcp-publisher). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Record current Anthropic directory submission form URLs The old 'Interest Form: MCP Directory' is deprecated; it now redirects to separate local-server and remote-server forms. StackQL uses the local form. Also mark the Official MCP Registry as published (0.10.500). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix server death under Claude Desktop: cwd-independent approot and audit Claude Desktop launches extensions with cwd '/', read-only on macOS. stackql's audit sink defaults to a file in the cwd with strict failure mode, so the server exited immediately after initialize ('Server disconnected'). The default approot (<cwd>/.stackql) would fail the same way on first provider pull. - manifest args now pass --approot ${HOME}/.stackql (plain arg - on Windows ${HOME} expands with backslashes, invalid inside JSON) and --mcp.config '{"server": {"audit": {"disabled": true}}}' - smoke-test.py now launches the server with the manifest's own mcp_config.args (substituting ${__dirname}/${HOME} to temp dirs), so manifest regressions fail the gate instead of surfacing in Desktop - docs/install.md manual-config example gets the same flags with explanation (no variable substitution exists in that file) Found by testing the published darwin bundle in Claude Desktop on macOS; reproduced root cause against the binary directly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Document registry SHA-pin recovery after in-place republish Registry versions are immutable; rebuilt assets need a suffixed registry version (e.g. 0.10.500.1) plus status-delete of the stale entry. Learned the hard way on the cwd-fix republish. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update listings tracker: registry live, Anthropic/Glama/mcp.so submitted 13-06-26 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Restructure listings tracker with status/date/follow-up columns; add new venues Jeff's table restructure (Status, Date, Listing URL, Follow up, Last Updated columns; current submission states for all venues) plus net-new rows: Goose Extensions, Zed Extensions, Warp MCP Catalog, Roo Code Marketplace, GitHub Actions Marketplace. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Feature/install vectors (#11) * Add OCI image and npm wrapper install vectors Two new distribution channels alongside the .mcpb bundles, both gated by the same smoke test (now supporting --docker <image> and --cmd '<command>' modes in addition to bundle mode): OCI (docker.io/stackql/stackql-mcp): - oci/Dockerfile: debian-slim, non-root, binary from the release zips staged by 'make oci-stage' (COPY --chmod=0755 - host-independent), io.modelcontextprotocol.server.name label for registry validation, CMD with the cwd-safe approot/audit args - make oci (local amd64 build) / make oci-push (multi-arch push) - build.yml: build + in-container smoke at PR time - publish.yml: multi-arch push, soft-skipped without DOCKERHUB_* secrets npm (@stackql/mcp-server): - npx-able launcher: downloads the platform's published .mcpb on first run, verifies sha256 against pins baked into the package, caches under ~/.stackql/mcp-server-bin/, spawns with cwd-safe args; extra args pass through; diagnostics on stderr only - scripts/render-npm-manifest.sh: pins from PUBLISHED .sha256 files (post-publish step, same ordering rule as server-json) - make npm-manifest / make npm-pack; npm publish stays manual (2FA) - build.yml: wrapper smoke via STACKQL_MCP_BUNDLE override (published pins do not exist at PR time for a new version) - publish.yml: renders real pins post-upload, attaches tarball artifact registry/server.template.json gains oci and npm package entries (schema validated against the live registry). mcpName in package.json and the image label satisfy the registry's namespace ownership checks. Verified locally: docker build + smoke (amd64 container, full MCP exercise), npm wrapper end-to-end against published 0.10.500 assets (download, sha verify, extract, cache, spawn, full MCP exercise, cache reuse on second run), npm pack contents (4 files, 3.4kB). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add PyPI wrapper install vector (stackql-mcp-server) Same launcher pattern as the npm wrapper, in stdlib-only Python (zero dependencies): downloads the platform's published .mcpb on first run, verifies sha256 against pins baked into the package, caches under ~/.stackql/mcp-server-bin/ (shared with the npm wrapper), execs the binary with the cwd-safe args (os.execv on posix, subprocess on Windows). Console scripts: stackql-mcp and stackql-mcp-server (the latter so 'uvx stackql-mcp-server' resolves directly). - pypi/: hatchling pyproject, package module, README with the 'mcp-name: io.github.stackql/stackql-mcp' marker the MCP Registry requires for pypi namespace validation - scripts/render-pypi-manifest.sh + make pypi-manifest / pypi-build (same post-publish ordering rule as npm; twine upload stays manual for 2FA) - build.yml: pypi-wrapper smoke job (venv install, STACKQL_MCP_BUNDLE override); publish.yml: pypi-dist artifact job - registry template: pypi package entry (schema-validated) - docs: install.md section 5 (uvx/pip), README/CLAUDE.md/npm README Verified locally: full smoke via the installed console script against published 0.10.500 assets (download, sha verify, extract, spawn, full MCP exercise), sdist+wheel build, wheel contains platforms.json + entry points + mcp-name marker in METADATA. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add setup-stackql-mcp GitHub Action Composite action: installs the signed stackql binary (sha256-verified against the release .sha256, or from a local bundle via bundle-path for CI/testing), defaults to read_only server mode, and emits: - binary-path output + PATH entry - mcp-config output (mcpServers JSON) that plugs directly into anthropics/claude-code-action's mcp_config input - STACKQL_MCP_BIN env (the npm/pypi wrappers detect it and skip their own download) build.yml gains an action-test job that installs via the action from a locally built bundle and smokes the server using the action's own emitted config. Lives under action/ for development; GitHub Marketplace listing requires extraction to a public repo with action.yml at the root (planned: stackql/setup-stackql-mcp). Verified locally on Windows: download + sha verify against published pin, extraction, JSON-escaped paths in mcp-config, and a full MCP smoke driven by the emitted config in read_only mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * Post-rollout cleanup: extract action to its own repo, land registry/docs fixes The setup-stackql-mcp action is now its own verified-publisher Marketplace repo (stackql/setup-stackql-mcp), so: - remove the action/ dir (action.yml, install.py, README) - single source of truth is the dedicated repo, tested by its own CI - remove the action-test job from build.yml (coverage moved to that repo) - README + docs/install.md point to stackql/setup-stackql-mcp@v1 Also lands the fixes made during the 0.10.500.2 registry publish: - server.template.json: OCI package entry uses canonical reference in identifier (docker.io/stackql/stackql-mcp:VERSION), no registryBaseUrl or version field - the registry rejects both for oci packages - README: 'Publishing the wrapper packages' section (npm/PyPI/OCI command sequences incl. the PEP-668 venv steps and .pypirc usage) - .gitignore: add .pypirc newline fix and __pycache__/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update listings tracker for Monday rollout - npm, PyPI, Docker Hub, GitHub Actions Marketplace: Published 06-15 - Official MCP Registry: now 0.10.500.2 with all 7 package types - PulseMCP: confirmed live (Official badge) - mcp.directory: submitted 06-15 (24h review) - mcp.so: config flipped to npx (public propagation pending) - Docker MCP Catalog + Smithery: unblocked, in progress - GitHub MCP Registry: recheck now that npm/oci/pypi types are in the registry Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * listings: Smithery N/A (25MB bundle cap), Docker Catalog pending upstream PR Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * listings: correct GitHub MCP Registry guidance (curated, auto-ingest not shipped) github.com/mcp is still empty 06-16 after adding npm/oci/pypi types - the cause is not package types or our config: GitHub's auto-ingest from the official registry is announced but not built yet, and the registry is currently curated. Prerequisite (official registry) is done. VS Code gallery is downstream of it. Updated both rows + the prose to reflect this. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add LICENSE, README, and privacy_policies to bundles (Anthropic review) Anthropic MCP Directory review (Bryan Thompson) asked for three additions before listing: 1. privacy_policies declared in the manifest -> https://stackql.io/privacy 2. MIT LICENSE text shipped at the bundle root (matches declared license) 3. a bundle README covering cloud-provider credentials/--auth, the ${HOME}/.stackql data/config root, and the available tools manifest/BUNDLE_README.md is the bundle-root readme; package.sh now copies it and LICENSE into every bundle. mcpb validate accepts privacy_policies. NOTE: https://stackql.io/privacy must be created and must resolve before re-publishing/re-submitting - it currently 404s. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * LICENSE: copyright year range 2022-2026 (#17) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Release: package stackql v0.10.542 (+ #18 proxy/UA changes) (#19) * LICENSE: copyright year range 2022-2026 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Route wrapper downloads via releases.stackql.io + per-vector UAs (#18) Wrappers now pull the .mcpb bytes from https://releases.stackql.io/stackql instead of GitHub directly. The render scripts split the two concerns: RELEASE_BASE (GitHub) stays the canonical source for the .sha256 pins, while DOWNLOAD_BASE is the proxy front door written as baseUrl into platforms.json. Same bytes behind the proxy, so the sha256 pins still verify. Both launchers now send a distinct, versioned User-Agent so the proxy can attribute traffic per vector: stackql-mcp-server-npm/<version> and stackql-mcp-server-py/<version> (npm previously sent none; pypi sent an unversioned string). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: drop hardcoded provider count from bundle/wrapper READMEs Provider count drifts; describe the set by example instead of pinning "40+". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * listings: update venue tracker statuses Glama/Cursor now published; Goose + Cline submitted; awesome-mcp PR refreshed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * release.yaml: pin stackql v0.10.542 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * render scripts: proxy path is /stackql/<version> without v prefix (#20) The releases.stackql.io proxy serves versioned assets at /stackql/<VERSION>/<asset> (e.g. /stackql/0.10.542/...), NOT v-prefixed. base_url was building /stackql/v<VERSION>/ which 404s. GitHub sha_base keeps the v prefix (v<VERSION>) since that is GitHub's own path scheme. Verified: rendered baseUrl https://releases.stackql.io/stackql/0.10.542 serves all four bundles with sha256 matching the canonical pins. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat: mcp credential (re)sourcing via server.env_file + reload_credentials tool (#688) A process environment block is fixed at spawn, so a stdio MCP server launched without credential env vars (eg by Claude Desktop) can never see later external changes, and credential resolution is already lazy per-request in any-sdk - the gap is purely getting fresh values into the process. This adds: - mcp.config server.env_file: a dotenv-style mutable credential store, sourced into the process env at startup and on demand; identical semantics on Linux, macOS and Windows. Non-empty values only; nothing is ever unset, so failed reloads preserve prior working credentials. - reload_credentials tool: re-sources the env file and reports per-provider resolution status (ok / unresolved / not_checked) and sourced variable names; secret values are never returned, logged or audited. Classified as a select, so available in every mode including read_only. Not supported on the reverse_proxy backend (credentials live in the remote server). - credential-resolution errors on queries now carry an agent-actionable hint to call reload_credentials and retry, so agentic clients self-heal. - robot coverage: stdio harness roundtrip spawning the server without the okta credential var, observing the hinted failure, writing the env file mid-session, reloading, and re-running the query successfully; plus unit coverage for the dotenv parser, sourcing semantics and error hint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: odata pushdown $select unions WHERE and ORDER BY columns (#682) A pushed $select that omits columns referenced only in WHERE / ORDER BY makes a spec-honouring server strip them from the response, so stackql's authoritative client-side re-filter sees absent columns and silently drops every row. buildPushdownIntent now pushes the union of SELECT-list columns and every column referenced in the full predicate tree (including OR branches and non-translatable comparisons, which remain client-side filters) plus ORDER BY columns, order-preserving and deduplicated. SELECT * (no $select restriction) and COUNT paths are unchanged, as is user-facing output shaping. The native_test mock now honours $select server-side, as real OData services do, so the robot scenarios observe the regression end to end: one asserts the pushed union wire shape, the other asserts a row filtered by a non-projected column still returns. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: function projections no longer inherit argument column schema type (#687) A single-arg scalar function over a provider column adopts its argument's column identity during name inference (parserutil.inferColNameFromExpr), and the projection typing then bound the ARGUMENT's provider schema to the FUNCTION's output column. Type-changing functions (typeof, date, datetime) had their text results scanned through the argument's declared type, yielding 0/null, and corrupted same-named sibling projections in the same SELECT ("contagion": co-projecting typeof(col) nulled a bare col). The provider schema now types a projection only when the expression IS the bare column; function and compound expressions default to the backend's text type, which scans dynamically (SQLite is dynamically typed, so type-preserving functions like abs/sum/max are unaffected) and preserves DESCRIBE output for expression-defined provider view columns. Robot: new function-projection suite asserting typeof/datetime over a bare integer column, the sibling-corruption guard, and an aggregate control, against the no-auth native_test XML fixture. Local full-suite sweep green including the provider-view DESCRIBE scenarios. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: disable star-check workflow Renames contribute.yaml to contribute.yaml.disabled: the check ran unauthenticated, failed spuriously on maintainer PRs, and gated nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat: constant-fold WHERE function expressions for provider parameters (#686) Parameter routing consumes only literal comparison values, so a required provider parameter constrained by a pure-literal function expression (eg WHERE start_time = strftime('%s', date('now', '-30 days'))) was silently not supplied and the request failed. A new early-analysis pass evaluates such expressions against the session's SQL backend and substitutes the typed literal into the AST before parameter extraction, so parameter routing, push-down intent and the client-side re-filter all see the same literal the request uses. Scope guards: expressions containing column references, subqueries or tuples are untouched (they remain authoritative client-side filters); NULL results and evaluation failures fall back to pre-existing behaviour; internally routable (pure SQL) statements are exempt, preserving non-deterministic function semantics on the native path. The issue's null/zero projection symptoms share the issue #687 root cause and are covered by that fix and its tests. Robot: required-param-via-lower() fold scenario, portable across sqlite and postgres backends (previously failed with "AWS region is nil"), plus a column-referencing-expression scope guard. Full local functional sweep green over the known environmental baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: robot coverage for page_number REST and pluggable GraphQL pagination strategies (#684) Black-box regression coverage for pagination features shipped in any-sdk v0.5.3-alpha05..alpha11 that previously had only unit coverage: - REST page_number: new no-auth stackql_native_test.paged service against new native_test mock endpoints serving three pages with result_info.page/total_pages; rows carry wire_page so traversal is asserted from STDOUT. Scenarios: full three-page traversal, successive wire page numbers, and the negative case - a response with no total_pages terminator fetches exactly one page (no infinite loop). - GraphQL cursor strategies: three new graph resources, each backed by a dedicated mock endpoint reflecting its strategy-specific wire argument: keyset (rankGt comparator advanced from the last row's sort key), offset (client-side running row count), and page_info (Relay-strict: endCursor stays non-empty on the final page, so completing traversal proves termination via pageInfo.hasNextPage rather than cursor emptiness). Existing cursor_after scenarios unchanged. The offset resource declares a jsonPath the strategy itself ignores: the acquire-layer validation requires one; noted inline in the spec. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat: batch mutation fan-out for IN-list parameters in the planner (#683) DELETE ... WHERE id IN ('a','b','c') now despatches one request per list element, mirroring SELECT semantics. The mutation parameter extraction (ExtractSQLNodeParams) only harvested `=` comparisons, silently skipping IN lists, so the request preparator failed with "missing required path parameter". IN-list elements are now collected and fanned out into the cartesian product of scalar parameter sets - one armoury request per set, each despatched by the existing executor loop. Scalar-only statements produce the identical single parameter set as before; NOT IN and non- literal list members are untouched (they remain client-side concerns). Robot: batch DELETE across two mock-permitted firewalls asserts successful despatch (previously an immediate parameterize error); the gcp mock gains a second deletable firewall to make the fan-out observable as two distinct wire deletions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: remove repo-level FUNDING.yml (moved to org level) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: strengthen batch mutation fan-out coverage (#683) - Robot: batch DELETE ... IN with RETURNING asserts exactly one response row per list element via exact-table match - a regression to single-element despatch now fails the assertion rather than passing on the despatch message alone. - Unit: ExtractSQLNodeParams coverage for scalar-only preservation, per-element fan-out with scalar replication, multi-list cartesian product, and the NOT IN exclusion guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * packaging: adapt imported mcpb tooling to in-repo workflows (manual publish) Companion to the preceding subtree import of stackql-mcpb-packaging under packaging/mcpb (full history preserved). One-stop-shop consolidation: - New .github/workflows/mcp-packaging.yml: validation on packaging/** PRs builds + smoke-tests all four bundles and the OCI image against the latest published release. Publishing is MANUAL (workflow_dispatch with the target version) by design: the consumed release assets include the Authenticode-signed Windows exe and the Apple-notarised darwin .pkg, both signed outside CI, so the flow is push tag -> create release -> attach signed assets -> dispatch. The publish path envelope-signs (when signing secrets are set), uploads bundles to the same-repo release via the default GITHUB_TOKEN (cross-repo STACKQL_RELEASE_TOKEN PAT retired), pushes the OCI image, and emits npm/pypi/server.json artifacts (npm/PyPI publishing stays manual 2FA). - release.yaml version pin and the imported per-directory workflows are removed; local make targets now require explicit VERSION=X.Y.Z. - build.yml push + pull_request paths-ignore gain packaging/** so packaging-only changes never trigger the full Go build matrix. - README / CLAUDE.md / Makefile updated for the new home. Deferred follow-ups (next release cycle): manifest user_config wiring for server.env_file needs a dedicated CLI flag in a released binary (values cannot substitute inside the --mcp.config JSON arg - Windows ${HOME} expands with backslashes); root server.json render lands as a workflow artifact pending automated PR wiring; MCPB_SIGNING_* / optional GEMINI_API_KEY secrets migrate when signing goes live; archive the standalone repo after one green dispatch through this pipeline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * packaging: multiplatform combined bundle for single-artefact venues The Anthropic MCP Directory serves ONE bundle per listing with no per-platform selection; the listing pointed at the darwin-universal bundle, so Windows/Linux directory installs received a Mach-O binary that died before the MCP handshake (confirmed by hash at v0.10.500). This brings the corrective combined artefact in-house: - New `make combined` / `package.sh --combined`: builds stackql-mcp-multiplatform.mcpb from the already-built per-platform bundles (byte-identical binaries, Authenticode/notarisation preserved; no pkgutil or macOS runner needed), hard-failing with the missing-target list unless all four bundles are present. Layout: server/{darwin,linux-x64,linux-arm64,win32}/ selected via mcp_config.platform_overrides; the linux key dispatches through a uname -m shim (Option A) because platform_overrides has no arch dimension. Signed + sha256'd via the existing helpers. - manifest.template.json gains a tokenised compatibility.platforms block so wrong-platform installs of per-platform bundles are refused at install time instead of dying at spawn; the combined template (manifest.combined.template.json, __VERSION__ only) lists all three. - scripts/verify-combined.py byte-asserts every payload: MZ for win32, ELF for both linux binaries, Mach-O fat magic for darwin, sh shebang for the shim - the check that catches a wrong-artefact incident in seconds. Wired into `make combined`. - smoke-test.py now resolves mcp_config.platform_overrides for the host platform (as MCPB clients do) and restores payload exec bits, so the combined bundle is smoke-testable everywhere. - mcp-packaging.yml: `combined` job builds + byte-verifies from the four bundle artifacts; `combined-smoke` matrix installs the combined bundle on ubuntu, ubuntu-arm64 (exercising the shim's aarch64 branch), macos and windows and completes the MCP handshake on each - closing the exact gap the incident went through (per-platform smoke can never detect a wrong artefact being distributed). Publish gates on both; make publish itself stays best-effort to preserve the two-machine local fallback. - docs/anthropic-submission.md corrected: the listing URL is the literal multiplatform bundle URL (no <arch> placeholder); listings do NOT auto-track releases (retracted; refresh requires an email on the Anthropic review thread per release); there is no self-service PR path. Release checklist now includes the combined bundle and the review-thread notification. Validated locally: mcpb accepts the combined manifest and all three per-platform compatibility variants; exec bits survive mcpb pack (0755 on every payload member); verify-combined.py passes against a fake-payload build. Decisions taken: Option A linux shim (B fallback if a client rejects it), asset name stackql-mcp-multiplatform.mcpb, CI-gated publish with best-effort make publish. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: exempt mcp-packaging workflow edits from the full build matrix Changes to .github/workflows/mcp-packaging.yml join packaging/** in build.yml's paths-ignore (both triggers): packaging pipeline edits are validated by lint (actionlint) and by the mcp-packaging PR jobs themselves, and must not burn the ~40 minute Go build matrix. Dispatching mcp-packaging never triggers build.yml (separate workflow, no push event). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: teach actionlint the ubuntu-24.04-arm hosted runner label actionlint 1.6.23 predates the GA arm64 Linux hosted runner, so the combined-smoke matrix entries in mcp-packaging.yml fail the runner-label rule. Register the label in actionlint.yaml, mirroring the existing windows-11-arm entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor: promote env_file to a root --env.file flag for every entrypoint Review feedback on #689: dotenv sourcing is not an MCP concern. The dotenv machinery moves from mcpbackend to internal/stackql/envfile and is wired to a root persistent flag, sourced in initConfig for exec, shell, srv, registry and mcp alike. server.env_file leaves the MCP config surface; the reload_credentials tool re-sources the same flag path mid-session as before. Robot: new exec-entrypoint scenario proves a credential var present only in the dotenv file resolves for plain exec; the existing MCP stdio reload roundtrip now drives --env.file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: halve comment volume across PR-touched code Review feedback on #689: comments were too verbose and risk rotting. Header blocks, function comments, robot [Documentation] entries, python docstrings and workflow/packaging script comments introduced by this PR are cut to roughly half, keeping the constraint or rationale and dropping restated mechanics. No functional change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * packaging: wire credentials env file into MCPB user_config The manifests gain an optional credentials_env_file user_config entry (default ${HOME}/.stackql/credentials.env) passed to the server as --env.file, so Claude Desktop's install/configure screen exposes it. Blank or missing paths are no-ops by the flag's semantics, so an unconfigured install behaves exactly as before. The smoke harness now resolves ${user_config.*} from defaults, matching an accepted configure screen, so the 4-runner matrix exercises the wiring. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Revert "packaging: wire credentials env file into MCPB user_config" The packaging validation (and any real bundle) packs the latest RELEASED stackql binary, which predates --env.file; the unknown flag kills the server at spawn (caught by the bundle smoke on all three legs). The wiring is release-gated: re-apply once a release containing --env.file exists. This reverts commit a885d57. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
selectanddescribesemantics on operations directly returningarraydata.describeleverages data returned by fist preference operation forselecton a given resource, taking no account for input parameters.