Tutorial 1 — AI / semantic retrieval via MCP¶
The runnable Python version is
examples/tutorials/01_ai_retrieval_mcp.ipynb. This page is the SQL / connector form for Spark, Trino, dbt, Flight SQL, MCP, and Rust.
Build a document corpus with embeddings, index it with HNSW, and run the six-step agent workflow: discover → schema → SQL → vector → graph → combine.
1. Create the table and index (SQL)¶
CREATE TABLE docs (id BIGINT, title VARCHAR, embedding FLOAT[4]);
INSERT INTO docs VALUES
(1, 'Iceberg overlays', [1.0, 0.0, 0.0, 0.0]),
(2, 'Vector search', [0.9, 0.1, 0.0, 0.0]),
(3, 'Graph on the lakehouse',[0.0, 1.0, 0.0, 0.0]);
-- HNSW overlay (rebuildable; the Parquet data is never rewritten).
-- The index *type* is named in the USING clause; a bare
-- `ALTER TABLE docs ADD INDEX (embedding)` would create a scalar Bitmap.
CREATE INDEX idx_emb ON docs (embedding) USING hnsw;
2. Vector retrieval (SQL)¶
SELECT id, title
FROM docs
ORDER BY vector_distance(embedding, [1.0, 0.0, 0.0, 0.0]) ASC
LIMIT 2;
3. The agent workflow via MCP¶
Register it with your MCP client (Claude Desktop, Cursor, Antigravity) using uvx (recommended) or from source:
Option A: Run via uvx (No build required)¶
{
"mcpServers": {
"benostreamdb": {
"command": "uvx",
"args": ["benostreamdb-mcp"],
"env": { "BSDB_WAREHOUSE": "/tmp/bsdb_warehouse", "BSDB_GPU_DEVICE": "auto" }
}
}
}
Option B: Build from Source¶
cargo build --release --manifest-path contrib/benostreamdb-mcp/Cargo.toml
{
"mcpServers": {
"benostreamdb": {
"command": "/path/to/benostreamdb-mcp",
"env": { "BSDB_WAREHOUSE": "/tmp/bsdb_warehouse", "BSDB_GPU_DEVICE": "auto" }
}
}
}
The agent then calls these tools:
Step |
Tool |
Arguments |
|---|---|---|
1. discover |
|
|
2. schema |
|
|
3. SQL |
|
|
4. vector |
|
|
5. graph |
|
|
6. combine |
|
join the above |
live tail |
|
|
The MCP server is read-all / write-scratch-only: it can query any schema but
only writes to the local scratch schema.
4. The same workflow from each connector¶
Spark (pass-through reader):
spark.read.format("benostream")
.option("path", "s3://my-lakehouse/docs")
.option("query", "SELECT id, title FROM t ORDER BY vector_distance(embedding, array(1.0,0.0,0.0,0.0)) LIMIT 2")
.load()
Trino:
SELECT id, title FROM benostreamdb.default.docs
ORDER BY vector_distance(embedding, ARRAY[1.0, 0.0, 0.0, 0.0]) LIMIT 2;
dbt (a model):
{{ config(materialized='table') }}
SELECT id, title FROM {{ ref('docs') }}
ORDER BY vector_distance(embedding, [1.0, 0.0, 0.0, 0.0]) LIMIT 2
Flight SQL (ADBC / pyarrow.flight): send the same SQL as a
CommandStatementQuery.
Rust (core API):
let table = Table::new_async(uri).await?;
let hits = table.vector_search("embedding", &[1.0, 0.0, 0.0, 0.0], 2).await?;
GPU¶
Pin the device with BSDB_GPU_DEVICE (Flight/MCP), spark.benostream.gpu.device
(Spark), benostream.gpu-device (Trino), the dbt profile gpu_device, or
benostreamdb.set_gpu_device(...) (Python).