Experimental source-available SQLite/libSQL backend for human-and-agent-native workflows, with Studio and scoped MCP access.
Overview
Typed data API · local Auth · object Storage · Realtime primitives · Studio · scoped MCP access. Built for fast local iteration and human-and-agent-native workflows, with local SQLite and authenticated remote libSQL profiles. downloads, installs, builds, starts the backend, and opens Studio at http://127.0.0.1:8082. Mekka explores a compact backend surface for people and agents working on the same application. The current release runs on Bun and supports two SQLite-compatible data profiles: a local Bun SQLite database for development and an authenticated remote libSQL primary for self-hosted deployments. A typed data API, Studio, Auth, policy, migrations, Storage, Realtime primitives, and scoped MCP access ship in the same repository. The project is experimental and targets controlled local development and self-hosted beta evaluation. It does not claim full Supabase or PostgreSQL compatibility. The remote profile does not silently fall back to a project .sqlite file.
README
Why Mekka exists
Mekka explores a compact backend surface for people and agents working on the same application. The current release runs on Bun and supports two SQLite-compatible data profiles: a local Bun SQLite database for development and an authenticated remote libSQL primary for self-hosted deployments. A typed data API, Studio, Auth, policy, migrations, Storage, Realtime primitives, and scoped MCP access ship in the same repository.
The project is experimental and targets controlled local development and self-hosted beta evaluation. It does not claim full Supabase or PostgreSQL compatibility.
What runs today
| Surface | Local profile | Self-hosted libSQL profile |
|---|---|---|
| User data | Bun SQLite in the project data directory | Authenticated remote libSQL over HTTPS |
| Studio | Table Editor, restricted SQL Editor, Authentication, Agent Access | The same supported Studio surface; unsupported upstream routes redirect away |
| Schema and rows | Manifest-backed table, column, index, row, and restricted SQL APIs | The same contracts through the selected remote engine; no local user-data fallback |
| MCP metadata | inspect_schema, migrations, policy summary, constrained query explanation |
The same tools against remote libSQL |
| MCP row data | Explicit opt-in query_rows with mcp:data:read |
Explicit opt-in query_rows against remote libSQL |
| Agent writes | Isolated local preview, validation, Studio approval, guarded promotion | Typed unsupported; self-hosted libSQL previews are not faked locally |
| Control plane | Local SQLite stores for Auth, sessions, grants, approvals, and audit state | The same local control plane; database credentials remain server-side |
The remote profile does not silently fall back to a project .sqlite file. If libSQL authentication, routing, or policy resolution fails, the request fails.
Every request carries the full tenant identity, and every user value stays a prepared-statement parameter. That’s the contract:
| Concern | Bound into each request |
|---|---|
| Who is calling | An authed caller with a capability set; the tenant tuple must match the headers exactly |
| Where data can go | One organization, project, environment, branch, generation |
| What it can touch | Type-resolved tables and columns from the schema manifest |
| How big it can be | Row cap, request byte cap, response byte cap, object cap, timeouts |
| Replay safety | SHA-256 fingerprint and reusable idempotency keys |
| Writes from agents | Preview branch plus one-time human-approved promotion when the selected engine profile supports previews; otherwise typed unsupported |
Deep PostgreSQL compatibility still belongs on PostgreSQL. Mekka rejects unsupported behavior instead of faking it. Teams that need native RLS, stored procedures, ranges, or a large extension catalog should use PostgreSQL directly.
Request path
Auth happens before permissions. The backend resolves table and column names through the schema manifest, binds user values as parameters, applies policy, and executes one prepared statement. It never parses user SQL directly: the constrained query dialect becomes an AST first, then a compiled statement, then a bounded execution.
Mutations carry idempotency keys. Payloads, results, uploads, queues, and Realtime buffers have hard limits. Unsupported operations return an explicit error instead of an approximation. Errors don’t carry secrets, SQL values, or stack traces.
What’s inside
Each subsystem ships in the repo and works against the same local project. Open any of them to see what it actually does.
Product tour
Studio contains code derived from Supabase Studio under Apache License 2.0. Provenance and the reproduced license live in apps/studio/UPSTREAM.md and apps/studio/UPSTREAM_LICENSE.
Agent access without production roulette
An AI agent should not need your database password or libSQL JWT. Mekka gives it a short-lived token bound to one organization, project, environment, branch, generation, and application session. Schema access and row access are separate grants. Write access exists only where the active engine profile can create an isolated preview.
Agent
→ one-hour scoped token
→ schema-only metadata by default
→ optional bounded row reads after explicit opt-in
→ optional isolated preview for supported write profiles
→ exact migration approval before production promotion
For profiles with write previews, Mekka stores the migration artifact, SQL, schema hashes, and the destructive-operation flag. Studio shows the change before approval. The approval secret works once and only for that artifact. Promotion checks the production schema again before it runs. The agent can break its preview; production stays behind a human decision and a schema check.
API surface
Every request gates on the tenant tuple organization / project / environment / branch / generation.
Security model
Capability and status
| Capability | Current status |
|---|---|
| Local data | Bun SQLite in one local runtime |
| Self-hosted data | Authenticated remote libSQL with a single writable primary |
| Data access | Typed API and a tested subset of common supabase-js CRUD operations |
| Human workflow | Studio surfaces for tables, restricted SQL, Auth, Agent Access, and approvals |
| Agent workflow | Scoped MCP schema tools and explicit, bounded row reads |
| Agent writes | Preview and human approval where the selected engine supports it; otherwise explicit unsupported |
| PostgreSQL features | Native RLS, RPC, extensions, ranges, and full PostgREST parity are not supported |
| Maturity | Experimental beta for controlled local development and self-hosted evaluation |
Run it
Install Node.js 20 or newer, then:
npx mekka my-app
Pass a folder name if the default mekka directory is taken. The CLI installs Bun when needed. Git is optional; without it, Mekka downloads the GitHub archive over HTTPS and enforces caps on archive size, extracted bytes, and entry count.
Inside an existing checkout:
bun install --frozen-lockfile
bun run dev
| Service | Address |
|---|---|
| Studio | http://127.0.0.1:8082 |
| Backend | http://127.0.0.1:3001 |
Local state stays in apps/studio/.local/.
Self-hosted libSQL profile
Run the pinned single-primary libSQL deployment behind Caddy HTTPS, issue a scoped EdDSA client JWT, and configure Mekka with server-only environment variables:
MEKKA_DATA_ENGINE=libsql-remote
MEKKA_LIBSQL_URL=https://libsql.example.com
MEKKA_LIBSQL_TOKEN_ENV=MEKKA_LIBSQL_TOKEN
MEKKA_LIBSQL_TOKEN=
docker compose -f deploy/libsql/compose.yaml up -d
bun run smoke:libsql
bun run --cwd apps/studio start:production
The baseline is one writable primary with persistent storage. It is not multi-writer and does not claim automatic failover or PITR. Backups must be encrypted, stored off-host, and restored into an isolated volume during drills. See docs/runbooks/self-hosted-libsql.md.
Verification and development
bun run check runs the full gate: formatting, lint, typecheck (core and Studio), the CLI suite, workspace tests, Studio tests, the production build, and smoke tests.
Read CONTRIBUTING.md before opening a pull request.
Roadmap
Repository map
| Path | Purpose |
|---|---|
apps/gateway |
Data, Storage, Realtime, compatibility, MCP mount |
apps/sqlite-meta |
Database management, Auth, branches, approvals, local MCP |
apps/mcp |
Agent resources, tools, and mutation workflow |
apps/studio |
Studio and production web server |
apps/health-service |
Health check example |
packages/auth-core |
Sessions, JWT/JWKS, OAuth, token rotation |
packages/storage-core |
Database adapter and object storage |
packages/engine-core |
Local SQLite, remote libSQL, replica routing, typed outcomes |
packages/realtime-core |
Changefeeds, channels, Broadcast, Presence |
packages/branch-core |
Preview lifecycle and guarded promotion |
packages/migration-engine |
Migration artifacts, checkpoints, restore |
packages/policy-engine |
Row and field authorization |
packages/schema-manifest |
SQLite schema contracts |
packages/sqlite-compiler |
Prepared SQLite statement compiler |
packages/query-ast |
Validated Data API queries |
packages/protocol |
Tenant identity, capabilities, errors |
packages/studio-domain-sdk |
Typed Studio API client |
packages/mekka-cli |
The npx mekka launcher and mcp-stdio bridge |
packages/onboarding-core |
Project provisioning and connect analyzer |
apps/studio/UPSTREAM.md |
Supabase Studio provenance |
Support and security
Use GitHub Issues for reproducible bugs, questions, and feature requests. Report vulnerabilities privately through the process in SECURITY.md.
Mekka is under active development. Reviewed paths have tests. A production deployment still needs monitoring, verified backups, deployment hardening, and an independent security review.
License
Install
npx mekkaConfiguration
{
"mcpServers": {
"mekka": {
"type": "http",
"url": "https://mekka.example.com/mcp",
"headers": {
"Authorization": "Bearer <temporary-agent-access-token>"
}
}
}
}