Agentic Search

Agentic Search helps agents answer questions when the answer is not in the first chunk returned by retrieval. Instead of searching again and hoping for a better result, the model can work inside the corpus: search to find a source, open it, move through nearby chunks, grep for exact terms, and search again without repeating chunks.

In short, retrieval finds likely sources. Agentic Search lets the model inspect those sources and gather enough evidence to answer. You can use it as a set of Model Context Protocol (MCP) tools that drop into any agent, or as part of the Search Toolkit SDK for custom retrieval pipelines. It works with the indexes you run with Search Toolkit, and you can connect it to Studio agents as a Connector.

Retrieval primitives and the agentic loop

Retrieval primitives and the agentic loop

Agentic Search is not another retrieval method next to keyword or semantic search. Keyword and semantic search are retrieval primitives. Agentic Search is an orchestration layer that uses those primitives, adds navigation, and iterates until the model has enough evidence.

LayerHow it worksBest for
Keyword (lexical)Matches exact terms or phrasesKnown identifiers, code, exact quotes
Hybrid or semantic retrievalCombines keyword and vector search, or uses vector search aloneNatural-language questions over a corpus
Agentic SearchCalls retrieval tools, navigates inside documents, excludes already-seen chunks, and searches againComplex questions that require source verification or evidence across documents

Most production search setups start with hybrid retrieval because it combines keyword precision with semantic recall. Agentic Search builds on that foundation: search uses semantic or hybrid retrieval, and grep adds targeted keyword matching inside a specific document.

How Agentic Search works

How Agentic Search works

Agentic Search runs a retrieval loop. The model doesn't stop at the first chunks it receives: it can inspect a result, read the surrounding context in the source document, then search again with what it learned.

  1. Search: The model runs a query across the collection and receives the most relevant chunks.
  2. Inspect: The model picks a promising hit and reads the surrounding context within that document, without re-running a global search.
  3. Grep: The model searches for an exact term or phrase inside the same document to jump to a more specific region.
  4. Navigate or read: The model steps through adjacent chunks or reads a known source range to gather evidence.
  5. Re-query: With the new context, the model runs another search with exclude_ids so that chunks it already saw don't come back.

The loop continues until the model has enough evidence to answer the question. exclude_ids makes corpus-level pagination possible: the agent can move through new results instead of cycling over the same chunks.

The model calls the following tools inside the loop. The search and navigation tools return chunks with their id, source_id, content, score, and start_offset and end_offset positions. ingest and delete return a status message.

ToolWhat it does
search(query, top_k, exclude_ids)Runs semantic or hybrid retrieval across the collection. Pass exclude_ids to avoid returning chunks the agent already inspected.
open(chunk_id, window)Expands context around a chunk returned by search. Returns the chunk and up to window adjacent chunks on each side, in reading order.
navigate(source_id, start_offset, end_offset, direction, top_k)Steps forward (next) or backward (previous) through a document from a known position.
read(source_id, start_offset, end_offset, top_k)Reads the chunks of a known source range, without expanding context. Leave an offset empty to read from the start or to the end of the document.
grep(source_id, pattern, mode, top_k)Lexical search for an exact phrase (phrase, the default) or for all terms in any order (term) within a single document.
ingest(uri)Adds a document to the index. Accepts a local file or directory path, a file:// URI, or an http(s):// URL.
delete(source_id)Removes a document and all its chunks from the index.
i
Information

Agentic navigation requires a NavigableIndex. When you define your schema migration, set IndexingMode.DOCUMENT_PER_CHUNK so that chunks carry source offsets and can be walked in order.

A Search Index is also a navigable index: it exposes navigate, read, grep, and get_chunk on its API. For details, see Navigate, read, and grep.

Get started with the starter app

Get started with the starter app

To try Agentic Search, start from the search-starter-app template. It is a Copier template that scaffolds a project with ingestion pipelines, a Vespa search index, an MCP server exposing the navigation tools, and sample data.

The starter app is designed to be driven by an agent. You scaffold the project, start Vespa, then launch an agent such as Vibe that discovers the MCP server and calls the search and ingestion tools through natural language.

Before you start, make sure you have the following:

  • A Mistral API key from console.mistral.ai
  • Docker with Docker Compose, to run Vespa locally
  • uv for Python package management. The setup command runs Copier through uvx, so you don't need to install it.
  • Vibe or any MCP-compatible agent, to drive the search loop
Scaffold and start the index

Scaffold and start the index

Create a new project from the template, then start Vespa and apply the schema migrations. Use the tabs to copy the commands or inspect the generated structure.

uvx copier copy gh:mistralai/search-starter-app my-search-project
cd my-search-project
make setup-vespa

Copier asks for the search backend, your Mistral API key, a collection name, and a deployment name for the workflow examples. Keep the default vespa backend: the rest of this page uses Vespa. The make setup-vespa target starts a Vespa container with Docker Compose and deploys the schema migrations. When it finishes, the search index is ready.

Ingest and search with an agent

Ingest and search with an agent

The starter app registers the MCP server for Vibe in .vibe/config.toml. When you launch Vibe in the project directory, it discovers the server and its seven tools. Use the tabs to start Vibe, ingest a document, then ask a question.

vibe --trust

