Infino MCP server
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| INFINO_MCP_URI | No | Data to serve: a local path or a bucket URI. Defaults to ~/.infino/mcp (persistent). | ~/.infino/mcp |
| INFINO_MCP_VALIDATE | No | When set (e.g., '1', 'true', 'yes'), validates storage credentials at startup. | off |
| INFINO_MCP_EMBED_MODEL | No | Embedding model name. Default is 'Xenova/all-MiniLM-L6-v2' for local, 'text-embedding-3-small' for openai. | Xenova/all-MiniLM-L6-v2 (local) / text-embedding-3-small (openai) |
| INFINO_MCP_EMBED_API_KEY | No | API key for the 'openai' provider. Optional for unauthenticated endpoints. | |
| INFINO_MCP_ENABLE_WRITES | No | When set (e.g., '1', 'true', 'yes'), enables write tools and DDL/DML. Omit for read-only. | off |
| INFINO_MCP_EMBED_BASE_URL | No | Base URL of the OpenAI-compatible embeddings API (e.g., https://api.openai.com/v1). Required if provider is 'openai'. | |
| INFINO_MCP_EMBED_PROVIDER | No | Embedding provider: 'local' (default, no key) or 'openai'. Inferred as 'openai' when INFINO_MCP_EMBED_BASE_URL is set. | local |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
Infino is an embedded retrieval engine for data on object storage: full-text (BM25), vector, hybrid, and SQL search over one copy of the data, in-process, with no separate server or managed service. Tables are stored as valid Parquet; DuckDB or pyarrow can read the same files. These tools retrieve from a connected catalog of tables.
Pick a tool by the question shape:
infino_keyword_search — literal terms, identifiers, error codes, names (ranked BM25).
infino_semantic_search — meaning or paraphrase when the exact wording is unknown; its optional 'filter' restricts the ranking to rows matching a keyword predicate first.
infino_hybrid_search — a query carrying both specific terms and an intent (fuses keyword + semantic in one pass).
infino_sql — counts, joins, aggregates, and filtering by exact column value (structural, not relevance).
infino_token_match / infino_exact_match — unranked keyword / exact-equality filters.
infino_list_tables / infino_describe_table — discover the tables and their columns before searching.
Writing data, in order: infino_create_database if a hosted database answers 404; infino_create_table with a utf8 key column, large_utf8 text columns, and vector: true for semantic search (the server sizes the vector column to its embedder); infino_add_documents with tens of rows per call, always including the key; rows without a vector are embedded from their text. To replace rows, infino_delete_documents by key predicate then add again; before any delete, check the predicate with infino_count or infino_sql. Every write is one commit and is durable when the tool returns. For a whole corpus use the infino CLI (infino ingest) or an SDK, not this server. There is no server-side write gate: the API key's capabilities decide what a hosted connection may do, and you are responsible for what you change.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| infino_list_tablesA | List the tables in the connected catalog. Call this first to discover what is available to search or query. |
| infino_describe_tableA | Return a table's column names and types — call before searching so you know which column to target and what fields each result row carries. |
| infino_create_databaseA | Provision the database named in the connection. On Infino Cloud this registers the database; on a local path or bucket the catalog root is the database, so this is a no-op success. Idempotent: an existing database is reported as created: false. Call it when a hosted connection answers 404. |
| infino_create_tableA | Create a table from a {column: type} descriptor. Full-text (BM25) indexes go on the columns named in 'fts' (default: every large_utf8 column; the index requires that type). With vector: true the server adds an 'embedding' column sized to its embedder and a cosine vector index on it, so semantic and hybrid search work and rows added without a vector are embedded from their text. Every column is required in every row you add, so declare only columns you will always fill. Give every table a stable key column of type utf8 so rows can be replaced or removed later by predicate (e.g. key = 'doc-1'); keep utf8 for ids and short labels and large_utf8 for the text to search, so the searches infer the right column. |
| infino_drop_tableA | Drop a table from the catalog and, by default, delete its storage objects too. Pass purge: false to only unregister the table and leave the bytes in place. Irreversible. |
| infino_semantic_searchA | Use when searching for a concept by meaning and the exact wording is unknown — this retrieves paraphrases and synonyms, not just literal matches. Embeds the query with a local model (no API key) and ranks a table's embedding column by vector similarity. Each hit carries a score that is a DISTANCE (lower is closer) plus the columns you project ('columns'; the full text column by default). Optional 'filter' restricts the ranking to rows whose keyword column matches a predicate first (a pushdown pre-filter, e.g. semantic search only within rows tagged 'billing'). For exact terms use infino_keyword_search; when the query has both literal terms and an intent use infino_hybrid_search. |
| infino_keyword_searchA | Use when the query is literal terms — identifiers, error codes, product names, exact phrases — and you want results ranked by relevance. BM25 full-text search over a text column: ranks rows by how well the query's tokens (and their stems) match, each with a relevance score (higher is better) plus the columns you project ('columns'; the full text column by default). Matches exact tokens, not synonyms or paraphrases. Prefer this over SQL LIKE for known literal terms. For meaning-based search use infino_semantic_search; for both at once use infino_hybrid_search. |
| infino_hybrid_searchA | Use when a query carries both specific terms and an intent — you want exact-term precision without giving up paraphrase recall. Fuses BM25 over a text column with vector similarity over the embedding column in a single ranking pass, so rows matching the literal terms AND the meaning rank highest; the score is the fused rank (higher is better) plus the columns you project ('columns'; the full text column by default). Embeds the query with a local model (no API key). Sits between infino_keyword_search (literal only) and infino_semantic_search (meaning only). |
| infino_token_matchA | Use when you need the SET of rows containing a keyword, not a ranked order — a fast unranked keyword filter. Returns rows whose text column contains the token(s), matching indexed tokens and their stems. For ranked results use infino_keyword_search; for analytical filtering across columns use infino_sql. |
| infino_exact_matchA | Use to fetch rows whose column exactly equals a value — a tag, status, or id string. Unranked exact-equality filter over an indexed column. For ranked text relevance use infino_keyword_search; for multi-column analytical filtering use infino_sql. |
| infino_countA | Use when you only need HOW MANY rows match a keyword query, not the rows themselves — a fast tally over a text column, without fetching or ranking. Cheaper than infino_keyword_search when a number is all you need (e.g. 'how many docs mention X'). For the matching rows use infino_keyword_search or infino_token_match. |
| infino_sqlA | Use for structural or analytical questions — counts, GROUP BY, joins, aggregates, filtering by column value — returning result rows. The engine's search functions are callable as table-valued relations, so a single query can rank AND aggregate: bm25_search('table','text_col','terms', k) — also bm25_search_prefix / token_match / exact_match — need no embedding. vector_search('table','vec_col', {{q}}, k) and hybrid_search('table','text_col','terms','vec_col', {{q}}, k) need a query vector: put a {{name}} placeholder where the vector goes and pass embed:{"name":"query text"} — the server embeds the text and substitutes the vector in. Example: SELECT path, SUM(end_line - start_line + 1) AS lines FROM bm25_search('docs','body','error timeout', 300) GROUP BY path ORDER BY lines DESC. Any single statement is allowed, DDL/DML included. |
| infino_add_documentsA | Append documents (rows, as JSON objects keyed by column name) to a table; one call is one commit. If the table has a vector index and a document omits the vector, the server embeds its text column (a local model, no API key). Send tens of rows per call; for a whole corpus use the infino CLI or an SDK. |
| infino_update_documentsA | Replace the rows matching a SQL predicate with new documents, 1:1; the number of matched rows must equal the number of replacement documents. As with add, a row that omits its vector has it embedded from the text column (local model, no API key). Requires durable storage (not memory://). |
| infino_delete_documentsA | Delete the rows matching a SQL predicate, e.g. "status = 'spam'". Returns how many rows matched and were removed. Check the predicate first with infino_count or infino_sql. Requires durable storage (not memory://). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 15 tools
The search family is well-differentiated by explicit cross-references: keyword (ranked literal), semantic (meaning), hybrid (both), token_match (unranked set), exact_match (equality filter), count (tally only), sql (analytics). There is some residual overlap—token_match/exact_match/keyword_search all return rows from text matching, and count duplicates what keyword_search plus sql can do—but the descriptions clearly steer selection.
All 15 tools share a consistent infino_ snake_case prefix, which keeps the set coherent. Within that, there is a minor mix of noun_verb (keyword_search, token_match) and verb_noun (list_tables, add_documents, create_table) patterns plus bare nouns (count, sql), but each is readable and internally consistent.
15 tools is well within the ideal 3-15 band and each earns its place: a complete table/database lifecycle plus a tiered search surface. Nothing is redundant enough to feel bloated, and nothing trivial is included.
The surface covers table/database lifecycle (create/list/describe/drop_table, create_database), document CRUD (add/update/delete, with reads via the search tools), and analytical SQL, which is strong. Minor gaps exist—no drop_database or explicit get-by-id—but agents can work around these via sql or exact_match.