Model or dataset
stackql/stackql avatar
stackql/stackql

StackQL pulls its provider registry with TLS verification switched off

Query, provision and operate Cloud, SaaS, API and Model Context Protocol (MCP) resources through a unified SQL-based framework for humans and AI agents.

1,080 stars93 forksGoMIT

At a glance

What is it?
stackql/stackql transpiles SQL into cloud and SaaS API calls and reaches the same engine three ways, through exec, shell, or a Postgres wire server. Its compose harness binds that server to 0.0.0.0 with a client CA list, fetches the provider registry from a CDN with verification disabled, and its parser and wire server dependencies are both pre-release.
Who is it for?
StackQL fits teams that already think in SQL and need to query or provision across several providers from one surface, and who are willing to read the provider registry before trusting what it generates. Verify five things first.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • stackql/stackql1,080 ★ · +121
Star history
Repository2026-09-122026-11-14
stackql/stackql9591.1k

121 Stars in the last 63 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

One binary, three front doors: exec, shell, and srv

StackQL is a standalone Go application that reaches provider APIs by transpiling SQL. The interesting part is that the same engine is exposed three ways.

Client mode comes in two shapes, exec and shell. Server mode is srv, which speaks the Postgres wire protocol so that an ordinary client such as psycopg2 can connect and issue SQL. The mechanism underneath is the same in all three: parse the statement, turn it into API requests against the provider, run those requests, return the results.

The schema is not hand-written. Provider interfaces are defined as extensions to each provider's own OpenAPI specification, and those definitions generate both the SQL schema and the API client. The definitions live in the StackQL Registry rather than in this repository, and the semantics of the interactions live in a separate library, any-sdk.

The practical consequence is that a StackQL deployment has a moving part most SQL tools do not have: the schema you query is generated from a provider specification fetched at run time.

The registry is fetched from a CDN with verifyConfig set to nopVerify

The compose harness shows how a provider registry is addressed. The registry argument carries a url pointing at a statically.io CDN path for the dev branch of the provider registry, and next to it a verifyConfig object with a single key, nopVerify, set to true.

So the source of the generated schema, which by the project's own description determines what SQL surface exists and which API calls get made, is fetched over a channel where certificate verification is turned off. Everything the tool generates, the SQL schema and the API client, descends from that fetch.

To be fair to the file it comes from, this is a test harness. The credentials in it are labelled as functional test dummies, and the key identifier in the aws entry is literally some-key-not-a-secret. The paths under /opt/stackql/credentials/dummy/ say the same. So this is not a production default being shipped carelessly.

It is still the clearest statement in the repository of what a registry fetch can look like, and it is worth knowing that the flag exists and is a boolean you set per registry.

srv binds 0.0.0.0 and expects a client certificate

The same command line that sets credentials and registry sets up the Postgres server, and the TLS block is the interesting part of it.

The pgsrv.tls argument names a keyFilePath and a certFilePath for the server, and a clientCAs entry that is a base64 encoded client certificate read from disk at container start. That is mutual TLS: the server presents a certificate and the client is expected to present one back against a listed authority.

Two other flags decide reachability. The address is 0.0.0.0, so the server listens on every interface of whatever it runs in rather than on loopback. The port comes from a variable with a default of 5476, expressed as --pgsrv.port=${PG_SRV_PORT_MTLS:-5476}.

Binding to all interfaces with client certificate verification is a coherent pairing, and it is the kind of pairing that breaks silently when a client is configured without a certificate, because the failure surfaces as a connection error rather than as a policy message. If you front this with a proxy, check which side terminates the certificate.

The Docker build runs the test suite, and integration tests default to on

The image is a two stage build on golang:1.25.3-bookworm. The preparation stage adds internal, pkg, stackql, mcp_client, and test into a source directory, copies go.mod and go.sum, and runs go get -v -t -d ./... before any compilation happens.

The builder stage then runs CGO_ENABLED=0 go test ./... as part of the build, and only builds the binary if that passes. Version metadata is injected through ldflags, one -X per field: BuildMajorVersion, BuildMinorVersion, BuildPatchVersion, BuildCommitSHA, BuildShortCommitSHA, and BuildDate, plus a separate planbuilder.PlanCacheEnabled value.

Two defaults are worth noticing. RUN_INTEGRATION_TESTS is an ARG that defaults to 1, so a plain image build is an integration run unless you say otherwise. And PLANCACHEENABLED defaults to false, meaning the plan cache is off unless the build opts in, which changes how much work repeated statements cost.

The version fields are also the answer to how a build identifies itself, since the release tags carry a different numbering scheme than major, minor, and patch would suggest.

Only five directories enter the build context

The repository root holds considerably more than the image ever sees. The top level includes internal, pkg, stackql, mcp_client, and test, which the Dockerfile adds into its source directory, plus a Dockerfile, build/, cicd/, packaging/, get-app/, docs/, testLib.Dockerfile, and seven compose files: docker-compose.yml, docker-compose-credentials.yml, docker-compose-externals.yml, docker-compose-live.yml, docker-compose-persist-postgres.yml, docker-compose-testing.yml, and docker-compose.audit.yaml.

So the application builds from a subset of the tree, and the rest, including the packaging and CI directories, is present in the checkout and absent from the image. That is normal for a Go project whose entry points are those directories, and it does mean the container cannot grow new commands that live elsewhere without an edit to the Dockerfile.

