Skip to content
ayan://bhardwaj (home)

// Built at Moss · YC F25 · Search

Mycelium

Your browser, with memory.

A spore for every page you finish.

Browser history works when you remember a title or a URL. Mycelium is for when you only remember the idea. It quietly turns the long articles you read into private semantic memory, then lets you search them by meaning from a command palette, and shows how they connect.

Mycelium is an unpacked Chrome extension (Chrome 121+), not on the Web Store yet, so there's nothing to visit. The palette, ingestion and graph below are recreations that run on this page.

Live demo, running on this page

⌘K

Recently ingested

  • Building agents that remember across sessionsdev.to · 620 words
  • Local-first software: you own your datamartinfowler.com · 1,811 words
  • Vector search explained with picturesmedium.com · 2,208 words
  • Offscreen documents in Chrome extensionsgithub.blog · 1,569 words
  • Knowledge graphs from your readingmedium.com · 2,484 words

00 Overview

After about 1.8 seconds on a page, and again when a single-page app changes URL, a content script runs Mozilla Readability. Only HTTP(S) pages with at least 500 readable words become memories, and a guard skips webmail, banking, checkout, payment and medical-record URLs. A stable URL hash means a revisit updates one memory instead of making a duplicate.

Moss runs embedding and vector search in WebAssembly inside the extension. Captured pages sync to your Moss project so the durable index can be built; once that index is loaded, warm queries run locally with no network round trip. OpenRouter is optional and off by default.

Built at
Moss · YC F25
Platform
Chrome extension (MV3)
Retrieval
Moss Web SDK, WASM
Model
moss-minilm
Graph
d3-force + Canvas 2D
  • TypeScript
  • Chrome Extension API (MV3)
  • Moss SDK (WASM)
  • d3-force
  • Canvas 2D
  • OpenRouter (optional)

01 Browse → ingest

Every article becomes memory.

Each tab below runs the real gates: Readability, the 500-word floor, the sensitive-site guard and URL-hash dedupe. Pages that pass are written to chrome.storage.local immediately, then upserted to Moss.

  1. dev.to/building-agents-that-rememberBuilding agents that remember1,840 wordsIngested · new memory
  2. medium.com/local-first-softwareLocal-first software2,310 wordsIngested · new memory
  3. news.example.com/quick-updateQuick product update212 wordsSkipped · under 500 readable words
  4. bank.example.com/accounts/checkingChecking accountnot readSkipped · sensitive-site guard (banking)
  5. arxiv.org/abs/self-improving-agentsSelf-improving AI agents3,120 wordsRevisit · same URL hash, 1 memory updated
chrome.storage.local2pages, written immediately
Moss index2upserted · 1 updated in place

02 Search

⌘/Ctrl+K on any page (or ⌘/Ctrl+Shift+K, or the toolbar icon) opens the palette in an isolated Shadow DOM. Input is debounced 150 ms; up to eight ranked results come back with query-aware snippets, favicons, scores, the retrieval source and measured latency. The footer is honest about where answers came from: LOCAL WASM when Moss answered from the loaded index, LOCAL CACHE when a lexical fallback answered while Moss was warming up. Moss gets 1.2 s before it times out; the fallback can render after about 250 ms and is replaced when Moss hits arrive.

One cold query, two answers
  1. Keystroke150 ms debounce
  2. LOCAL CACHElexical fallback renders after about 250 ms
  3. LOCAL WASMMoss hits replace the fallback when they arrive; it gets 1.2 s before timing out

The palette at the top of the page runs this race in your browser, over a 40-page demo index with a tiny hashed embedding, not Moss's model. The first query after a cold start shows it: LOCAL CACHE answers while the index warms, then LOCAL WASM results replace it.

03 Connect

Memory becomes connected.

⌘/Ctrl+Shift+G opens graph.html: up to 300 pages, clustered by domain with stable colours, sized by revisits and search matches. Edges come from normalised shared-term overlap, kept above 0.08 and capped at five per node, and cached by data revision. Pan, zoom, drag, hover focus, graph search and a node inspector.

40 pages · 111 hyphae
All 40 pages, as a list
  • dev.to
  • arxiv.org
  • medium.com
  • github.blog
  • simonwillison.net
  • lilianweng.github.io
  • web.dev
  • martinfowler.com

04 Under the soil

Four parts, one message.

  1. 01Content script

    React + Shadow DOM. Readability after ~1.8 s, 500-word and sensitive-site gates, immediate chrome.storage.local write, the palette UI.

  2. 02Service worker

    MV3 background: search orchestration and lexical fallback, settings, graph and summary caches, the OpenRouter queue, commands, offscreen lifecycle.

  3. 03Offscreen document

    Owns @moss-dev/moss-web: createIndex, addDocs({ upsert: true }) in batches of 50, loadIndex, then in-browser query embedding and top-8 vector retrieval.

  4. 04graph.html

    React + d3-force + Canvas 2D with an affinity-edge cache.

Why an offscreen document: MV3 service workers are short-lived and can't host the Moss WASM stack, so a long-lived offscreen page owns the client and the loaded index. The background build is a single static file because dynamic imports are rejected there; Vite builds three targets (extension pages, the worker, an IIFE content script).

05 What stays local

Honest about what leaves.

  • Page text + metadatachrome.storage.localSTAYS LOCALAlways. Written the moment a page passes the gates.
  • Page textYour Moss projectSYNCSSynced, so the durable index can be built and loaded.
  • Search queriesMoss WASM, inside the extensionSTAYS LOCALLocal. No per-query network round trip once the index is loaded.
  • Title + up to 12,000 charsOpenRouterNOT SENTOff by default. Nothing is sent.

06 Also

  • Optional AI summaries

    Off by default. When on, OpenRouter (openrouter/free by default) writes one sentence under 20 words from the title and up to 12,000 characters, capped at 60 tokens, cached per URL and queued so it never blocks ingestion. Without it, Mycelium falls back to the title or snippet silently.

  • Built for revisits

    Each memory tracks first and last visit, revisit count and how often it matched a search, which also drives node size in the graph.

  • Local by default

    Text and metadata live in your Chrome profile with unlimitedStorage. Six storage keys hold pages, settings, summaries, the data revision, last sync and the graph cache.

Stack TypeScript, React, Chrome Extension MV3 (service worker, offscreen document, content scripts, commands), Moss Web SDK (WASM, moss-minilm), Mozilla Readability, d3-force, Canvas 2D, Vite, pnpm, OpenRouter (optional).

07 From the promo video

Frames from the 27-second promo video in the repo, rendered programmatically with Python and Pillow. They're stylised, not screen recordings, and the latency figures in them are illustrative.

Title card from Mycelium's promo video: a violet glow behind the words “Your browser, with memory.” and a Powered by Moss pill
Frame from Mycelium's promo video: three ingested article cards with violet progress bars and the caption “Every article becomes memory.”
Frame from Mycelium's promo video: the search palette returning ranked pages for “self-improving AI agents”
Frame from Mycelium's promo video: read pages connected as a knowledge graph around an AI agents hub