API reference · More
MCP tools
The tools the vectro-mcp server offers an AI assistant, with their arguments and results.
NodeBrowserEdge
vectro-mcp is a Model Context Protocol server over stdio. An assistant loads files from the data folder (--root) into named tables and asks questions of them; Vectro answers on every core, on the same machine. Expressions are Vectro’s small math language, so no code the assistant writes is run. The MCP server is experimental: tools may change. Setup is in MCP server.
Calls and results
The server answers initialize (protocol versions 2025-06-18, 2025-03-26 and 2024-11-05; server name vectro), ping, tools/list and tools/call. A tool’s result comes back twice, as JSON text in content and as structuredContent, and always includes ms, the time the call took. In rows, dates are ISO text and NaN or infinite numbers are null.
A mistake (an unknown table, a bad expression, a file outside the folder) comes back as a result with isError: true and the message as text, so the assistant can read it and fix its call. An unknown tool name is a JSON-RPC error.
load_file
Loads a file from the data folder into a named table, or opens a .vectro dataset on disk. Loading under a name already in use replaces that table.
| Argument | Type | Required | Meaning |
|---|---|---|---|
path |
string | yes | The file, relative to the data folder. |
name |
string | no | The table name for later calls. Default: the file name without its extension, with characters other than letters, digits and _ replaced by _. |
types |
object | no | Column kinds: { column: 'number' or 'category' or 'string' } (string: free text, returned but not filtered). |
Files: .csv, .tsv, .jsonl and .ndjson (one flat object per line), .arrow, .feather and .ipc, and .vectro. Text columns become categories, which can be filtered and grouped. A JSON-lines file whose lines carry an array of numbers (an embedding) also gets a vector index, for search_similar. Files over 2 GB, other than .vectro, are refused.
Result: { table, rows, columns, sample }, where columns is { name: 'number' or 'category' or 'date' or 'text' } and sample the first 5 rows. A JSON-lines file with embeddings adds embedding: { field, dim }; skipped lines add skipped_lines. A dataset adds on_disk: true.
list_tables
No arguments. Result: { tables: [{ table, source, rows, columns }] }, source being the path it was loaded from.
describe_table
| Argument | Type | Required | Meaning |
|---|---|---|---|
table |
string | yes | A loaded table. |
Result: { table, rows, columns }, with per column:
| Kind | Fields |
|---|---|
| number | { kind: 'number', n, min, max, mean, missing }; n counts the values present. |
| category | { kind: 'category', distinct, most_common }; most_common is the 10 most frequent labels, [{ <column>: label, rows }]. |
| date | { kind: 'date', min, max, missing }, min and max as ISO text. |
| text | { kind: 'text' } (free text). |
query
Answers a question about one table without SQL. Every argument but table is optional.
| Argument | Type | Meaning |
|---|---|---|
table |
string | A loaded table. Required. |
filter |
string | Which rows: an expression, e.g. region == 'EU' && price > 100. |
aggregates |
object | { name: 'sum(expr)' }; also mean, min, max, count(), count(condition), countDistinct(expr). |
group_by |
string or string[] |
Aggregate per group of these columns. Needs aggregates. |
sort |
string or string[] |
A column, aggregate name or expression; a leading - for largest first. |
limit |
integer | Rows to return: default 50, at most 500. |
Results, by what was asked:
| Asked | Result |
|---|---|
group_by and aggregates |
{ groups, returned, rows }: groups is the number of groups; rows are sorted by sort if given, else by key. |
aggregates only |
{ rows: [totals] }: one row. |
| neither | { matching_rows, returned, rows }: the matching rows, sorted by sort if given. |
sql
Runs one SQL SELECT over the loaded tables, by their names. The SQL of sql().
| Argument | Type | Required | Meaning |
|---|---|---|---|
query |
string | yes | The statement. |
Result: { rows_in_answer, returned, rows }: at most 500 rows come back, and rows_in_answer says how many the query has.
search_similar
For tables loaded from JSON lines with an embedding field: the rows whose embeddings are most similar (cosine) to a row’s or to a given vector.
| Argument | Type | Required | Meaning |
|---|---|---|---|
table |
string | yes | A table with embeddings. |
like |
object | one of like or vector |
The row to compare with, found by a column value: { column, value }. |
vector |
number[] |
one of like or vector |
An embedding of the stored length. |
k |
integer | no | Rows to return: default 10, at most 500. |
filter |
string | no | Which rows may be returned, e.g. year >= 2020. |
Result: { returned, rows }, each row with the table’s columns and score, best first. A row found through like is among the results itself, unless the filter leaves it out.
add_column
Adds a computed column to a table in memory (not to a dataset; use the expression in query or sql instead).
| Argument | Type | Required | Meaning |
|---|---|---|---|
table |
string | yes | A loaded table. |
name |
string | yes | The new column. |
expression |
string | yes | E.g. price * qty * (1 - discount). |
Result: { table, columns, sample }, sample being the first 3 rows.
drop_table
| Argument | Type | Required | Meaning |
|---|---|---|---|
table |
string | yes | The table to unload. |
Frees the table’s memory (and its added columns and vector index). Result: { dropped }.