The SQL side is deliberately narrow — schema reads and read-only queries — while the vector side is where the writes are: create a store, insert documents, search it. That makes it a reasonable single dependency for a retrieval workflow whose source data already sits in MariaDB. On the read-only flag, take the project's own advice: it is a whitelist of allowed statements, so the guarantee you actually want comes from connecting as a database user that has no write privileges.
MariaDB's own server, covering both halves of the database: standard SQL against tables, and vector stores for embedding-based search, created and queried through the same tool set.
- Every accessible database, and the tables in one you name
- A table's schema, or the same schema with its foreign-key relations
- Read-only SQL — SELECT, SHOW and DESCRIBE — with parameters passed separately from the statement
- A database created if it does not exist yet
- Vector stores created, listed and deleted, each a table of document, embedding and JSON metadata
- Documents inserted in batches with optional metadata, and similarity search across a store with the number of neighbours you ask for
- Sensitive SHOW commands blocked by default — PROCESSLIST, GRANTS, VARIABLES, replication status — independently of the read-only switch
Python 3.11, uv, and a reachable MariaDB. Connection settings come from the environment or a .env file: DB_HOST, DB_USER and DB_PASSWORD are required, with DB_PORT, DB_NAME and a full set of DB_SSL options for TLS and client certificates. MCP_READ_ONLY is on by default. The vector tools appear only when EMBEDDING_PROVIDER is set to openai, gemini or huggingface, each with its own key or model name. Over SSE or HTTP the server ships no authentication of its own — that is yours to add before anything outside localhost can reach it. MIT.
Build from source — clone the repository and build it, then point your client at the binary