The compose file count is the other thing to notice. Seven variants, named for credentials, externals, live, a persisted Postgres, testing, and audit, sit beside the default. Anyone copying one of them should confirm which case it was written for, because the names describe intent rather than configuration.

The parser and the Postgres wire server are pre-release dependencies

go.mod declares go 1.25.3 and pulls in four StackQL components, none of them at a stable tag.

stackql-parser is at v0.0.16-alpha02, and it is the component that turns SQL into whatever the engine does next. psql-wire is at v0.1.2-beta01, and it is what makes server mode speak to psycopg2. any-sdk, the library that defines provider interaction semantics, is at v0.6.0-alpha01, and stackql-labs/omnisdk is at v0.1.3-alpha05. A stackql-parser version of 0.0.x also tells you the module has not been numbered as a stable library yet.

Against those, two dependencies are pinned to 2018 pseudo-versions: chzyer/readline at v0.0.0-20180603132655 and olekukonko/tablewriter at v0.0.0-20180130162743. Those two handle the interactive shell, which is the least interesting part of the system to be moving slowly.

The broader dependency list shows the same spread, with kin-openapi for the OpenAPI extensions, pgx and lib/pq for the Postgres side, gosnowflake for the Snowflake side, cobra and viper for the command line, and go-sdk for MCP.

Release tags encode a build counter in the patch position

The three most recent releases are v0.11.669 on 2026-09-08, v0.12.718 on 2026-09-22, and v0.12.732 on 2026-09-30.

Look at the numbers rather than the dates. The minor moves from 11 to 12, and the third component runs into the hundreds. That is a build counter wearing a semver slot, not a semver promise about compatibility. Two weeks separate the first two tags and eight days separate the last two, and the third component rises by 49 and then by 14, which is the shape of commits counted rather than of breaking changes classified.

The consequence is that a pin has to be exact. A range such as a minor version wildcard would pull in a large number of builds, and there is nothing in the numbering that tells you which of them changed behaviour. The ldflags in the Dockerfile carry the same fields, BuildMajorVersion, BuildMinorVersion, BuildPatchVersion and the commit identifiers, so a binary can report both what it was built from and which tag you meant to install.

The MCP surface is one flag, five install vectors, and 40 plus providers

StackQL also runs as an MCP server, which is how an agent reaches the same engine:

sh
stackql mcp --mcp.server.type=stdio

The claim attached to it is SQL over 40 or more cloud and SaaS providers for AI agents, and the deployment description is that any MCP-capable client can be pointed at it. The README names Claude, VS Code, and Cursor as examples of such clients.

Distribution is unusually spread for a binary: published to the official MCP registry as io.github.stackql/stackql-mcp, and delivered through npm, PyPI, Docker, a GitHub Action, and .mcpb bundles. Two GitHub Marketplace actions are linked for setup and for exec.

One thing to hold onto when an agent is the caller: the same credential shapes apply, in the five flavors the harness shows, service account credentials for Google, an API key from an environment variable for Okta, basic credentials for GitHub, signing v4 for AWS, and a bearer prefixed token for Kubernetes. An agent that can issue SQL can therefore act on all five with whatever credentials the process was given, which is the reason to scope the process before wiring it to a client.

Editorial conclusion

StackQL fits teams that already think in SQL and need to query or provision across several providers from one surface, and who are willing to read the provider registry before trusting what it generates. Verify five things first. Whether your provider definitions come from the release branch of the registry or the dev branch, because that is a difference in behavior and not in documentation. Whether your PostgreSQL client can present a certificate, since srv is built for mutual TLS and nothing weaker is described. What your credentials look like in the five provider shapes the harness demonstrates. Whether the compose file you copy is the one for your case, given there are eight of them. And whether a pre-release parser and a beta wire server are acceptable dependencies for the path you are putting into production.

Frequently asked questions

What is StackQL and how does it reach cloud providers?

It is an open-source Go project that creates, modifies, and queries the state of services and resources using SQL semantics. It parses SQL statements and transpiles them into API requests against the provider, executing them and returning the results.

What is the difference between the StackQL exec, shell, and srv commands?

All three run the same engine. exec and shell are client mode, and srv is server mode, which speaks the Postgres wire protocol so a client such as psycopg2 can connect and issue SQL against provider APIs.

Where does StackQL get the SQL schema for a provider?

Provider interfaces are defined as extensions to each provider's OpenAPI specification, and those definitions generate both the SQL schema and the API client. The definitions live in the StackQL provider registry, and the interaction semantics live in the any-sdk library.

How do I run the StackQL MCP server?

Run stackql mcp --mcp.server.type=stdio over stdio. It is published to the official MCP registry as io.github.stackql/stackql-mcp and distributed through npm, PyPI, Docker, a GitHub Action, and .mcpb bundles, covering SQL over 40 or more cloud and SaaS providers.

Which Python and Go versions does StackQL build against?

go.mod declares go 1.25.3, and the Dockerfile builds on golang:1.25.3-bookworm. The Postgres wire path is handled by stackql/psql-wire at v0.1.2-beta01, which is what a psycopg2 client connects through.

What license is StackQL released under?

MIT. The repository also carries a SECURITY.md at its root, and the release tags follow a build counter in the third version component, with v0.12.732 on 2026-09-30 as the most recent.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. stackql/stackql on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stackql-stackql.svg)](https://hysenlabs.com/projects/stackql-stackql)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/stackql-stackql.svg)](https://hysenlabs.com/projects/stackql-stackql)

Was this useful?