Vibe detects the MCP server and the search skill. To check the connection, run /mcp, which lists the server and its tools.

Tip

You can also run ingestion and search directly from the shell with make ingest path=sample_data/hello.txt and make search query="hello world". The MCP server is the recommended path for agentic workflows.

Use Agentic Search as MCP tools

Use Agentic Search as MCP tools

The MCP server exposes seven tools that any MCP-compatible agent can call. The starter app registers the server so that Vibe discovers it, but you can also connect it to Studio or to a custom agent.

The server starts automatically when Vibe launches in the project directory. To run it standalone, use the tab that matches your transport mode.

uv run python -m entrypoints.mcp_server

Use stdio mode for local agents such as Vibe.

Register the server with an agent

Register the server with an agent

  • Vibe: The .vibe/config.toml file in the generated project registers the server. Run vibe --trust in the project directory and Vibe discovers it.
  • Studio: Run the server in HTTP mode at a URL that Mistral can reach, then register that URL, ending in /mcp, as a Connector. A server on 127.0.0.1 or in stdio mode can't be registered.
  • Custom agents: Connect any MCP-compatible client to the server's stdio or HTTP endpoint. Clients that read .mcp.json pick up the stdio command from that file.

The MCP server includes instructions that describe the retrieval loop: start with search, drill into results with open, grep, navigate, and read, then call search again to connect information across documents. The search tool describes exclude_ids, so the agent can skip the chunks it already read.

Tip

To scope a search to a single document, include the document title or source_id in the query. This narrows the global search.

Use Agentic Search with the SDK

Use Agentic Search with the SDK

If you need more control than the MCP server provides, build the loop yourself with the Search Toolkit SDK. The MCP tools map onto methods of the search index: search and retrieve find relevant chunks across the index, and navigate, read, grep, and get_chunk work inside a document. The SDK requires Python 3.12 to 3.14.

The SDK snippets build from the smallest setup to a full loop step. Use the tabs to open the index, run a search, then gather evidence around a hit.

from mistralai.search.toolkit.mistral_search_index import MistralSearchIndexService

index = await MistralSearchIndexService().get_search_index("exampledocs")
Ingest documents

Ingest documents

The ingestion pipeline loads files, extracts text, splits it into chunks, optionally enriches them, generates embeddings, and indexes the result. The starter app routes files by extension: text files use plain-text extraction, and everything else uses Mistral OCR. Use the tabs to compare the two extractor paths.

from mistralai.search.toolkit.ingestion.pipelines import Pipeline
from mistralai.search.toolkit.ingestion.loaders import FilesystemFileLoader
from mistralai.search.toolkit.ingestion.extractors import PlainTextExtractor
from mistralai.search.toolkit.ingestion.text_splitters import (
    MarkdownTextSplitter,
    MarkdownTextSplitterConfig,
)

pipeline = Pipeline(
    loader=FilesystemFileLoader(),
    extractor=PlainTextExtractor(),
    text_splitter=MarkdownTextSplitter(
        MarkdownTextSplitterConfig(chunk_size=4096, chunk_overlap=50)
    ),
    embedder=embedder,
    stores=vector_store,
)

total = await pipeline.run(documents=["doc.txt"], use_checkpoint=False)
print(f"Indexed {total} chunks.")

You can also ingest documents through the MCP server's ingest tool, which accepts local paths, file:// URIs, and HTTP URLs. The server picks the extractor from the file extension.

Latency and tradeoffs

Latency and tradeoffs

Each tool call adds latency and tokens. Navigation helps the agent avoid repeated broad searches: it can stay inside the right source, use grep to jump to specific terms, and use exclude_ids to avoid revisiting the same chunks.

For background on Search Toolkit, see Introducing Search Toolkit.

To keep the loop efficient, follow these practices:

  • Use exclude_ids on follow-up searches so the agent sees new chunks instead of repeated results.
  • Scope searches to a single document by including its title or source_id in the query.
  • Use grep before broad re-querying when the agent already knows the term or phrase it needs.
  • Tune top_k per hop to keep context windows manageable.
  • Bound the number of hops in your agent definitions to limit the loop depth.
Integrate into agents, workflows, and deployments

Integrate into agents, workflows, and deployments

  • Agents: Register the MCP server as described in Register the server with an agent. With Vibe, run vibe --trust in the project directory, then run /mcp to check the connection.
  • Workflows: The starter app includes ingestion workflows for Mistral Workflows in src/examples/workflows/. Start the worker with make start-examples, then start an ingestion with make execute-ingestion file_path=sample_data/hello.txt. Searches stay direct and don't go through a workflow.
  • Deployments: Self-host the index with Vespa and Docker, or use a managed backend. Expose the MCP server in HTTP mode behind your own authentication for production agents. To snapshot the Vespa application package for CI reproducibility, run make generate-vespa-lock.
Next steps

Next steps

  • Search Toolkit: learn about ingestion pipelines, retrieval strategies, and the full SDK.
  • Libraries: use managed document ingestion and search for built-in RAG.
  • Connectors: connect models and agents to external tools and data sources.
  • Agents: combine language models with built-in tools for multi-step reasoning.
  • search-starter-app: the Copier template for bootstrapping a Search Toolkit project.