Skip to content

Repository files navigation

sqlize

An SQL layer for REST API endpoints.

Query GitHub issues, Stripe customers, GitLab pipelines — any REST API that has an OpenAPI spec — using plain SQL. Pagination, auth, filter pushdown, and cross-API JOINs are handled automatically.

sqlize demo

SELECT number, title, state
FROM issues
WHERE owner = 'rust-lang' AND repo = 'rust' AND state = 'open'
LIMIT 5;
[5]{number,title,state}:
  154162,"(EXPERIMENT) Replace zero-deps nodes with a singleton",open
  154161,On E0277 tweak help when single type impls traits,open
  154160,Rollup of 6 pull requests,open
  154158,"Audit `//@ run-pass` directives in UI tests",open
  154157,Enforce deterministic signed zero behavior in float min/max and clamp,open

Why SQL

REST APIs are imperative — you need to know the endpoint, the parameters, the pagination scheme, the response shape. SQL is declarative — you say what you want and the engine figures out how to get it.

The mapping is natural: endpoints become tables, parameters become columns, and the query planner translates SQL into API calls. WHERE owner = 'rust-lang' becomes a path parameter in the URL. WHERE state = 'open' becomes ?state=open in the query string. ORDER BY, GROUP BY, LIMIT are applied locally by the engine after fetching.

Powered by Apache DataFusion. Supports SELECT, WHERE, ORDER BY, LIMIT, OFFSET, GROUP BY, HAVING, COUNT, SUM, AVG, MIN, MAX, JOIN, subqueries, CTEs, UNION/INTERSECT, CASE, CAST, and more. Read-only.

Quickstart

# macOS / Linux
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Benaiad/sqlize/releases/latest/download/sqlize-installer.sh | sh

# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/Benaiad/sqlize/releases/latest/download/sqlize-installer.ps1 | iex"

# Or with Cargo
cargo install sqlize

Query GitHub

export GITHUB_TOKEN=ghp_...
export SQLIZE_BEARER_ENV_VAR=GITHUB_TOKEN
sqlize --spec specs/github-minimal.json
sqlize> SHOW TABLES;
sqlize> DESCRIBE issues;
sqlize> SELECT number, title FROM issues WHERE owner = 'rust-lang' AND repo = 'rust' LIMIT 5;

Query Stripe

export STRIPE_API_KEY=sk_test_...
export SQLIZE_BEARER_ENV_VAR=STRIPE_API_KEY
sqlize --spec specs/stripe-minimal.json
sqlize> SELECT email, name FROM customers;

Query GitLab

export GITLAB_TOKEN=glpat-...
export SQLIZE_BEARER_ENV_VAR=GITLAB_TOKEN
sqlize --spec specs/gitlab-minimal.json
sqlize> SELECT title, state FROM issues WHERE id = '12345' LIMIT 5;

Curated minimal specs ship with the repo:

Spec Tables Notes
specs/github-minimal.json 9 Issues, PRs, commits, releases, repos
specs/gitlab-minimal.json 5 Projects, issues, MRs, pipelines, members
specs/stripe-minimal.json 5 Customers, charges, subscriptions, invoices, products

Any REST API with an OpenAPI spec works — these are just the ones we've tested.

Cross-API JOINs

Query multiple APIs in a single session:

sqlize \
  --spec github:specs/github-minimal.json \
  --spec stripe:specs/stripe-minimal.json
SELECT c.name, c.email, k.commit_message
FROM stripe.customers c
JOIN github.commits k ON c.name = k.author_login
WHERE k.owner = 'openclaw' AND k.repo = 'openclaw'
LIMIT 5;

Each spec registers a named schema. Use qualified names (github.issues, stripe.customers) to query across APIs.

Per-spec auth

Each spec resolves its token independently:

export SQLIZE_BEARER_ENV_VAR_GITHUB=GITHUB_TOKEN
export SQLIZE_BEARER_ENV_VAR_STRIPE=STRIPE_API_KEY

Falls back to SQLIZE_BEARER_TOKEN / SQLIZE_BEARER_ENV_VAR when no per-spec var is set.

MCP server

sqlize runs as an MCP server, giving AI agents SQL access to REST APIs through three tools:

  • get_schemaCREATE TABLE DDL for table discovery
  • query — executes SQL, returns results in TOON
  • explain — shows the execution plan without running it

Three tools. Not 25 per service. Adding more APIs adds tables, not tools — the context window cost stays flat.

claude mcp add \
  --transport stdio \
  --env SQLIZE_SPEC_PATH=/path/to/specs/github-minimal.json \
  --env SQLIZE_BEARER_ENV_VAR=GITHUB_TOKEN \
  --scope user \
  sqlize-github -- sqlize mcp

Results are returned in TOON format by default — 40-50% smaller than JSON, designed for LLM consumption.

CLI reference

Single-shot commands for scripts and automation:

sqlize --spec specs/github-minimal.json query "SELECT number, title FROM issues WHERE owner = 'rust-lang' AND repo = 'rust' LIMIT 5"
sqlize --spec specs/github-minimal.json explain "SELECT ..."
sqlize --spec specs/github-minimal.json schema issues

Output is JSON by default, --format toon for compact output, --format table for human-readable tables.

How queries map to API calls

EXPLAIN SELECT number, title FROM issues
WHERE owner = 'openclaw' AND repo = 'openclaw' AND state = 'open'
ORDER BY created_at DESC
LIMIT 10;
  • owner, repo — path parameters, substituted into the URL
  • state — query parameter, pushed to the API as ?state=open
  • ORDER BY, LIMIT — applied locally by DataFusion after the fetch

Path parameters are required — omitting them fails at query planning, before any HTTP call is made.

Pagination

sqlize paginates automatically using the standard Link header (rel="next") or common response body fields (next, next_url). Works with GitHub, GitLab, Stripe, and most REST APIs without configuration.

Each table scan fetches pages lazily until one of these limits is reached:

  • SQL LIMIT — only the needed pages are fetched
  • max_rows (default 1000) — caps total rows per table scan when no SQL LIMIT applies

Override the default:

sqlize --spec specs/github.json --max-rows 5000
# or
export SQLIZE_MAX_ROWS=5000

Bring your own API

sqlize works with any REST API that has an OpenAPI 3.x spec. For large specs, use --tags to filter endpoints:

curl -L -o specs/github.json \
  https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json

sqlize --spec specs/github.json --tags repos,issues

Status

Early development — APIs may change.

About

An SQL layer for REST API endpoints.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages