https://github.com/benaiad/sqlize
SQL interface for REST APIs
https://github.com/benaiad/sqlize
cli developer-tools mcp openapi rest-api rust sql
Last synced: 3 months ago
JSON representation
SQL interface for REST APIs
- Host: GitHub
- URL: https://github.com/benaiad/sqlize
- Owner: Benaiad
- License: mit
- Created: 2026-03-22T06:01:24.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-03T18:17:03.000Z (3 months ago)
- Last Synced: 2026-04-03T20:55:05.590Z (3 months ago)
- Topics: cli, developer-tools, mcp, openapi, rest-api, rust, sql
- Language: Rust
- Size: 3.69 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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.

```sql
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](https://datafusion.apache.org/). 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
```sh
# 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
```sh
export GITHUB_TOKEN=ghp_...
export SQLIZE_BEARER_ENV_VAR=GITHUB_TOKEN
sqlize --spec specs/github-minimal.json
```
```sql
sqlize> SHOW TABLES;
sqlize> DESCRIBE issues;
sqlize> SELECT number, title FROM issues WHERE owner = 'rust-lang' AND repo = 'rust' LIMIT 5;
```
### Query Stripe
```sh
export STRIPE_API_KEY=sk_test_...
export SQLIZE_BEARER_ENV_VAR=STRIPE_API_KEY
sqlize --spec specs/stripe-minimal.json
```
```sql
sqlize> SELECT email, name FROM customers;
```
### Query GitLab
```sh
export GITLAB_TOKEN=glpat-...
export SQLIZE_BEARER_ENV_VAR=GITLAB_TOKEN
sqlize --spec specs/gitlab-minimal.json
```
```sql
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:
```sh
sqlize \
--spec github:specs/github-minimal.json \
--spec stripe:specs/stripe-minimal.json
```
```sql
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:
```sh
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_schema`** — `CREATE 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.
```sh
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](https://github.com/toon-format/toon) format by default — 40-50% smaller than JSON, designed for LLM consumption.
## CLI reference
Single-shot commands for scripts and automation:
```sh
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
```sql
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:
```sh
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:
```sh
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.