Skip to content

aws-ec2-volumes-works - #18

Merged
general-kroll-4-life merged 1 commit into
mainfrom
feature/aws-signing-tidy
May 26, 2022
Merged

general-kroll-4-life merged 1 commit into
mainfrom
feature/aws-signing-tidy

Conversation

@general-kroll-4-life

Copy link
Copy Markdown
Contributor

Summary

  • Support read operations against aws.
  • Expand integration testing.

@general-kroll-4-life
general-kroll-4-life merged commit 4b8cf9e into main May 26, 2022
@general-kroll-4-life
general-kroll-4-life deleted the feature/aws-signing-tidy branch May 26, 2022 13:07
jeffreyaven added a commit that referenced this pull request Jul 18, 2026
* 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>
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant