Description
Universal Search gives people and agents one retrieval surface across every knowledge type registered with Dots. A query can start in the Cmd+K palette, the top-bar search field, Chat's universal mention picker, dots search, the MCP search tool, or POST /api/v1/search; each surface reaches the same SearchService behavior rather than maintaining a separate ranking implementation.
The engine classifies intent, obtains a cached query embedding when available, retrieves full-text and vector candidates, reranks and graph-expands them, then returns facets, suggestions, degradation metadata, and a stable keyset cursor. Authorization is resolved before retrieval and every SQL leg is company-scoped. Isolated provider or entity-stream failures degrade visibly without discarding successful results.
Selling Points
- One search mental model spans the UI, CLI, MCP, API, and Chat, so users do not have to learn which store owns a fact before looking for it.
- Hybrid retrieval finds both literal matches and conceptually related knowledge, improving recall without making exact terms less useful.
- Access filtering happens before database retrieval, preventing search from becoming a side channel into unreadable Dotabases.
- Graceful degradation preserves keyword search when embeddings or reranking are unavailable and tells the surface which capability degraded.
- Stable cursor pagination and cross-page deduplication let large result sets remain usable while data changes underneath them.
User Story
A workspace member remembers a decision but not whether it lives in a note, an artifact, a conversation, or a project row. They press Cmd+K, enter the remembered phrase, narrow if needed, and open the best result. The same query can be repeated by an agent through MCP or by a script through the API, with the same company boundary and ranking behavior.
Extension Surface
Pluggable is the first true rung because packages/search/src/registry/entity-types.ts exposes registerEntityType, a formal boot-time registration point for additional searchable entity implementations. The core in packages/search/src/internal/service.ts also receives embedding, reranking, graph, access, cache, and event dependencies as injected contracts. Registration is composition-root scoped, not a tenant self-service marketplace.
Capabilities & Limits
- Searches all registered entity types with relevance, created-time, or updated-time sorting.
- Returns result metadata, facets, suggestions, degradation flags, and keyset pagination.
- Supports exact-ID pinning and scoped filters without storing actor-specific pins in the shared cache.
- Limits: the built-in entity registry is intentionally empty until packages register descriptors at boot; unregistered types cannot be searched.
- Limits: provider failure can reduce semantic quality to BM25-only, although the request still succeeds.
Implementation Map
packages/search/src/internal/service.tspackages/search/src/internal/pipeline.tsapps/web/src/modules/shell/search-palette/SearchPalette.tsxpackages/api/src/routes/search-universal.tspackages/mcp/src/tools.ts