Embedded StackQL MCP server for Swift/macOS (package, conformance tests, CI)#1
Merged
Merged
Conversation
…sts, CI
Initial implementation of the Swift member of the StackQL embedded-MCP
family.
Package (Sources/StackQLMCP):
- Platform/Pins: packaging platform keys and per-version sha256 pins,
mirroring the Go/Rust siblings and the packaging repo contract.
- LaunchArguments: the canonical, cwd-independent launch args
(mcp --mcp.server.type=stdio --approot <abs> --mcp.config {...} [--auth]),
default read_only mode, ~/.stackql approot and ~/.stackql/mcp-server-bin
shared cache.
- BinaryResolver: locate-or-install in priority order - override env/path,
bundled .app resource (Contents/Resources or Contents/Helpers), shared
cache, then download. Atomic, sha-verified cache install.
- BundleFetcher: download the .mcpb release bundle, verify against the
published pin (in-package table -> platforms.json -> .sha256 asset),
extract the manifest entry_point with traversal guards.
- StackQLServer: spawn the binary over stdio via Foundation.Process, wire
pipe FDs into the MCP SDK StdioTransport, connect a Client; convenience
listToolNames/call wrappers. Quarantine cleared only on the download path.
Tests: offline unit suite (args, platform, pins, cache, sha,
bundle-extraction) plus a conformance integration suite gated on
STACKQL_MCP_INTEGRATION that mirrors the packaging repo smoke-test.py
(initialize -> tools/list -> pull_provider github null_auth ->
list_services) and asserts read_only refuses mutations.
CI runs on macOS runners on PRs to main, pushes to main, and v* tags:
build, offline unit tests, then the conformance suite.
Docs: bundling-and-notarisation.md (codesign/spctl/notarytool transcripts,
why --deep must not be used on the embedded binary, sandbox reality check)
and a rewritten README. Only dependency is modelcontextprotocol/swift-sdk.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first CI run failed in the swift-sdk dependency (HTTPClientTransport.swift: "missing argument for parameter 'of'"), which is the symptom of compiling its swift-tools-version 6.1 package with Swift 6.0. The workflow had pinned Xcode_16.app (Swift 6.0). Select Xcode 16.4 (the macos-15 default, Swift 6.1.2) instead, and bump our own manifest to swift-tools-version 6.1 to document the real floor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
An empty override string built URL(fileURLWithPath: "") which resolves to the cwd; locateOffline then returned it instead of nil. Guard against empty. Caught by testLocateOfflineReturnsNilWhenNothingPresent on CI. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Initial implementation of
stackql-mcp-swift, the Swift member of the StackQL embedded-MCP family.What's here
SwiftPM package
StackQLMCP(Sources/StackQLMCP):Platform/Pins- packaging platform keys and per-version sha256 pins, matching the Go/Rust siblings and the packaging-repo contract.LaunchArguments- the canonical, cwd-independent launch args (mcp --mcp.server.type=stdio --approot <abs> --mcp.config {...} [--auth]), defaultread_only,~/.stackqlapproot and~/.stackql/mcp-server-binshared cache.BinaryResolver- locate-or-install in priority order: override (STACKQL_MCP_BINARY/path) -> bundled.appresource (Contents/ResourcesorContents/Helpers) -> shared cache -> download. Atomic, sha-verified cache install.BundleFetcher- download the.mcpbbundle, verify against the published pin (in-package table ->platforms.json->.sha256asset), extract the manifestentry_pointwith traversal guards.StackQLServer- spawn over stdio viaFoundation.Process, wire pipe FDs into the MCP SDKStdioTransport, return a connectedClient;listToolNames/callconvenience. Quarantine cleared only on the download path.Tests (
Tests/StackQLMCPTests): offline unit suite (args, platform, pins, cache, sha, bundle-extraction) + a conformance integration suite gated onSTACKQL_MCP_INTEGRATIONthat mirrors the packaging reposmoke-test.py(initialize -> tools/list ->pull_providergithubnull_auth->list_services) and assertsread_onlyrefuses mutations.CI (
.github/workflows/ci.yml): macOS runners only (the SDK and the value of this repo are macOS); runs on PRs tomain, pushes tomain(merge), andv*tags. Build -> offline unit tests -> conformance suite.Docs:
docs/bundling-and-notarisation.md(codesign/spctl/notarytool transcript checklist, why--deepmust not touch the already-notarised embedded binary, sandbox reality check) and a rewritten README.Notes
modelcontextprotocol/swift-sdk(sets the floors: Swift 6.0 / Xcode 16, macOS 13). The project notes mention Swift 5.10+, but the SDK requires 6.0, so that is the effective minimum.CloudLensdemo app is intentionally out of scope for this PR (milestone 2).Generated with Claude Code.