MCP Tools Reference
The laurus MCP server exposes the following tools.
connect
Connect to a running laurus-server gRPC endpoint. Call this before using other
tools if the server was started without the --endpoint flag, or to switch to
a different laurus-server at runtime.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
endpoint | string | Yes | gRPC endpoint URL (e.g. http://localhost:50051) |
Example
Tool: connect
endpoint: "http://localhost:50051"
Result: Connected to laurus-server at http://localhost:50051.
create_index
Create a new search index with the provided schema.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
schema_json | string | Yes | Schema definition as a JSON string |
Schema JSON format
FieldOption uses serde’s externally-tagged representation where the variant name is the key:
{
"dynamic_field_policy": "Dynamic",
"fields": {
"title": { "Text": { "indexed": true, "stored": true } },
"body": { "Text": {} },
"score": { "Float": {} },
"count": { "Integer": {} },
"active": { "Boolean": {} },
"created": { "DateTime": {} },
"embedding": { "Hnsw": { "dimension": 384 } }
}
}
The optional dynamic_field_policy key controls how fields that appear in
ingested documents but are absent from the schema are handled. Accepted
values: "Strict", "Dynamic" (default), "Ignore". Warning: under
"Dynamic", integer fields silently truncate incoming float values
(3.14 → 3); use "Strict" to reject such mismatches. See
Schema & Fields for the
full behaviour matrix.
Example
Tool: create_index
schema_json: {"fields": {"title": {"Text": {}}, "body": {"Text": {}}}}
Result: Index created successfully at /path/to/index.
A schema with a Geo3d field for 3D ECEF positions:
{
"fields": {
"title": { "Text": { "indexed": true, "stored": true } },
"position": { "Geo3d": { "indexed": true, "stored": true } }
}
}
See 3D Geographic Search (ECEF) for the coordinate system; Geo3d is queryable via the geo3d_distance / geo3d_bbox / geo3d_nearest DSL forms (see the search tool below).
add_field
Add a new field to the index.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The field name |
field_option_json | string | Yes | Field configuration as JSON |
Example
{
"name": "category",
"field_option_json": "{\"Text\": {\"indexed\": true, \"stored\": true}}"
}
Result: Field 'category' added successfully.
delete_field
Remove a field from the index schema. Existing indexed data remains in storage but becomes inaccessible. Per-field analyzers and embedders are unregistered.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The name of the field to remove |
Example
{
"name": "category"
}
Result: Field 'category' deleted successfully.
get_stats
Get statistics for the current search index, including document count and vector field information.
Parameters
None.
Result
{
"document_count": 42,
"vector_fields": {
"embedding": {
"vector_count": 42,
"dimension": 384
}
}
}
vector_fields is a map keyed by field name; each entry reports the number of indexed vectors and the field’s configured dimension.
get_schema
Get the current index schema, including all field definitions and their configurations.
Parameters
None.
Result
{
"fields": {
"title": { "Text": { "indexed": true, "stored": true } },
"body": { "Text": {} },
"embedding": { "Hnsw": { "dimension": 384 } }
},
"default_fields": ["title", "body"]
}
put_document
Put (upsert) a document into the index. If a document with the same ID already exists, all its chunks are deleted before the new document is indexed. Call commit after adding documents.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | External document identifier |
document | object | Yes | Document fields as a JSON object |
Example
Tool: put_document
id: "doc-1"
document: {"title": "Hello World", "body": "This is a test document."}
Result: Document 'doc-1' put (upserted). Call commit to persist changes.
Example with a Geo3d value:
Tool: put_document
id: "drone-1"
document: {"title": "Drone over Tokyo", "position": {"x": -3955182.0, "y": 3350553.0, "z": 3700276.0}}
The MCP server accepts a 3D ECEF point as a JSON object with x, y, z keys (meters). This is distinct from the HTTP gateway, which currently does not infer Geo3d from JSON — the MCP path is fully supported for both writes and reads.
add_document
Add a document as a new chunk to the index. Unlike put_document, this appends without deleting existing documents with the same ID. Useful for splitting large documents into chunks. Call commit after adding documents.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | External document identifier |
document | object | Yes | Document fields as a JSON object |
Example
Tool: add_document
id: "doc-1"
document: {"title": "Hello World - Part 2", "body": "This is a continuation."}
Result: Document 'doc-1' added as chunk. Call commit to persist changes.
put_documents
Put (upsert) many documents in one call. Entries are applied sequentially, in input order, with one WAL fsync for the whole batch — much faster than calling put_document per document. Duplicate IDs within one batch dedup (the last occurrence wins). Call commit afterwards.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
documents | array | Yes | Array of {"id": "...", "document": {...}} entries; each document has the same shape as put_document’s |
Example
Tool: put_documents
documents: [
{"id": "doc-1", "document": {"title": "Hello"}},
{"id": "doc-2", "document": {"title": "World"}}
]
Result: 2 documents put (upserted). Call commit to persist changes.
A failure aborts at the offending entry without rolling back the already-applied prefix, so retrying the batch (or its suffix) is idempotent.
add_documents
Add many documents as new chunks in one call. Unlike put_documents, existing documents are never deleted, so repeating an ID adds multiple chunks of the same logical document. One WAL fsync covers the whole batch. Call commit afterwards.
Parameters
Same as put_documents.
Example
Tool: add_documents
documents: [
{"id": "doc-1", "document": {"title": "Part 1"}},
{"id": "doc-1", "document": {"title": "Part 2"}}
]
Result: 2 documents added as chunks. Call commit to persist changes.
get_documents
Retrieve all stored documents (including chunks) by external ID.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | External document identifier |
Result
{
"id": "doc-1",
"documents": [
{ "title": "Hello World", "body": "This is a test document." }
]
}
delete_documents
Delete all documents and chunks sharing the given external ID from the index. Call commit after deletion.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | External document identifier |
Result: Documents 'doc-1' deleted. Call commit to persist changes.
commit
Commit pending changes to disk. Must be called after put_document, add_document, or delete_documents to make changes searchable and durable.
Parameters
None.
Result: Changes committed successfully.
search
Search documents using the laurus unified query DSL. Supports lexical search, vector search, and hybrid search in a single query string.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query in laurus unified query DSL |
limit | integer | No | Maximum results (default: 10) |
offset | integer | No | Results to skip for pagination (default: 0) |
fusion | string | No | Fusion algorithm as JSON (for hybrid search) |
field_boosts | string | No | Per-field boost factors as JSON |
Query DSL examples
Lexical search
| Query | Description |
|---|---|
hello | Term search across default fields |
title:hello | Field-scoped term search |
title:hello AND body:world | Boolean AND |
"exact phrase" | Phrase search |
roam~2 | Fuzzy search (edit distance 2) |
count:[1 TO 10] | Range search |
title:helo~1 | Fuzzy field search |
3D geographic search
| Query | Description |
|---|---|
position:geo3d_distance(x, y, z, distance_m) | Sphere with center (x, y, z) and maximum distance in meters |
position:geo3d_bbox(min_x, min_y, min_z, max_x, max_y, max_z) | 3D axis-aligned bounding box |
position:geo3d_nearest(x, y, z, k) | k nearest neighbors to (x, y, z) |
position is the field name; substitute the actual Geo3d-typed field declared in your schema. See Query DSL → 3D Geographic Queries for the full DSL syntax.
Vector search
| Query | Description |
|---|---|
content:"cute kitten" | Vector search on a field (field must be a vector field in schema) |
content:python | Vector search with unquoted text |
content:"cute kitten"^0.8 | Vector search with weight/boost |
a:"cats" b:"dogs"^0.5 | Multiple vector queries |
Hybrid search
| Query | Description |
|---|---|
title:hello content:"cute kitten" | Lexical + vector (OR/union — results from either) |
title:hello +content:"cute kitten" | Lexical + vector (AND/intersection — only results in both) |
+title:hello +content:"cute kitten" | Both required (AND); + on lexical field = required clause |
title:hello AND body:world content:"cats"^0.8 | Boolean lexical + weighted vector |
Fusion algorithm examples
{"rrf": {"k": 60.0}}
{"weighted_sum": {"lexical_weight": 0.7, "vector_weight": 0.3}}
Field boosts example
{"title": 2.0, "body": 1.0}
Result
{
"total": 2,
"results": [
{
"id": "doc-1",
"score": 3.14,
"document": { "title": "Hello World", "body": "..." }
},
{
"id": "doc-2",
"score": 1.57,
"document": { "title": "Hello Again", "body": "..." }
}
]
}
search_batch
Execute multiple independent searches in a single round trip. All queries
run in parallel on the server; the same limit and offset apply to every
query. Useful for agents issuing several sub-queries per turn.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
queries | array of string | Yes | Query strings, each in the laurus unified query DSL (same syntax as search) |
limit | integer | No | Maximum results per query (default: 10) |
offset | integer | No | Results to skip per query for pagination (default: 0) |
Result
The batch array preserves input order: batch[i] is the result set for
queries[i].
{
"batch": [
{
"total": 1,
"results": [
{ "id": "doc-1", "score": 3.14, "document": { "title": "Hello World" } }
]
},
{
"total": 1,
"results": [
{ "id": "doc-2", "score": 2.71, "document": { "title": "Vector Search" } }
]
}
]
}
Typical Workflow
1. connect → connect to a running laurus-server
2. create_index → define the schema (if index does not exist)
3. add_field → dynamically add fields (optional)
delete_field → remove fields (optional)
4. put_document → upsert documents (repeat as needed)
add_document → append document chunks (optional)
5. commit → persist changes to disk
6. search → query the index
7. get_documents → retrieve documents by ID
8. delete_documents → remove documents
9. commit → persist changes