Adding a database to ChatGPT is one MCP URL and about ninety seconds of clicking. Deciding which database takes longer, and getting it wrong is expensive later. So this repo starts with the choice.
freebase.cloud hands out free instances of fifteen engines, each reachable over the same MCP endpoint shape. Pick one, mint a token, paste it into ChatGPT, done. If you picked badly, mint a token for a different engine — the connector setup is identical and takes the same ninety seconds.
| Engine | Version | Reach for it when | Language the model writes | Native TCP |
|---|---|---|---|---|
| PostgreSQL | 16.2 | Related tables, constraints that catch model mistakes, JSONB when you need to cheat | SQL | yes, 5432 |
| MongoDB | 7.0.4 | Nested records whose shape is still changing | MQL + aggregation pipeline | yes, 27017 |
| Redis | 7.2.3 | Counters, flags, TTL'd state between turns | Redis commands | yes, 6379 |
| MySQL | 8.0.36 | You already think in MySQL, or the schema came from somewhere that did | SQL | no |
| MariaDB | 11.3.2 | Same, but you prefer the MariaDB lineage and its syntax additions | SQL | no |
| SQLite | 3.45.1 | One small dataset, no ceremony, file-database mental model | SQL | no |
| ClickHouse | 24.1.5 | Aggregating a lot of rows and you want the answer fast | SQL (columnar/OLAP) | no |
| Elasticsearch | 8.12.0 | The question is "find things that mention…" rather than "select where" | Query DSL | no |
| Neo4j | 5.17.0 | The relationships are the data — paths, degrees of separation | Cypher | no |
| Cassandra | 4.1.4 | Write-heavy, wide rows, access patterns already known | CQL | no |
| DynamoDB | 2024.1 | Key/document access in an AWS-shaped codebase | DynamoDB API | no |
| InfluxDB | 2.7.4 | Timestamped measurements, retention, downsampling | Flux / InfluxQL | no |
| TimescaleDB | 2.14.2 | Time series, but you want to keep writing SQL | SQL (Postgres + Timescale) | no |
| Prometheus | 2.50.1 | Metrics, rates, and alerting-shaped questions | PromQL | no |
| CockroachDB | 23.2.4 | Distributed SQL semantics, Postgres-compatible surface | SQL | no |
Reading the last column. Three engines — PostgreSQL, Redis and MongoDB — expose a real TCP wire
protocol, so psql, redis-cli, mongosh, Prisma, ioredis, Mongoose and friends connect unmodified. The
other twelve are reached over the HTTP query API and over MCP; the port and CLI listed for them describe
the dialect your statements are written in, not a socket you can dial. If a legacy client has to connect
directly, that narrows your choice to three.
- Most people should start with PostgreSQL. Constraints and types make a model's mistakes fail loudly instead of quietly, which matters more than any other property when something else is writing your rows.
- Choose MongoDB when you cannot yet name your columns. Adding a field to a document costs nothing; adding one to a schema you have already populated costs a migration.
- Choose Redis when nothing needs to be queried six different ways. Set it, increment it, expire it.
- Do not choose an analytics engine for a hundred rows. ClickHouse over a small table is slower to reason about than Postgres, and no faster in practice at that size.
- Do not choose Neo4j because the data has foreign keys. Choose it when you are asking questions about paths — who connects to whom, through how many hops.
The steps are identical for all fifteen engines.
Sign up on the freebase.cloud dashboard — free, no credit card. Create a session and choose your engine. There is no cluster to size and no provisioning wait.
Settings → MCP → New Token → select the connection → copy the URL:
https://freebase.cloud/api/mcp/YOUR_TOKEN
The token is a path segment. That is why every configuration in this repo sets Auth: None and no
Authorization header ever appears. It also means the URL is the credential — treat it accordingly.
The name you gave the connection becomes the prefix on all four tool names. This README uses attic, so
the tools are attic_query, attic_store, attic_list_tables, attic_annotate_table. Two connections
called attic and garage give you eight unambiguous tools; two both called db give you a bad afternoon.
OpenAI documents this in two places, and the two documents describe different menu paths. Rather than guess, look in both — one of them exists in your build.
Path A — Apps developer mode
- Settings → Apps
- Advanced settings → enable developer mode
- Apps → Create
- Paste
https://freebase.cloud/api/mcp/YOUR_TOKENinto the MCP server URL field - Authentication: None
- Press Scan Tools. Four tools with your connection prefix should appear. If nothing appears, the URL was truncated or the token was revoked — re-copy it from the dashboard.
- Create
Path B — Connectors
- Settings → Connectors
- Add custom connector
- Paste the same URL, authentication None, confirm
Either way, ChatGPT requires the streamable HTTP transport. That is what this endpoint serves. The
older HTTP+SSE arrangement — a /sse endpoint plus POST /messages — is deprecated in the current spec
revision and is not what you are configuring here.
Custom apps are off by default in new chats. Press + in the composer, find your app under Connectors, switch it on. Then confirm it is live:
What tables exist in my database?
[attic_list_tables]
No tables yet — the connection is empty. Want me to create one?
An answer that does not mention a tool call means the app is not enabled in this conversation, whatever the settings page says.
Every connection, every engine, the same four:
| Tool | Purpose |
|---|---|
<name>_query |
Read, in the engine's own language — SQL, MQL, CQL, Cypher, PromQL, Flux, Redis commands |
<name>_store |
Write — inserts, upserts, updates, and the DDL that creates your structures |
<name>_list_tables |
Enumerate tables, collections, keyspaces, indices or measurements |
<name>_annotate_table |
Attach a human description so the model understands what a column means |
Two engines add extras: PostgreSQL surfaces pg_dump, pg_restore and pg_tables; the SQLite
engine surfaces sqlite_master and sqlite_version.
Annotate before you ask anything important. It is the least glamorous tool and the one that changes
answer quality most. value is a number; whether it means purchase price, current resale value, or the
insurer's figure is not recoverable from the schema, and a model will pick one and never mention that it
guessed.
A home inventory — what you own, where it is, what it cost — is a good test because it is genuinely modellable three ways.
Postgres. Two tables, a foreign key, one query.
Create
roomsanditems, then tell me the total purchase value per room, highest first.
[attic_store] CREATE TABLE rooms (...); CREATE TABLE items (...);
[attic_query] SELECT r.name, sum(i.purchase_cents)/100.0 AS total
FROM items i JOIN rooms r ON r.id = i.room_id
GROUP BY r.name ORDER BY total DESC;
Garage 4,210.00
Living room 3,880.00
Kitchen 1,940.00
MongoDB. One collection, room as a field, warranty as a nested document that only some items have.
Which items have a warranty expiring in the next 90 days?
[attic_query] db.items.find({ "warranty.expires": { $lte: <date> } })
No schema change was needed for the items that have no warranty at all. That is the whole argument for the document model in one sentence.
Redis. Not an inventory so much as the state around one — the Redis 7.2 instance holds the counters and TTL'd flags between turns.
How many boxes have I logged in the garage today?
[attic_query] GET count:packed:2026-08-18
[attic_store] INCR count:packed:2026-08-18
Same connector, same four tools, three genuinely different shapes. examples/home_inventory.mjs runs
against whichever you chose and adapts its prompts to the dialect.
If you are building rather than chatting, skip the connector UI entirely:
{
"model": "gpt-5.6",
"tools": [{
"type": "mcp",
"server_label": "attic",
"server_description": "Home inventory. Free cloud database — query and store structured data.",
"server_url": "https://freebase.cloud/api/mcp/YOUR_TOKEN",
"require_approval": "never"
}],
"input": "What is the total insured value of everything in the garage?"
}Notes that save debugging time:
server_descriptionis read by the model on every call. Put your unit conventions in it — cents versus dollars, minutes versus hours — even if you have also annotated the tables. Redundancy is cheap here.require_approval: "never"suits a database you own driven by prompts you wrote. Leave approvals on the moment any part of the prompt comes from a user, a scraped page or an inbox.- One
toolsarray can hold several MCP servers. Giving a model both a durable SQL connection and a Redis one is a reasonable architecture: durable records in one, ephemeral counters in the other.
Stated plainly, because the situation is genuinely unsettled and confident write-ups on this are usually wrong:
- OpenAI's documentation describes this feature in two different places with two different menu paths. Check Settings → Apps → Advanced settings and Settings → Connectors before concluding the feature is missing from your account.
- Developer mode for custom MCP servers is documented for Pro, Plus, Business, Enterprise and Edu.
- Full write access is currently rolling out to Business, Enterprise and Edu workspaces.
- The practical consequence: on some accounts today the model will happily run
attic_queryand declineattic_store. That is the rollout, not a broken token, and no amount of reconfiguration will change it.
Nothing here is stuck behind that. The Responses API path above is unaffected in both directions, and the same URL works in other clients — the connection is not owned by any one vendor.
| Client | Where the URL goes |
|---|---|
| Claude Desktop / web | Settings → Connectors → Add custom connector (UI only; the desktop JSON config does not take remote HTTP servers) |
| Claude Code | claude mcp add --transport http attic <url> |
| Cursor | ~/.cursor/mcp.json, a plain url key |
| VS Code / Copilot Chat | .vscode/mcp.json, top-level servers, "type": "http" |
| Gemini CLI | gemini mcp add --transport http attic <url> — in settings.json the key is httpUrl, not url |
| n8n | MCP Client Tool node, transport HTTP Streamable, auth None |
| Zed | settings.json → context_servers |
Per-engine walkthroughs for the Claude side live at
https://freebase.cloud/how-to-connect-claude-to-<engine> — for example
PostgreSQL,
MongoDB,
Redis.
- The free tier targets development, prototyping and small production workloads. No SLA, uptime figure, backup schedule or storage quota is published, and none is invented here. Export anything you would regret losing.
- The URL is a bearer credential. Not in commits, not in screenshots. Rotate it in Settings → MCP.
- A model with write access will occasionally write when you meant "check". Constraints help. Approvals help more. Both are cheaper than a restore you do not have.
- Switching engines later means moving data, not just changing a URL. That is why the decision table is at the top rather than the bottom.
examples/
pick_engine.py Decision helper — narrows 15 engines to a shortlist offline,
then optionally asks the model to sanity-check the choice
home_inventory.mjs Node 18+ — the same inventory task, adapted per engine
smoke_test.sh curl — confirms the endpoint answers and lists your tools
README.md how to run them
- Engine list and signup — every connection starts here
- Free PostgreSQL instance · the MongoDB engine page · Redis instance page · ClickHouse · Neo4j
- Model Context Protocol specification — current revision 2026-07-28
- OpenAI Responses API
MIT licensed. If your engine choice went badly for an instructive reason, a pull request adding it to the decision notes would be genuinely useful.
freebase.cloud is an independent service and is not affiliated with OpenAI, or with any of the database projects and vendors named above — PostgreSQL, Oracle (MySQL), MongoDB, Inc., Redis Ltd., SQLite, the Apache Software Foundation (Cassandra), Amazon Web Services (DynamoDB), ClickHouse, Inc., Elasticsearch B.V., Neo4j, Inc., MariaDB Foundation, InfluxData, Prometheus, Timescale, Inc. or Cockroach Labs.