Skip to content

Querying your data ​

Moʻolelo exposes four query surfaces, each optimized for a different use case:

SurfaceUse caseHow you reach it
Model Context Protocol (search tool)Interactive search from LLM agents — Claude Desktop, custom agents, IDE pluginsA single MCP search tool over Streamable HTTP or stdio
The search index (Apache Vespa)Programmatic search from your own application — hybrid lexical + semantic, low-latency rankingVespa's HTTP Document and Query APIs
The durable record store (Apache Iceberg)Analytical queries — joins, aggregations, time-range filters, exporting batchesTrino, DuckDB, Spark, PyIceberg, Snowflake external tables, or any other Iceberg-aware tool
The audit warehouseCompliance evidence — every query, tokenization, and access decision served by the platformA second Iceberg catalog, separated from the ingest warehouse so auditors can read it without exposing customer content

Iceberg is the source of truth — all records land there first. Vespa is a search projection of Iceberg, kept in sync automatically. The MCP search tool is a thin wrapper over Vespa retrieval that applies source-system ACLs, detokenizes vault fields, optionally pulls related entities via the graph-expansion step, and emits an audit row per query.

Every retrieval surface honours the per-tenant supersession policy — stale duplicates are either marked, downranked, or filtered out depending on your tenant config. This applies whether you query via MCP, Vespa, or Iceberg.

Choosing where to query from ​

If you're plugging Moʻolelo into an LLM agent or assistant, use the MCP search tool. It's the simplest path and the only one that automatically applies source-system permissions and audit-logs the call.

If your question fits "give me the documents that match this query, ranked by relevance" and you're calling from your own application code, you can use Vespa directly — but you become responsible for applying source-system ACLs yourself.

If your question fits "give me everything that was ingested last Tuesday from this source, joined to author identity, exported as CSV", you want Iceberg. That's analytical querying.

If your question fits both — "find me the top 100 documents by hybrid score, then group them by source and count" — you typically issue the search to Vespa, then run the aggregation in your application code or in Iceberg. Vespa supports grouping queries natively, but for cross-source analytical questions, Iceberg's joinable schema is more flexible.

Authentication for queries ​

The two layers have different authentication models:

  • Vespa is reached at the cluster URL with no built-in auth; operators are expected to put a reverse proxy (Linkerd's mTLS, an API gateway, or a custom service) in front of it to do the user authentication. Moʻolelo's audit log captures whichever identity the proxy passes through.
  • Iceberg via the Nessie REST catalog uses Nessie's authentication mechanism — typically OAuth2 against your IDP. Trino, Spark, etc., are configured with the catalog credentials at install time.

For both layers, Moʻolelo's per-record authority chains are present in the data; it's the responsibility of the querying tool (or your application code) to apply them based on the calling user's identity. See Security model for the contract.

Moʻolelo — self-hosted federated enterprise knowledge platform.