polyglot

Polyglot是一个统一接口,覆盖9个类别的18种数据库,可作为Python/Java库或MCP服务器供LLM使用,并内置安全防护措施。

文档

Polyglot

One uniform interface to many databases — usable as a library and as a Model Context Protocol (MCP) server for LLMs, in both Python and Java.

License Python Java

Polyglot gives you a single, consistent set of operations — list_tables, run_query, explain_query, execute, copy_data, and more — that behave the same across relational, document, key-value, wide-column, object, graph, vector, time-series, search, and warehouse engines. One core library backs both the MCP tools and the importable API, so they never drift.

An independent, community-driven open-source project, released under the Apache 2.0 license.

The problem

Every database speaks its own language. The moment an app — or an LLM agent — needs more than one, you're on the hook for a different driver, query language, auth scheme, result shape, and safety story for each one. That cost multiplies by every database you touch, and again for every language you write in and every LLM tool you expose.

Without Polyglot — every engine is its own bespoke integration:

flowchart LR
    App["Your app / LLM agent"]
    App -->|"psycopg · SQL"| PG[(PostgreSQL)]
    App -->|"pymongo · BSON filters"| MG[(MongoDB)]
    App -->|"redis-py · commands"| RD[(Redis)]
    App -->|"boto3 · S3 API"| S3[(S3)]
    App -->|"bolt · Cypher"| NEO[(Neo4j)]
    App -->|"REST · vector search"| QD[(Qdrant)]
    App -->|"…a new SDK each time"| ETC[(…9 more)]

Every arrow is separate code to build, secure, and maintain — no shared caps on result size, no consistent read-only/destructive rules, no uniform output.

With Polyglot — one uniform interface (and one set of guardrails) in front of them all:

flowchart LR
    App["Your app / LLM agent"] ==>|"one API · 12 MCP tools"| P{{Polyglot}}
    P --> PG[(PostgreSQL)]
    P --> MG[(MongoDB)]
    P --> RD[(Redis)]
    P --> S3[(S3)]
    P --> NEO[(Neo4j)]
    P --> QD[(Qdrant)]
    P --> ETC[(…14 engines,<br/>9 categories)]

Highlights

  • One interface, 14 engines tested live across 9 categories (18 engines implemented in all; the warehouse category and a few managed/licensed engines are implemented but need cloud credentials to test). list_tables, run_query, explain_query, execute, copy_data, … behave the same everywhere.
  • Library and MCP server from one core. Call it from code, or let an LLM drive it — identical behavior, because both wrap the same DatabaseCore.
  • Safe by default. Read-only unless a connection opts in; destructive ops need explicit confirmation; results are capped; PII columns are redacted; credentials never reach the model.
  • Two languages, one contract. Python and Java expose byte-identical MCP tools — a Java gateway is a drop-in replacement for the Python one.
# the same call, whatever the engine underneath
db.run_query("warehouse", "SELECT ...")          # a SQL warehouse
db.run_query("cache", "GET session:42")          # Redis
db.copy_data("shop", "orders", "orders_archive") # any engine, same signature

"Which customers churned last month?" — an LLM connected to Polyglot answers that against Postgres, Mongo, or BigQuery without you writing per-database glue.

Get started

I want to…Go to
Use it from Python (library or MCP server)python/README.md
Use it from Java (library or MCP server)java/README.md
Test it (incl. a natural-language script)TESTING.md
ContributeCONTRIBUTING.md

When should I use this?

Pick based on who is driving:

  • The library (polyglot-core) — when code is the consumer: ETL and migrations, a data-access layer spanning several stores, admin/reporting endpoints, batch jobs. Typed, programmatic, no LLM involved.
  • The MCP server (polyglot-mcp) — when an LLM or agent is the consumer: conversational data access in Claude Desktop/Code, Cursor, etc.; agentic workflows that inspect, query, and move data; governed access for non-engineers.

Both share the same DatabaseCore, so behavior and guardrails are identical whether a function call or a language model triggers them.

Architecture

