Skip to content
archived Visibility internal Owner erik@uvilo.com Approver _ Created _ Updated 2026-04-09

TypeSense Research

Context

Uvilo OS uses Astro Starlight with Pagefind for full-text search. Pagefind is fast and zero-config but is keyword-only — it cannot find conceptually related results when exact terms don’t match. As the documentation grows, semantic search becomes valuable for finding related architecture concepts, specs, and prompts even when users don’t know the exact terminology.

Additionally, Forge agents need a way to discover knowledge files across the entire repo without relying on explicit cross-references. Currently, an agent can only find a file if it’s linked from a previously loaded file or matched by a glob/grep. This is the primary discoverability bottleneck in the system. Typesense with an MCP server solves this by giving agents semantic search over the full repo.

What is Typesense?

Typesense is an open-source, typo-tolerant search engine designed for instant search (sub-50ms). It supports full-text keyword search, faceted search, and — since v0.25.1 — semantic/vector search using built-in ML models (S-BERT) or external APIs (OpenAI, Google). Hybrid search (keyword + semantic combined) is also supported.

Two Consumers, One Index

ConsumerInterfaceUse Case
Humans (website)Starlight DocSearch UI pluginBrowse/search published docs in browser
Humans (terminal)CLI tool (forge-search)Search repo from command line
Agents (LLM)MCP server (typesense-mcp)Semantic search over all repo markdown during agent sessions

All three consumers query the same Typesense instance and collection. The MCP server and CLI are required — without them, agents and terminal users have no access to the search index.

Starlight Integration

There is an official community plugin: starlight-docsearch-typesense. It replaces Pagefind with a DocSearch-style interface powered by Typesense. The setup requires:

  1. A running Typesense server (self-hosted or Typesense Cloud)
  2. The typesense-docsearch-scraper to index the site content
  3. The Starlight plugin to provide the search UI

Hosting Options

Typesense can be deployed on Railway using an official template. Cost is approximately $5–10/month for small deployments. The data lives on a persistent Railway volume.

Advantages:

  • Free open-source software
  • Already have Railway infrastructure for LibreChat
  • Full data ownership
  • ~$5–10/month

Disadvantages:

  • Need to manage the server
  • Need to set up the scraper as a build step or cron job

Option B: Typesense Cloud

Managed service starting at ~$40/month. Includes a one-time free tier of 720 hours (30 days).

Advantages:

  • Zero infrastructure management
  • Monitoring and backups included

Disadvantages:

  • More expensive (~$40/month vs ~$5–10/month self-hosted)
  • Free tier is one-time only, not recurring

Recommendation

Self-host on Railway. We already have Railway infrastructure, and the cost is minimal. The scraper can run as a post-build step in the Vercel deployment or as a scheduled Railway cron service.

Implementation Plan

Phase 1: Deploy Typesense on Railway

  1. Use the Railway Typesense template to deploy a Typesense instance
  2. Configure a persistent volume for data storage
  3. Set API key via Railway environment variable
  4. Expose the service via Railway internal networking or public URL (behind API key)

Phase 2: Repo-Wide Indexing

Unlike the website scraper (Phase 4), this phase indexes the raw repo — all markdown files across all departments, including non-published files like specs, state docs, knowledge files, and agent instructions.

  1. Write a Node.js indexing script (scripts/index-repo.ts) that:
    • Walks the repo tree and finds all .md files
    • Extracts frontmatter (title, status, owner, visibility) as facet fields
    • Extracts the body text as the searchable content
    • Computes the file path relative to repo root as a unique document ID
    • Chunks files >800 words into overlapping segments (~400 words with ~50 word overlap) for better retrieval
  2. Configure the Typesense collection schema:
    • id: relative file path
    • title: from frontmatter or first heading
    • department: root-level folder name
    • content: body text (chunked)
    • path: full relative path
    • type: skill | knowledge | project | infrastructure (derived from path)
    • embedding: vector field using built-in ts/all-MiniLM-L12-v2 model
  3. Run indexing as a git post-commit hook or CI step
  4. Support incremental re-indexing (only changed files)

Phase 3: MCP Server (typesense-mcp)

Build an MCP server that agents can call during sessions. This is the critical piece for agent discoverability.

Tools exposed:

ToolParametersReturns
search_knowledgequery (string), department (optional), type (optional), limit (default 5)Array of {path, title, snippet, score}
get_file_summarypath (string)First 200 words + frontmatter of the file

Implementation:

  1. TypeScript MCP server using the MCP SDK
  2. Connects to the Railway-hosted Typesense instance
  3. Uses hybrid search (keyword + semantic) by default
  4. Facet filtering by department and type
  5. Deploy as a Railway service or run locally as a stdio MCP server
  6. Add to LibreChat MCP server configuration

A simple CLI for humans to search the repo from the terminal.

forge-search "file naming conventions"
forge-search --department=Forge "skill structure"
forge-search --type=knowledge "memory architecture"

Implementation:

  1. Thin Node.js CLI wrapper around the Typesense search API
  2. Formats results as a table: path, title, snippet
  3. Installable via npm link from the repo
  4. Uses the same Typesense instance and collection as the MCP server
  1. Install starlight-docsearch-typesense plugin
  2. Configure the plugin with Typesense server URL, API key (search-only), and collection name
  3. This replaces Pagefind — the search UI becomes DocSearch-style
  4. The website uses the same Typesense instance but may use a separate collection that only indexes published pages (vs the full repo collection used by agents)
  5. Configure the typesense-docsearch-scraper to index the deployed site
  6. Set up scraper as a Vercel deploy hook or Railway cron
  1. Configure the Typesense collection schema with an embedding field using the built-in ts/all-MiniLM-L12-v2 model
  2. Adjust both the repo indexer and website scraper to populate the embedding field
  3. Enable hybrid search (keyword + semantic) in MCP server, CLI, and website plugin
  4. Note: Built-in ML models are CPU-intensive; for a small repo (~100 files), this should be manageable. If slow, consider using OpenAI embeddings API instead.

Dependencies

  • Railway account (already have)
  • Typesense Docker image
  • typesense-docsearch-scraper Docker image (for website indexing)
  • starlight-docsearch-typesense npm package
  • MCP SDK (@modelcontextprotocol/sdk)
  • Typesense API key (search-only key for frontend/agents, admin key for indexer/scraper)

Estimated Effort

PhaseEffortDependencies
Phase 1: Deploy Typesense1 sessionNone
Phase 2: Repo-wide indexing1-2 sessionsPhase 1
Phase 3: MCP server1-2 sessionsPhase 1, Phase 2
Phase 4: CLI tool0.5 sessionPhase 1, Phase 2
Phase 5: Starlight integration1 sessionPhase 1
Phase 6: Semantic search1 sessionPhase 1

Total: ~6-8 sessions. Phases 2-4 (agent discoverability) should be prioritized over Phase 5 (website search), since agent discoverability is the more critical gap.

Open Questions

  • Should the website scraper run against the Vercel preview URL or against a local build?
  • Do we need the Vercel Auth bypass for the scraper, or should we scrape a local build directory?
  • Should we keep Pagefind as a fallback during the transition?
  • Should the MCP server run as a Railway service (accessible from LibreChat cloud) or as a local stdio server (accessible from local Claude Code)?
  • Should we use one Typesense collection for both repo and website, or separate collections with different schemas?
  • Is ts/all-MiniLM-L12-v2 sufficient for our use case, or should we use OpenAI embeddings for better semantic quality?