fancy-api
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fancy-apilist records in the quotes collection"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Fancy
Paste data. Get a fancy API.
Fancy turns a table you paste, a CSV you drop, or a declarative YAML/JSON
file into a live, queryable REST API in minutes — filtering, sorting,
pagination, and full-text search included, with an OpenAPI doc generated for
free. It started from a simple problem: an app with nowhere to store its
data shouldn't need a backend project to get one. Every API also gets an
MCP endpoint, so an AI agent can read and
write records the same way a person edits a spreadsheet — no custom
integration code required. Self-hostable with one docker compose up.
Repo: github.com/carmelosantana/fancy-api
Screenshots
Dashboard — your APIs, at a glance.

Create an API — paste a table, get a schema.

Instant success — live endpoints, a write token, ready to use.

Query playground — build a filtered request and see the response.

Related MCP server: MCP-Maker
Install
Docker (recommended)
cp .env.example .env
make upOpen http://localhost:3000 and log in with the
ADMIN_PASSWORD from your .env (defaults to change-me — change it before
exposing this beyond your own machine).
The container seeds a demo API, hello-tony, on first start. Try it:
curl http://localhost:3000/api/hello-tony/quotes/randommake logs # follow the web service
make down # stop the stack (data persists in the fancy-data volume)Local dev
make install # pnpm install
make seed # populate the hello-tony demo against ./data/app.db
make dev # next dev on http://localhost:3000Deploying somewhere else
Running Dokploy or Coolify (or anything Docker-based)? See Deploy on Dokploy / Coolify below.
The four ways to create an API
From /admin/new, pick one:
Paste table — paste tab- or comma-separated rows (e.g. straight out of a spreadsheet); Fancy infers column names and types.
Upload CSV — drop a
.csvfile.Paste CSV — paste raw CSV text.
Import declarative file — paste a YAML or JSON spec that fully describes the api, its collection(s), and their schema + records.
A minimal declarative file looks like this:
slug: hello-tony
name: Hello Tony Quotes
collections:
- slug: quotes
name: Quotes
schema:
- { name: author, type: string }
- { name: text, type: string }
- { name: year, type: number }
- { name: topic, type: string }
records:
- author: Winston Churchill
text: "Success is not final, failure is not fatal: it is the courage to continue that counts."
year: 1941
topic: perseveranceschema[].type is one of string, number, boolean, date. Any api can
be exported back to this same shape from its detail page — the declarative
file is a portable import/export format, not the runtime store (see
Architecture).
Query syntax
Every collection gets a read API at /api/{api}/{collection}, plus
/{id}, /random, and an OpenAPI document at /api/{api}/openapi.json.
Responses are shaped { data, meta: { total, limit, offset } } (a single
object, no meta, for /{id} and /random).
Syntax | Meaning |
| Equals |
| Greater than / or equal |
| Less than / or equal |
| Not equal |
| Substring match |
| In a set |
| Sort ascending by |
| Page size (default |
| Page offset |
| Free-text search across the collection's string columns |
Examples against the seeded hello-tony demo:
# List, filtered and sorted
curl "http://localhost:3000/api/hello-tony/quotes?topic=perseverance&sort=-year"
# Pagination
curl "http://localhost:3000/api/hello-tony/quotes?limit=5&offset=10"
# Free-text search
curl "http://localhost:3000/api/hello-tony/quotes?q=courage"
# One random record — handy for a "quote of the day" widget
curl "http://localhost:3000/api/hello-tony/quotes/random"
# A single record by id
curl "http://localhost:3000/api/hello-tony/quotes/1"
# OpenAPI document for the whole api
curl "http://localhost:3000/api/hello-tony/openapi.json"Writing data with AI agents (MCP)
Every api gets a write-capable MCP
endpoint at /api/mcp/{api}, served over Streamable HTTP. Read-only tools
work without a token; the four mutating tools require the api's write token,
sent as Authorization: Bearer <writeToken>. The token is shown once when
the api is created and can be rotated from its detail page in /admin at
any time.
{
"mcpServers": {
"hello-tony": {
"url": "http://localhost:3000/api/mcp/hello-tony",
"headers": {
"Authorization": "Bearer <writeToken>"
}
}
}
}Tools exposed:
Tool | Requires token | Description |
| No | Paginated list of a collection's records |
| No | Fetch one record by id |
| No | Filter, sort, and free-text search |
| Yes | Insert a single record |
| Yes | Insert multiple records at once |
| Yes | Shallow-merge a patch into a record by id |
| Yes | Delete a record by id |
Self-hosting
Persistence — the sqlite database lives at
DATABASE_PATHinside the container (default/data/app.db), backed by the namedfancy-dataDocker volume.make downstops the stack without touching it;make cleandeletes it (with a confirmation prompt).Admin password — set
ADMIN_PASSWORDin.envbefore first start. Fancy has a single admin credential, no multi-user accounts (v1).Ports — the container listens on
3000; the compose file maps it to3000on the host. Change the left side of theports:mapping indocker-compose.ymlto use a different host port.Seeding —
SEED_ON_START=1(the default) seeds thehello-tonydemo on every start; it's idempotent, so this is safe to leave on. Set it to0for a blank instance.
Deploy on Dokploy / Coolify
Fancy is a single Docker container plus one sqlite file, which maps cleanly onto either platform. Two supported paths:
Option A — Dockerfile app (recommended)
Point the platform at this repo (or a fork) and let it build Dockerfile
directly — no compose file needed.
App type: "Dockerfile" / "Application from Git", build context = repo root, dockerfile path =
Dockerfile.Port: the container listens on
3000— tell the platform to route to that port.Volume — required: attach a persistent volume mounted at
/data. The sqlite database lives at/data/app.db; without a persistent mount at that path, every redeploy starts from an empty database. This is the single most important setting for either platform.Environment: set the variables from the table below.
Domain: add a domain and enable HTTPS (see the HTTPS note below).
Option B — Docker Compose
Point the platform at docker-compose.yml and let it deploy the web
service as-is.
Set the same environment variables (below) on the
webservice.Map your domain to service
web, container port3000.The
ports:mapping indocker-compose.yml(${WEB_PORT:-3000}:3000) is there for localdocker compose upconvenience — on a PaaS the platform's reverse proxy talks to the container directly over its internal network, so publishing a host port is usually unnecessary and can conflict with other stacks. The domain/proxy feature is what actually exposes the app publicly; thefancy-datanamed volume still provides the persistent/datamount either way.
Required environment
Variable | Required | Notes |
| Yes | The single admin login for |
| Yes, for anything beyond a demo | HMAC key signing the admin session cookie. Without it the app generates a random secret per process, so every redeploy logs everyone out. Generate one with: |
| No |
|
| No | Defaults to |
HTTPS note
Session cookies are marked Secure in production, so the app must be served
over HTTPS — the browser will silently drop the cookie otherwise and login
won't persist. Both Dokploy and Coolify default to a Traefik + Let's Encrypt
domain setup that handles this for you; if you instead hit the app over
plain HTTP by bare IP, expect to be logged out on every navigation.
Scaling note
Fancy's storage is a single sqlite file (via libsql), not a networked
database — run one instance only. Multiple replicas pointed at the same
/data volume will corrupt or race on writes.
Deploy on Vercel (with self-hosted libsql)
Vercel's filesystem is ephemeral (no persistent /data volume), so the
Docker/local-file mode above doesn't apply there. Instead, Fancy can connect
to a remote libsql database — the same SQLite engine, just reached over
HTTP(S) instead of a local file. The query builder, repo, ingest, and MCP
layers don't change at all; only the connection does.
1. Run a libsql server somewhere reachable over HTTPS
sqld (the libsql server) is a single lightweight process — self-host it on
any small always-on VPS (or use a hosted libsql provider like Turso). This
repo includes docker-compose.sqld.yml for the self-hosted route:
docker compose -f docker-compose.sqld.yml up -dBy default it listens with no auth (fine for a private network or while
wiring things up) on the host port 8899. For a production deploy, put it
behind a TLS-terminating reverse proxy and enable JWT auth — see the
commented SQLD_AUTH_JWT_KEY guidance in that compose file — so you can
connect with a libsql:// URL + bearer token instead of plain http://.
2. Configure the Vercel project
This is a pnpm monorepo (apps/web + packages/core). The simplest setup:
In the Vercel project's Settings → General → Root Directory, set it to
apps/web. Vercel auto-detects Next.js there and installs the pnpm workspace from the repo root on its own (it walks up to findpnpm-workspace.yaml), sopackages/coreis resolved correctly without any extra build-command overrides.If you'd rather not use the Root Directory setting (e.g. you want to keep deploying from the repo root for some other reason), a minimal
vercel.jsonat the repo root with"buildCommand": "pnpm --filter web build"and"outputDirectory": "apps/web/.next"(plus"installCommand": "pnpm install") achieves the same thing — but Root Directory is less to maintain, so this repo doesn't ship one.
3. Required environment variables
Variable | Notes |
| The remote libsql URL, e.g. |
| The JWT/token for that database. Leave unset for the no-auth dev setup. |
| Same as the Docker deploy — the single admin login. |
| Same as the Docker deploy — set this or every redeploy invalidates sessions. |
Vercel serves everything over HTTPS by default, so the Secure session
cookie (see AGENTS.md) works out of the box — no HTTPS caveat to manage here
like the bare-IP case in the Dokploy/Coolify section above.
4. Seed once
Unlike the Docker image (which can seed on every container start), a Vercel deployment has no "on start" hook against a remote DB. Seed it once from your machine, pointed at the same database:
DATABASE_URL=libsql://your-host DATABASE_AUTH_TOKEN=your-token pnpm seedHonesty check / things to confirm on your own deploy
The local-file mode is completely unaffected by any of this — nothing above changes
DATABASE_PATHbehavior, Docker, ormake up.next.config.ts'soutput: "standalone"is harmless on Vercel — Vercel builds Next.js natively and ignoresstandaloneoutput, so no config change is needed there.middleware.tsruns on the Node.js runtime (runtime: "nodejs") becauselib/auth.tsusesnode:crypto, which the default Edge middleware runtime doesn't support. This should work unmodified on Vercel, but Node-runtime middleware has had a narrower rollout than Edge middleware — this hasn't been verified against an actual Vercel deployment, so confirm/adminand/api/_manage/*auth still gate correctly on your first deploy.No Vercel deploy was performed as part of this change — the config above is written correct-by-construction from Vercel's documented monorepo behavior, not verified against a live deployment.
Architecture
Monorepo, two packages:
packages/core— the engine: ingest (CSV/paste/declarative-file parsing + type inference), the generic JSON-column record store, the query builder, the declarative import/export spec, and the MCP tool definitions. Framework-agnostic and meant to be reusable outside this Next.js app.apps/web— the Next.js (App Router) binding: the admin builder UI, the public read API, the management API, and the MCP HTTP route.
Storage today is SQLite (via drizzle-orm/libsql + @libsql/client) —
the query layer is built directly on SQLite's json_extract. It runs either
as a local file (DATABASE_PATH, the Docker/localhost default) or
against a remote libsql database (DATABASE_URL + DATABASE_AUTH_TOKEN
— a self-hosted sqld or Turso, for ephemeral-FS hosts like Vercel; see
Deploy on Vercel above) — it's
the same engine and protocol either way, so nothing downstream changes.
Postgres is a roadmap item, not a working option yet (see
docker-compose.yml's commented-out db service and the design spec
below); switching backends will need query-layer changes, not just a
connection string.
The declarative file (YAML/JSON) is a portable import/export format for moving an api's shape + data in and out of Fancy. The database is the runtime source of truth — the file is a snapshot, not something Fancy reads from at request time.
Development
Target | Does |
|
|
| Seed the local DB, then run |
| Production build ( |
| Unit tests (Vitest) |
| Playwright end-to-end suite |
| Populate the |
| Typecheck every workspace package |
| Build (if needed) and start the Docker stack |
| Stop the stack (keeps data) |
| Follow the web service's logs |
| Restart the web service |
| Stop the stack and delete the data volume (confirms first) |
|
|
Run make (or make help) to print this from the terminal.
Testing
Unit (
make test/pnpm test) — 99 Vitest tests overpackages/coreandapps/web: ingest/type-inference, the query builder, the record repo, spec import/export, auth token handling, and the MCP tool definitions.End-to-end (
make e2e/pnpm e2e) — 8 Playwright specs driving the real app: creating an api from a pasted table, the query playground, MCP round-trips, and more.
Contributing
Design constraints and the decisions behind them live in AGENTS.md —
read it before making changes (human or agent).
License
AGPL-3.0. If you run a modified version of Fancy as a network service, the AGPL requires you to make your modified source available to users of that service.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/carmelosantana/fancy-api'
If you have feedback or need assistance with the MCP directory API, please join our Discord server