flowchart TD
    subgraph Consumers
        A[LLM via MCP client]
        B[Application code]
    end
    A -->|MCP tools over stdio/HTTP| G[polyglot-mcp<br/>MCP gateway]
    B -->|import| C
    G --> C[polyglot-core<br/>DatabaseCore + ConnectionRegistry]
    C --> S[Security guardrails<br/>read-only · destructive-confirm · row caps · redaction]
    C --> D{DatabaseAdapter<br/>one per engine}
    D --> E1[(Relational)]
    D --> E2[(Document)]
    D --> E3[(Key-value)]
    D --> E4[(Wide-column)]
    D --> E5[(Object)]
    D --> E6[(Graph / Vector)]
    D --> E7[(Time-series)]
    D --> E8[(Search)]
    D --> E9[(Warehouse)]

The gateway is an in-process router: one MCP server that loads adapters as libraries and dispatches each call to the right backend by a connection name. The Python and Java gateways expose the same tool contract (identical names, arguments, and result shapes) and are drop-in replacements for each other.

Supported databases

Universal operations work on every engine. Legend — ✅ tested live in the Docker stack · ⚠️ implemented, not yet tested (needs a licensed q process or cloud credentials) · — not yet implemented in that language (roadmap).

CategoryEnginesPythonJava
RelationalPostgreSQL, MySQL/MariaDB, SQLite
Relational (managed)GCP Cloud SQL⚠️⚠️
DocumentMongoDB
DocumentCouchDB
Key-valueRedis
Key-valueAmazon DynamoDB
Wide-columnCassandra / ScyllaDB
Object storeS3 / MinIO
GraphNeo4j
VectorQdrant
Time-seriesTimescaleDB, InfluxDB
Time-serieskdb+ / q⚠️
SearchOpenSearch / Elasticsearch
WarehouseBigQuery, Snowflake⚠️

Java has full parity on every Docker-testable engine — 14 engines, verified by the Java test suite. kdb+ and the cloud warehouses are the Java roadmap.

Real AWS S3 needs no separate adapter — the tested S3/MinIO adapter talks to AWS directly; just omit endpoint_url and supply AWS credentials.

Security guardrails

  • Read-only by default. Writes require allow_write on the connection.
  • Destructive operations need extra care. DELETE / DROP / TRUNCATE / UPDATE-without-WHERE (and each engine's equivalents), plus copy_data with mode='replace' (which clears the target first), require both allow_delete and an explicit confirm_destructive=true.
  • Reads stay reads. run_query accepts only reads; the SQL adapters run them inside a rolled-back, server-side read-only transaction, so a data-modifying CTE or EXPLAIN ANALYZE DELETE that slips past classification still can't write.
  • Result caps. Reads are clamped to the connection's max_rows.
  • PII redaction. redact_columns are masked in read output.
  • No credentials to the model. Connections are pre-registered; the LLM only references them by name.

Guardrails live in the core and apply identically to the library and the MCP server, in both languages.

Repository structure

polyglot/                       (monorepo)
├── python/                     Python implementation → PyPI
│   ├── polyglot-core/          the library
│   ├── polyglot-mcp/           the MCP server
│   └── tests/
├── java/                       Java implementation → Maven Central (dev.polyglot)
│   ├── polyglot-core/          the library
│   └── polyglot-mcp/           the MCP server
├── examples/                   SHARED: docker-compose stack, seed data, connection configs
├── README.md                   (this file)
├── ANALYSIS.md · TESTING.md · PUBLISHING.md
├── CONTRIBUTING.md · CODE_OF_CONDUCT.md · LICENSE
└── .mcp.json                   attaches the server to Claude Code sessions

The package names are identical across languages: PyPI polyglot-core / polyglot-mcp, and Maven dev.polyglot:polyglot-core / dev.polyglot:polyglot-mcp (the reverse-DNS groupId provides uniqueness).

Absolute paths in configs: .mcp.json, examples/claude_desktop_config.json, and the sqlite_notes entry in examples/connections.json hold machine-specific absolute paths (the interpreter, POLYGLOT_CONFIG, and the SQLite file). If you clone to a different location, update those paths and recreate the .venv.

License

Apache License 2.0 — see LICENSE. Copyright 2026 The Polyglot Authors.