Content
# Paradox MCP Server
Talk to your old Paradox `.db` database files using plain English (or SQL).
## What is this?
If you have old **Paradox database files** (`.db`) from the 90s/2000s and want to:
- Query them with **SQL** (JOINs, GROUP BY, etc.)
- Let **AI assistants** (Claude, Cursor, etc.) read and modify them
- Export data to modern formats
...this tool bridges the gap.
## What you need
| Item | Required? | Notes |
|------|-----------|-------|
| Paradox `.db` files | **Yes** | Your database files |
| Linux or macOS | **Yes** | Windows: use Docker or WSL |
| Docker | Recommended | Easiest setup |
| `pxlib` | Linux only | Auto-installed in Docker |
## Quick Start (5 minutes)
### Option 1: Docker (Easiest)
```bash
# 1. Put your .db files in a folder, e.g. ~/my-data
# 2. Build and run
docker build -t paradox-mcp .
docker run -i --rm -v ~/my-data:/data paradox-mcp --location /data --permit-editing
```
### Option 2: Local (macOS/Linux)
```bash
# 1. Clone and build
cd paradox-mcp
cargo build --release
# 2. Point it at your data folder
mkdir -p ./data
cp ~/my-data/*.db ./data/
./target/release/paradox-mcp --location ./data --permit-editing
```
The server runs on **stdin/stdout** (no web server needed).
## Test it works
Once running, paste this JSON to test:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_server_status"}}
```
Expected response:
```json
{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"Paradox Server Configuration:\n- Location: /data\n- Permit Editing: true\n- Version: 0.1.0"}]}}
```
If you see that, the server is alive!
## What can it do?
### 1. Direct Paradox queries (no setup)
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_tables"}}
```
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"read_table_data","arguments":{"table_name":"customers","limit":5}}}
```
### 2. Advanced querying (SQL-like, still on Paradox files)
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"query_table","arguments":{"table_name":"customers","where":{"Age":{"op":">","value":18}},"order_by":{"field":"Name","direction":"asc"},"limit":10}}}
```
Operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `like`, `in`
### 3. Full SQL via SQLite bridge
**Import** a Paradox table into SQLite:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"import_to_sqlite","arguments":{"table_name":"customers"}}}
```
**Query** with real SQL:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"sql_query","arguments":{"db_key":"/data.customers","sql":"SELECT * FROM customers WHERE Age > 18 ORDER BY Name LIMIT 10"}}}
```
**Modify** with SQL:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"sql_execute","arguments":{"db_key":"/data.customers","sql":"UPDATE customers SET Status='Active' WHERE LastLogin > '2024-01-01'"}}}
```
**Export back** to Paradox:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"export_from_sqlite","arguments":{"db_key":"/data.customers","sqlite_table":"customers"}}}
```
### 4. Write operations (needs `--permit-editing`)
Create table:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_table","arguments":{"table_name":"new_table","fields":[{"name":"ID","type":"LONG"},{"name":"Name","type":"ALPHA","length":50}]}}}
```
Insert record:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"insert_record","arguments":{"table_name":"new_table","record":{"ID":1,"Name":"Alice"}}}}
```
Update record:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"update_record","arguments":{"table_name":"new_table","index":0,"record":{"Name":"Bob"}}}}
```
Delete record:
```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"delete_record","arguments":{"table_name":"new_table","index":0}}}
```
## All 17 Tools
| # | Tool | What it does | Needs `--permit-editing`? |
|---|------|-------------|---------------------------|
| 1 | `get_server_status` | Show server config | No |
| 2 | `list_tables` | List all `.db` files | No |
| 3 | `read_table_schema` | Show columns and types | No |
| 4 | `read_table_data` | Read records as JSON | No |
| 5 | `search_table` | Simple search by field | No |
| 6 | `query_table` | SQL-like WHERE, ORDER BY, LIMIT, aggregation | No |
| 7 | `create_table` | Make a new `.db` file | **Yes** |
| 8 | `insert_record` | Add a row | **Yes** |
| 9 | `update_record` | Change a row by index | **Yes** |
| 10 | `delete_record` | Remove a row by index | **Yes** |
| 11 | `import_to_sqlite` | Copy Paradox → SQLite | No |
| 12 | `sql_query` | Run `SELECT` on SQLite | No |
| 13 | `sql_execute` | Run `INSERT/UPDATE/DELETE` on SQLite | **Yes** |
| 14 | `export_from_sqlite` | Copy SQLite → Paradox | **Yes** |
| 15 | `close_sqlite_db` | Free memory for one DB | No |
| 16 | `clear_sqlite_cache` | Free memory for all DBs | No |
| 17 | `list_sqlite_dbs` | Show loaded SQLite DBs | No |
## Troubleshooting
### "Failed to create pxdoc" or "Table not found"
You're on macOS or Windows without `pxlib` installed. This is **expected** — the server compiles a "mock" version that lets you test the tool interface, but can't actually read Paradox files.
**Fix:** Use Docker (Linux with pxlib), or install `pxlib-dev` on Linux.
### "Editing is not permitted"
You didn't pass `--permit-editing`. Restart with that flag for write operations.
### SQLite database not found
The `db_key` is the path shown by `import_to_sqlite`. Usually: `/path/to/data.foldername`.
Use `list_sqlite_dbs` to see all loaded databases.
### Docker build is slow
First build compiles Rust from scratch (~5-10 min). Subsequent builds use cache.
## Development
```bash
# Quick check (fast)
cargo check
# Full build
cargo build --release
# Run tests (uses mock, works everywhere)
make test-local
# Run server locally
make run-local
```
## Type Mapping
| Paradox | SQLite | Example value |
|---------|--------|---------------|
| ALPHA | TEXT | `"Hello"` |
| SHORT | INTEGER | `42` |
| LONG | INTEGER | `123456` |
| NUMBER | REAL | `3.14` |
| CURRENCY | REAL | `19.99` |
| LOGICAL | INTEGER | `1` (true) or `0` (false) |
| DATE | TEXT | `"2024-01-15"` |
| BLOB | BLOB | Binary data |
## For AI Assistant Developers
This is an **MCP server** — it speaks JSON-RPC over stdio. Any MCP-compatible client (Claude Desktop, Cursor, custom scripts) can call these tools.
Example Python client:
```python
import json, subprocess
proc = subprocess.Popen(
["./target/release/paradox-mcp", "--location", "./data", "--permit-editing"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True
)
def call(name, args=None):
req = {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":name,"arguments":args or {}}}
proc.stdin.write(json.dumps(req) + "\n")
proc.stdin.flush()
return json.loads(proc.stdout.readline())
# List tables
print(call("list_tables"))
```
## Architecture (For Contributors)
```
MCP Client (Claude/Cursor/Script)
↓ JSON-RPC over stdio
paradox-mcp (Rust)
├── Core: Read/write Paradox files via pxlib FFI
├── Query: SQL-like filtering/sorting/aggregation
├── SQLite Bridge: Import → Query → Export back
└── Tools: 17 MCP tool definitions
```
### Module Layout
```
src/
├── main.rs, args.rs, mcp.rs, handlers.rs # Server plumbing
├── pxlib.rs (+ mock.rs) # FFI bindings
├── core/ # Paradox engine
│ ├── paradox.rs # Reader
│ ├── writer/ # Writer (create/insert/update/delete)
│ ├── query/ # Query engine + aggregation
│ └── schema.rs # Type mapping
├── sqlite/ # SQLite bridge
│ ├── bridge.rs # Import/export
│ ├── query.rs # SQL runner
│ └── sync.rs # Write-back to Paradox
└── tools/ # MCP tool registry
├── registry.rs
└── responses.rs
```
## License
MIT
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.