TableFox
PostgreSQL schema intelligence for AI agents (MCP server)
An agent pointed at a database doesn't know the schema. Pasting the whole dump into every prompt is the usual fix — this is the better one.
−29%
Tokens per task
1,200ms
Warm median
14/14
Answers matching SQL
67
pytest tests
01The problem
A schema dump in the prompt grows with the database, costs tokens on every turn, and still produces hallucinated table names.
02The approach
Map the database into a searchable graph of tables, columns and relationships. The agent retrieves the few relations a question needs, drafts bounded SQL, and runs it through a read-only guard. Two MCP calls per task, one connection checkout.
03Architecture — the camera follows the data
How it works
> Two MCP calls per task. One database connection checkout.
Step 1: Question
from the agent
Step 2: Rank
BM25F over schema text
Where the work happens
Step 3: Join
declared FK edges
Step 4: Pack
byte-bounded context
Step 5: Guard
EXPLAIN · policy · read-only
Where the work happens
Step 6: Rows
compact columnar
04Perks — why it's built this way
The edge
Bounded context
BM25F ranks relations over schema text, declared foreign-key joins are added, and the result is packed into a byte-bounded context — not the whole dump.
Guarded execution
Every batch runs in one pooled, read-only transaction: EXPLAIN plan and cost-ceiling policy first, then execute, on a minimal-privilege role.
Never indexes your rows
Only schema is indexed. Nothing about application rows is ever stored or cached.
Honest benchmark
42 executions over a reviewed 14-task corpus against a live database, with the cases where it loses printed next to the ones where it wins.
05Tech — and what each part does
The stack
- Python 3.11
- Server and retrieval
- MCP
- database_task_context · database_readonly_batch
- PostgreSQL
- Read-only, connection-pooled role
- BM25F
- Ranks relations over schema text
- FastAPI
- Backend for the UI
- Next.js
- Schema explorer UI
- pytest
- 67 tests
06Evidence
The proof
- Warm median latency · lower is better
- TableFox: 1,200msCatalog search + direct SQL: 2,396ms
- Mean tokens per task · lower is better
- TableFox: 879Catalog search + direct SQL: 1,240
Live PostgreSQL, 38 tables, 14 tasks × 3 repeats. Tokens (with the optional context window at 16) varied under 1%; latency moved ±100 ms between runs, so treat it as approximate.
07Known limits — stated plainly
Where it doesn't win
- Cold start is slower: the first task in a new process lands around 2,683 ms against 2,396 ms. It only pulls ahead from the second task on.
- Retrieval is lexical, so meaning that lives only in row values is invisible — that single miss is the 13/14 retrieval score.
- Simple single-table lookups gain the least.