mcp server
moogodev
A lightweight database for serverless applications.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 21, 2026Moogo
A lightweight database for serverless applications. Every project gets its own SQLite file and its own key, and you talk to it over HTTP — no connection string, no driver, no connection pool to manage. Object storage lives under the same project, behind its own credential.
This repository is the whole service: a Go API, the React dashboard that it serves from the same origin, and the small news service behind the dashboard's update feed.
What you get
- SQL over HTTP —
POST /queryfor reads,POST /execfor writes, with prepared statements only and a tokenizing sanitizer that runs before anything touches the database. - One database per project — a real SQLite file you can back up, with its own secret key and its own quota (250 MB per database, 15 seconds per statement, 64 KB per statement text).
- Object storage — buckets under the same project, with their own storage credential: upload, preview, public/private objects.
- Cursor-based pagination — stable
next_cursor+totalfor object listings (no offset drift). - Range requests —
206 Partial Content,416 Range Not Satisfiable,If-Rangefor resumable downloads. - Custom Cache-Control — send
Cache-Controlheader on upload to override defaults (public, max-age=31536000, immutable,no-store, etc.). - Maintenance/Vacuum —
POST /maintenance(vacuum) ormoogo db vacuum(REINDEX → ANALYZE → VACUUM → WAL checkpoint). - Rate-limit headers —
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reseton every response. - Base URLs in responses —
public_url_base(CDN origin) +url_base(API origin) for client-side URL construction. - Per-object publishing —
PATCH /bucket/.../keywithis_public: true; bucket toggle sets default for new uploads. - Dashboard QoL — bulk select, copy authenticated/public URLs, bulk publish/make private, delete multiple.
- Official JS/TS client —
npm i @moogodev/clientwith full TypeScript types. - OAuth rate limiting —
/auth/google*endpoints limited separately from email/password (30/min vs 10/min shared). - Dashboard — projects, a table browser with a visual table builder, a SQL console that runs pasted multi-statement scripts in order (with an examples shelf), a read-only schema visualizer with relationship edges, bucket browsing, and backups.
- Accounts — email + password with verification and reset flows, Google OAuth, rate limits on every sensitive route, and API keys scoped per project.
- Docs built in — the whole manual ships with the product at
/docs, from quickstart to error codes to an AI adoption prompt you can paste into any coding agent.
What Moogo is for
Moogo is built for applications that want simplicity, isolation, and speed over raw scale.
| Use case | Why Moogo fits |
|---|---|
| Serverless functions / Edge workers | No connection pool, no driver, no cold start. Just POST /query with a key. |
| Small SaaS / Multi-tenant apps | One SQLite file per project = structural isolation. No RLS policies to get wrong. |
| AI agents / LLM tools | Native MCP server (cmd/mcp) exposes SQL + object storage as tools. No HTTP client to write. |
| Internal tools / Admin panels | Dashboard included — table browser, SQL console, schema visualizer, bucket browser. |
| Prototypes → Production | Same API from day one. No migration to "real" database needed. |
| Apps ≤ 250 MB data / project | Honest ceiling, reported in every response. |
The pattern: a few tables, a handful of queries, a few MB of files, and you want zero operational overhead.
What Moogo is not for
| You need | Use instead |
|---|---|
PostGIS / spatial queries | PostGIS on Postgres |
| Cross-region read replicas | Managed Postgres (Supabase, Neon, RDS) |
| Concurrent analytical scans (OLAP) | ClickHouse, DuckDB, BigQuery |
| Database > 250 MB per project | Postgres, MySQL, or a larger SQLite host |
| Row-level security across tenants | You get file isolation — RLS not needed |
GRANT/REVOKE, multiple DB roles | Moogo has one key per project |
Triggers, ATTACH, load_extension | Not supported (security design) |
| Self-hosting (this version) | Planned for future release |
The trade-off is intentional: Moogo optimizes for the 80% of apps that don't need Postgres features, giving them structural isolation, zero-driver integration, and honest limits.
What is in here
- Control plane — accounts, projects, quotas, credentials. Postgres, because it is internal state and needs transactions.
- Data plane — SQL and object storage for one project. SQLite, because that is what the customer actually owns.
- Dashboard — table browser, SQL console, schema visualizer and bucket browser, served from the same origin as the API so there is no CORS and one cookie jar.
- News service — a second binary (
cmd/news, frontend innews/) behind the dashboard's announcement feedGET /api/updatesand its own site. Separate process, separate database. - MCP server — a separate binary (
cmd/mcp) that exposes the SQL API as Model Context Protocol tools over stdio, so a coding agent can callquery,execandtransactionwithout hand-writing an HTTP client. It talks only to the data plane, never to the database directly. - Command line client — a separate binary (
cmd/moogo) for applying a SQL file, seeding once, resetting a database, compacting withdb vacuum, and listing or deleting objects. It is an HTTP client and nothing else: same routes, same credentials, same rules as curl, and no configuration that reaches past the API. Install viacurl -fsSL https://get.moogo.dev | sh(no Go required) orgo install github.com/moogodev/moogodev/cmd/moogo@latest. - Official JS/TS client —
@moogodev/clienton npm with full TypeScript types, cursor pagination, Range downloads, presigned URLs, signed uploads, and credential management.
The two planes share no tables. A client on the data plane never learns whether a project exists on the control plane; a signed-in user never holds a secret they did not ask for.
Build
The binary embeds the built frontend, so the frontend has to exist first. In a
fresh clone web/dist is committed, so this is only needed after changing
web/ui:
cd web/ui && npm install && npm run build && cd ../..
go build ./cmd/api
go build ./cmd/mcp # optional: the MCP server for coding agents
go build ./cmd/moogo # optional: the command line client
Install CLI (binary)
The fastest way, no Go required:
curl -fsSL https://get.moogo.dev | sh
Or build from source (requires Go):
Frontend scripts (in web/ui):
| Script | What it does |
|---|---|
npm run dev | Vite dev server — serves files and proxies /auth and /api to the Go API, which still runs separately |
npm run build | tsc -b && vite build → web/dist, embedded by go build |
npm run lint | oxlint |
npm run verify:docs | renders every docs page outside a browser and checks links |
Run it against a Postgres instance and a data directory:
export MOOGO_DATABASE_URL='postgres://user:pass@localhost:5432/moogo?sslmode=disable'
export MOOGO_SESSION_SECRET="$(openssl rand -base64 32)"
export MOOGO_DATA_DIR=./data
./api
dev.sh exports the local defaults and starts the API if you would rather not
do it by hand, along with the Postgres it uses. It is development only — the
session secret it defaults to is published in this repository, and production
refuses to start with it.
./dev.sh # the "dev" environment: localhost:8080
./dev.sh staging # a second one, running beside it
An environment is one self-contained set of state — its own Postgres cluster
and database, its own directory of project files, its own ports — living under
~/.moogo-dev/ (~/.moogo-dev/<name>/ for a named one). The first run creates
it; later runs reuse it. That is what makes a scratch environment safe to
create, reset or leave broken without touching the one you work in every day.
Ports are derived from the name and printed at start, so the same environment
lands on the same ports every time; MOOGO_HTTP_PORT, MOOGO_PGPORT,
MOOGO_DATA_DIR, MOOGO_DATABASE_URL and the rest still override any of it.
MOOGO_ENV accepts exactly development, test or production. It is the
switch the production rules hang on, so a value the code does not branch on
stops the server at startup instead of quietly running with the development
ones.
Every other setting has a default; internal/config/config.go is the list.
The one rule
| Endpoint | Accepts | Rejects |
|---|---|---|
/query | Reads — SELECT, VALUES, PRAGMA, EXPLAIN, WITH that selects | Writes, with not_a_read |
/exec | Writes — INSERT, UPDATE, DELETE, CREATE, ALTER, DROP | Reads, with not_a_write |
Sending the wrong kind of statement is rejected rather than quietly accepted, so you find out immediately instead of after it has written something.
Documentation
- Deployment guide — every step, every setting, every failure mode, written for an agent operating the VPS
- Quickstart — an account to a working
query in two minutes (source:
internal/docs/files/quickstart.md) - Architecture decisions — what is locked in, and why
deploy/README.md— systemd unit, nginx site, backup and healthcheck scripts- Contributing — what makes a good change, and the gates to run
- Security policy — how to report a vulnerability
Tests
# Unit tests and race detector; database integration tests skip themselves.
go test -race ./...
# Full suite, integration included — needs a scratch Postgres.
MOOGO_TEST_DATABASE_URL='postgres://user:pass@localhost:5432/moogo_test?sslmode=disable' \
go test -race ./...
Support Moogo — help, sponsor, fund
Moogo is free, open source (MIT), and needs help to keep going. If it is useful to you, here is how to give back — all of it matters:
- Use it & report issues — a clear bug report with steps to reproduce is funding-grade help. Open an issue — the bug template asks for exactly what makes it actionable.
- Contribute — docs, fixes, tests, guides for your favourite framework. Small pull requests are welcome and reviewed — see CONTRIBUTING.md.
- Report security problems privately — never in a public issue. See
SECURITY.md: email moogo.dev@gmail.com
with
[SECURITY]in the subject, or use a private GitHub security advisory. - Sponsor / become a funder — running the infrastructure, the VPS, domains, and ongoing development are paid for out of pocket. If Moogo saves you time, consider backing it: the Sponsor button on the repository leads to GitHub Sponsors. Recurring funding is what makes this sustainable; one-time support counts too.
Sponsors get listed in the repository (with permission) and early access to the roadmap discussions.
License
MIT — see LICENSE. Use it, change it, sell it; keep the notice.