Skip to main content

Problem

Extensions need to retain context and work within tight constraints: limited APIs, no backend to lean on, and a strong expectation of privacy since they can see the pages a user visits. Sending every lookup to a server adds latency and exposes user data you would rather keep on the device.

Approach

Run retrieval entirely in the browser. A modest knowledge base fits comfortably in the client - on the order of a million 256-dimension vectors compresses to roughly 500 MB, and typical extensions need far less - so the index can live on-device and answer queries with no network hop. Data the extension sees never has to leave the browser.

Architecture

  • Background service worker hosts a Moss client (use the browser SDK, @moss-dev/moss-web)
  • Content scripts post messages to the background worker for index/query
  • Persist the index using extension storage or IndexedDB

Code walkthrough (Background)

// background.ts
import { MossClient } from '@moss-dev/moss-web'
const client = new MossClient(process.env.MOSS_PROJECT_ID!, process.env.MOSS_PROJECT_KEY!)

chrome.runtime.onMessage.addListener(async (msg, _sender, sendResponse) => {
  if (msg.type === 'query') {
    await client.loadIndex('ext-context')
    const res = await client.query('ext-context', msg.text, { topK: 3 })
    sendResponse(res)
  }
})

Outcome

Lightweight, private context that improves responses and suggestions - all on-device, with nothing sent to a server.

Browser SDK

The in-browser @moss-dev/moss-web client.

Local embeddings

Embed on-device for privacy.