Shweta-Mishra-ai/tokenmizer

๐Ÿง  Knowledge & Memory
0 Views
0 Installs

๐Ÿ ๐Ÿ  ๐ŸŽ ๐ŸชŸ ๐Ÿง - Graph-structured session memory for LLMs. Local OpenAI-compatible proxy that extracts tasks, decisions, and files into a typed knowledge graph, auto-checkpoints before context overflow, and resumes any session in 250 tokens. 6 MCP tools including whydecision (traces why a decision changed, with reasons and evidence). pip install tokenmizer

Quick Install

One-Click IDE Configuration
claude_desktop_config.json
{
  "mcpServers": {
    "shweta-mishra-ai-tokenmizer": {
      "command": "npx",
      "args": [
        "-y",
        "shweta-mishra-ai-tokenmizer"
      ]
    }
  }
}
Or

Using an AI coding agent (Claude Code, Cursor, etc.)? Copy a ready-made prompt that tells it to fetch the setup instructions and install this server for you.

Documentation Overview

TokenMizer

TokenMizer

Keep your AI context alive across sessions.

Graph-backed memory ยท session checkpointing ยท intelligent compression
Drop-in proxy for Claude, GPT, Gemini, Grok, DeepSeek, Ollama โ€” any LLM.

PyPI Downloads CI MCP Registry Stars Glama Score

Quick Start ยท How it works ยท Benchmarks ยท Claude Code ยท Contributing

TokenMizer demo: 40-turn session checkpointed at 87% context, resumed next day in 233 tokens
Real run: 25-node graph, checkpoint ckpt_21a0959c3ddf, 233-token resume. Regenerate with python scripts/gen_demo_gif.py.

The Problem

Every AI session has a context limit. When you hit it:

  • The model forgets every decision, rationale, and context built over hours
  • You waste 10โ€“30 minutes re-explaining the project every new session
  • Large files (CSV, PDF, Excel) eat your entire token budget instantly

How TokenMizer Solves It

TokenMizer is a local proxy between your app and any LLM. Every request goes through a pipeline that builds a live knowledge graph, compresses inputs, caches responses, and auto-checkpoints before context runs out.

Your App  โ†’  TokenMizer (:8000)  โ†’  Claude / GPT / Gemini / any LLM
                    โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚   6-Layer Pipeline     โ”‚
          โ”‚   L0  File Intel       โ”‚  CSV/PDF/Excel โ†’ schema + sample
          โ”‚   L1  Compression      โ”‚  15โ€“40% input reduction
          โ”‚   L2  Output Trim      โ”‚  5โ€“15% output reduction
          โ”‚   L3  Semantic Cache   โ”‚  100% on repeated queries
          โ”‚   L4  Graph Memory     โ”‚  session continuity
          โ”‚   L5  Prompt Cache     โ”‚  90% on repeated system prompts
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Architecture

Architecture

Decision Memory โ€” 4-State Model

StatusMeaningIn Resume
๐ŸŸข ACTIVECurrent โ€” in effectโœ… Always
๐ŸŸก SUPERSEDEDReplaced by newer decisionโš ๏ธ 7 days
๐Ÿ”ด INVALIDATEDExplicitly wrong/cancelledโš ๏ธ Always (warning)
โฌœ ARCHIVEDSuperseded >7 days ago โ€” aged outโŒ Never

History is never deleted. "Why did we switch from React to Next.js?" โ€” always answerable: ask GET /api/graph/{session}/why?q=react (or the why_decision MCP tool) and get the full old โ†’ new trail with trigger, reason, and evidence per hop.

From Storage to Reasoning

The graph doesn't just store facts โ€” it answers questions over them:

CapabilityEndpoint / ToolWhat it answers
OntologyGET /api/ontologyThe formal vocabulary: node/edge types with semantics, and the status state machine (which lifecycle transitions are legal)
Causal chainsGET /api/graph/{id}/why?q=... ยท MCP why_decision"Why is X the current choice?" โ€” walks the supersession chain with trigger/reason/evidence per hop
Reasoning viewGET /api/graph/{id}/reasoningActive decisions per topic, recent changes, decision timeline, and a consistency audit
Consistency audit(part of /reasoning)Contradictions the tracker missed, superseded decisions with lost history, dangling references

All reasoning is deterministic and local โ€” no LLM calls, no extra cost.


Quick Start

๐ŸŸข Complete step-by-step setup (start here if you're new โ€” 5 minutes, no code reading needed)

Step 0 โ€” Check Python (need 3.10 or newer)

Open a terminal (Windows: press Win, type "PowerShell", Enter ยท Mac: Cmd+Space, type "Terminal"):

python --version

You should see Python 3.10 or higher. If not: install from python.org/downloads (Windows: tick "Add Python to PATH" during install).

Step 1 โ€” Install TokenMizer

pip install "tokenmizer[anthropic,cache]"

โœ… You should see: Successfully installed tokenmizer-...

Step 2 โ€” Add your API key (get one at console.anthropic.com โ†’ API Keys)

Windows PowerShell:

setx TOKENMIZER_ANTHROPIC_API_KEY "sk-ant-YOUR-KEY"

then close and reopen the terminal.

Mac/Linux:

export TOKENMIZER_ANTHROPIC_API_KEY=sk-ant-YOUR-KEY

(No key? Use free local Ollama instead โ€” see "No API key?" below.)

Step 3 โ€” Start TokenMizer

tokenmizer serve

โœ… You should see: Proxy: http://localhost:8000/v1/chat/completions Leave this terminal open โ€” TokenMizer runs here.

Step 4 โ€” Verify it's alive

Open http://localhost:8000 in your browser โ†’ the TokenMizer dashboard appears. That's it โ€” the proxy works.

Step 5 โ€” Connect your tool (pick yours)

  • Cursor: Settings โ†’ Models โ†’ OpenAI API โ†’ Base URL: http://localhost:8000/v1
  • Claude Desktop / Claude Code: see Claude Code Integration below (copy one JSON block, restart the app)
  • Your own Python code: see "Use โ€” change one line" below

Something failed? pip not found โ†’ reinstall Python with "Add to PATH". Port 8000 busy โ†’ tokenmizer serve --port 8001. Anything else โ†’ open an issue with the error text โ€” median response < 1 day.

1. Install

Works on Windows, macOS, and Linux (Python 3.10+). Same command everywhere:

# Recommended
pip install "tokenmizer[anthropic,cache]"

# All providers
pip install "tokenmizer[anthropic,openai,gemini,cohere,cache]"
No API key? Use Ollama (free, local)
# macOS:   brew install ollama
# Windows: winget install Ollama.Ollama   (or download from ollama.com)
# Linux:   curl -fsSL https://ollama.com/install.sh | sh

ollama pull llama3
pip install tokenmizer
# then set provider: ollama in tokenmizer.yaml

2. Set your API key

macOS / Linux (bash, zsh):

export TOKENMIZER_ANTHROPIC_API_KEY=sk-ant-...

Windows (PowerShell):

$env:TOKENMIZER_ANTHROPIC_API_KEY = "sk-ant-..."      # current session
setx TOKENMIZER_ANTHROPIC_API_KEY "sk-ant-..."         # persistent (new terminals)

Other providers: TOKENMIZER_OPENAI_API_KEY, TOKENMIZER_GEMINI_API_KEY, etc. โ€” full table in Supported Providers.

3. Start

tokenmizer serve
# โ†’ Proxy:     http://localhost:8000/v1/chat/completions
# โ†’ Dashboard: http://localhost:8000
# โ†’ API docs:  http://localhost:8000/docs

4. Use โ€” change one line

from openai import OpenAI

client = OpenAI(
    api_key="your-key",
    base_url="http://localhost:8000/v1",  # โ† only this changes
)

response = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Let's build an auth service"}],
    extra_body={"session_id": "my-project"},  # enables graph memory
)

โœ… Streaming works (v0.3+): stream: true gives real SSE passthrough for Anthropic, OpenAI, DeepSeek, Mistral, OpenRouter, Grok and Ollama. Cursor and Continue.dev work with default settings โ€” no config changes needed.


Claude Code Integration

Option A โ€” Plugin (recommended)

# Add TokenMizer as a plugin marketplace
/plugin marketplace add Shweta-Mishra-ai/tokenmizer

# Install
/plugin install tokenmizer@Shweta-Mishra-ai/tokenmizer

Then use skills directly:

/tokenmizer:checkpoint my-project      โ†’ save session to graph memory
/tokenmizer:resume my-project          โ†’ load previous session (300 tokens)
/tokenmizer:resume my-project full     โ†’ full 600-token context
/tokenmizer:analyze /data/sales.csv    โ†’ analyze file (99% token savings)
/tokenmizer:stats                      โ†’ token savings report

Option B โ€” MCP server (Claude Desktop, Claude Code, Cursor, VS Code, Zed)

mcp-name: io.github.Shweta-Mishra-ai/tokenmizer

Add this mcpServers block to your client's MCP config file:

{
  "mcpServers": {
    "tokenmizer": {
      "command": "tokenmizer-mcp",
      "env": { "TOKENMIZER_URL": "http://localhost:8000" }
    }
  }
}

Where the config file lives:

ClientConfig file
Claude Desktop (Windows)%APPDATA%\Claude\claude_desktop_config.json
Claude Desktop (macOS)~/Library/Application Support/Claude/claude_desktop_config.json
Claude Code.mcp.json in your project, or ~/.claude/settings.json
CursorSettings โ†’ MCP โ†’ Add server (same JSON)
VS Code / Zedtheir MCP settings โ€” same command + env
OpenAI Codex CLI~/.codex/config.toml โ€” TOML format, see below
Codex CLI config (TOML, not JSON)
[mcp_servers.tokenmizer]
command = "tokenmizer-mcp"
env = { TOKENMIZER_URL = "http://localhost:8000" }

Then restart the client. Keep tokenmizer serve running for the checkpoint/resume/stats/reasoning tools (file analysis works without it). If tokenmizer-mcp isn't on your PATH, use "command": "python", "args": ["-m", "tokenmizer.mcp.server"] instead.

Tools exposed (6): checkpoint_session, resume_session, get_graph_stats, analyze_file, get_savings_stats, and why_decision โ€” ask your agent "why did we pick X?" and it traces the decision's supersession chain with reasons and evidence.


Other Tools

Cursor / Continue.dev / any OpenAI-compatible tool:

API Base URL:  http://localhost:8000/v1

Session Resume

tokenmizer checkpoint my-project
tokenmizer resume my-project
Goal: Build FastAPI auth service with JWT + PostgreSQL
Done: Project setup | User model | Login endpoint | Fix 422 | 18 tests passing
In progress: Refresh token rotation
Decided: PostgreSQL (concurrent writes) | bcrypt | Redis for refresh tokens
Changed: ~~React~~ โ†’ Next.js (better SEO)
Files: api/auth.py, api/models.py, config.py
Continue: Implement token refresh endpoint

247 tokens replaces 25,000+ tokens of conversation history.


File Intelligence

from tokenmizer.filters.file_intelligence import FileIntelligence

fi = FileIntelligence()
result = fi.process(open("sales.csv","rb").read(), "sales.csv",
                    token_budget=500, query="which regions underperforming")
# 412,000 tokens โ†’ 447 tokens  (99.9% saved)
FileSavings
CSV (50k rows)99.9%
PDF (200 pages)98.8%
Excel (10 sheets)99.7%
JSON (1k items)95%

Works Alongside Caveman & CodeBurn

TokenMizer complements โ€” does not replace โ€” these tools:

ToolWhat it does
CavemanOutput tokens shorter (~65%)
CodeBurnInput context trimming
TokenMizerGraph memory + resume + file intelligence + cache

Tip: If using Caveman, set terse_output: enabled: false in tokenmizer.yaml to avoid conflicting system prompts.


Supported Providers

Model strings pass through unchanged โ€” the newest models work out of the box: claude-fable-5, claude-opus-4-8, claude-sonnet-5, claude-haiku-4-5, GPT-4o/o-series, Gemini 1.5/2.0, and any Ollama/OpenRouter model.

ProviderEnv var
Anthropic (Claude)TOKENMIZER_ANTHROPIC_API_KEY
OpenAITOKENMIZER_OPENAI_API_KEY
Google GeminiTOKENMIZER_GEMINI_API_KEY
DeepSeekTOKENMIZER_DEEPSEEK_API_KEY
MistralTOKENMIZER_MISTRAL_API_KEY
Grok (xAI)TOKENMIZER_GROK_API_KEY
CohereTOKENMIZER_COHERE_API_KEY
OpenRouterTOKENMIZER_OPENROUTER_API_KEY
OllamaNo key โ€” free, local

Configuration

# tokenmizer.yaml
provider: anthropic
default_model: claude-sonnet-4-6

graph_checkpoint:
  enabled: true
  trigger_at_percent: 0.85
  use_llm_extraction: false     # true = hybrid LLM+heuristic extraction
                                # (needs a provider key, ~$0.001/turn;
                                # requires v0.3.2+ โ€” see CHANGELOG)

compression:
  enabled: true

cache:
  enabled: true
  max_size: 10000

state_backend: memory           # memory | redis (production)

All settings via env vars: TOKENMIZER_PROVIDER, TOKENMIZER_API_KEY, etc.


Docker

# Quick start
docker-compose up tokenmizer

# With Redis (production)
ANTHROPIC_API_KEY=sk-ant-... docker-compose up

# With proxy auth
TOKENMIZER_API_KEY=strong-key docker-compose up

API Reference

EndpointMethodDescription
/v1/chat/completionsPOSTOpenAI-compatible proxy
/api/resume/{id}GETGet resume context
/api/checkpointPOSTManual checkpoint
/api/decision/invalidatePOSTMark decision as invalid
/api/graph/{id}GETSession graph stats
/api/graph/{id}/htmlGETInteractive graph page โ€” decision-history timeline, supersession arcs, type/status filters, search, zoom/pan, PNG export. Zero external dependencies (works offline)
/api/graph/{id}/why?q=GETReasoning: causal chain behind a decision (old โ†’ new with trigger/reason/evidence)
/api/graph/{id}/reasoningGETReasoning view: active decisions by topic, recent changes, consistency audit
/api/ontologyGETMachine-readable graph ontology (types, relations, status state machine)
/api/statsGETToken savings analytics
/healthGETHealth check
/docsGETSwagger UI

Security

  • API key auth โ€” TOKENMIZER_API_KEY (constant-time comparison)
  • Secret/PII redaction applied once at ingestion, before graph storage, checkpoint storage, and every LLM call (main chat and the background extraction model). Patterns cover Anthropic/OpenAI/Google/GitHub/AWS/ Slack/Stripe/JWT/OpenRouter/HF/xAI keys, URL-embedded credentials (postgres://user:pass@host), and generic key=/password= assignments. Best-effort by nature โ€” an unrecognized format with no keyword context can still slip through. The checkpoint layer independently re-redacts what it persists (defense in depth).
  • Session-isolated cache (sensitive data never shared across sessions)
  • Basic prompt-injection keyword filter โ€” catches copy-pasted jailbreak templates only; not a security boundary against a motivated adversary. See SECURITY.md for exactly what it does and doesn't catch.
  • CORS restricted to configured origins by default

Benchmarks

python benchmarks/checkpoint_accuracy/runner_v2.py
pytest tests/ -v

Benchmark v2 โ€” Graph vs plain Summary (3 sessions, heuristic-only, measured 2026-07-02 on v0.2.4):

MethodTask RecallDecision RecallFile RecallInfo Preserved
TokenMizer Graph76%85%100%87%
Plain Summary baseline76%70%92%79%
ฮ” advantage0%+15%+8%+8%

Avg resume size: 254 tokens vs ~1,500+ tokens of raw history. (n=3 synthetic sessions โ€” small sample; treat as directional, reproduce with the command above.)

Enable use_llm_extraction: true for hybrid extraction (LLM + heuristic merge).

On LLM/hybrid recall numbers โ€” read this before trusting any percentage here: earlier versions of this README quoted "90-100% hybrid recall" sourced from runner_v3.py's MockLLMProvider. That mock sampled its fake output directly from the same ground-truth dict used to score recall โ€” circular by construction, guaranteed to look good regardless of what the real extraction logic did. It measured nothing about actual LLM extraction quality. That number has been removed rather than replaced with a better-sounding one we can't back up.

What runner_v3.py now actually does:

  • Default mode verifies HybridExtractor.merge()'s logic contract against fixtures with deliberately known overlap (corroborated / LLM-only / heuristic-only items) โ€” confirms merge never drops an item either source found, and applies confidence tiers (0.95 corroborated, 0.80 LLM-only, 0.65 heuristic-only) correctly. This is a real, non-circular check, but it's a logic-contract test, not a recall measurement.
  • --live mode calls a real configured provider (ANTHROPIC_API_KEY or OPENAI_API_KEY) and scores its actual output against ground truth. This is the only path that produces a number meaningful enough to put in a table. Run it yourself โ€” we're not publishing a live-mode number here because n=3 sessions is too small a sample to generalize, and publishing one without a large, ongoing benchmark would just be swapping one unsubstantiated number for another.

Heuristic-only numbers above (76-100%) ARE real, deterministic, reproducible measurements โ€” runner_v2.py runs actual heuristic extraction against actual ground truth with no LLM and no mocking involved, which is why those numbers are presented with confidence and the LLM ones currently are not.


Why TokenMizer and not X?

Engineers ask this every time. Honest answers:

Why not just use Git history? Git stores what changed, not why you decided to change it. You can't ask Git "what did we decide about auth?" or "why did we switch from MySQL to PostgreSQL?" TokenMizer stores decisions with trigger, reason, and evidence โ€” not diffs.

Why not RAG (retrieval-augmented generation)? RAG retrieves relevant chunks โ€” it doesn't model decision state. If you switched from bcrypt to Argon2 mid-session, RAG might retrieve both and confuse the model about which is current. TokenMizer tracks decision supersession explicitly: old decision is marked SUPERSEDED, new decision is ACTIVE. Resume context only includes current state.

Why not a plain summary at the start of each session? Summaries lose structure. You can't query "all superseded decisions" or "what triggered the auth change" from a blob of text. Our benchmark shows graph memory preserves +5% more information than a summary baseline โ€” and unlike summaries, the graph is queryable, editable, and grows incrementally without re-summarizing everything each turn.

Why not Mem0 or Zep? Mem0 and Zep store facts ("user prefers Python"). TokenMizer stores decisions with rationale โ€” the full causal chain: what was decided, what replaced it, why, what evidence triggered the change, and how confidence shifted. If you need "remember my name across sessions," use Mem0. If you need "remember that we switched from PostgreSQL to SQLite because of cost, and here's the evidence," use TokenMizer.

Why not just a longer context window? Longer context = higher cost + slower inference + model attention dilution on long histories. TokenMizer compresses a 50-turn session into ~246 tokens of structured context โ€” not by summarizing, but by extracting what actually matters: goals, active decisions, current tasks, recent errors.


CLI

tokenmizer serve [--port 8000]
tokenmizer checkpoint <session-id>
tokenmizer resume <session-id> [--level standard|full|critical]
tokenmizer stats

Note on file analysis: /tokenmizer:analyze (used from inside Claude Code, see Claude Code Integration above) is real and works โ€” it's a plugin skill (.claude-plugin/skills/analyze/) that calls FileIntelligence directly via an inline Python snippet, independent of the CLI/API layer. What does not exist is a bare tokenmizer analyze <file> terminal command or a /api/analyze HTTP endpoint โ€” useful if you want file analysis from a plain shell or a non-Claude-Code tool (Cursor, a script, curl, etc.) rather than inside Claude Code specifically. Found during a documentation accuracy pass: an earlier version of this README listed tokenmizer analyze <file> in this CLI section as if it were a cli.py command โ€” it never was. Removed from here rather than left in place pointing at something that would fail. Tracked as a real, wanted gap โ€” contributions adding a /api/analyze endpoint + thin CLI wrapper (following the existing pattern in cli.py) are welcome.


Roadmap

VersionFocus
v0.3SSE streaming passthrough (checkpoint on stream close)
v0.4Graph ontology ยท deterministic reasoning API (why, impact, consistency checks)
v0.5Cross-session memory ยท embedding-based edge linking ยท per-node storage schema (scale past 200-node graphs)
ResearchReal-transcript benchmark suite โ†’ paper (tokenmizer-research)

Have a use case that doesn't fit? Open an issue โ€” extraction misses have their own issue template.


Contributing

Contributions welcome โ€” this project merges fast (median PR review < 1 day).

git clone https://github.com/Shweta-Mishra-ai/tokenmizer
cd tokenmizer
pip install -e ".[dev]"
pytest tests/ -v && ruff check tokenmizer/     # 302 tests, must stay green
python scripts/mcp_e2e_check.py                # full-pipeline e2e check

Highest-impact areas right now:

  1. Graph extraction quality โ€” real-world transcripts where extraction misses tasks/decisions (file an extraction-miss issue even if you don't fix it โ€” the failing transcript itself is the contribution)
  2. Decision tracker edge cases โ€” negation, semantic opposites, and same-decision matching are an active area (see recent merges below)
  3. Reasoning and ontology (graph_memory/reasoning.py, graph_memory/ontology.py) โ€” new in v0.4, still growing
  4. Benchmark sessions โ€” add a real session + ground truth to benchmarks/

Every PR runs the full CI gauntlet (tests ร— 3 Python versions on Linux, one Python version on Windows, lint, Docker build). See CONTRIBUTING.md for guidelines and TESTING.md for the test architecture.

Contributors

Thanks to everyone who has sent a fix upstream:

  • @0xfroOty โ€” negated-decision handling in the decision tracker (#22), OutputTrimmer level alignment (#25), streaming cache-hit analytics (#31)
  • @pollychen-lab โ€” graph node IDs derived from stored (truncated) labels (#21), semantic-opposite decision detection (#26)
  • @floze-the-genius โ€” dashboard stats authentication fix (#35)

Open a PR โ€” CONTRIBUTING.md covers setup and review expectations.


Support the project

TokenMizer is built and maintained by one person. If it saved you tokens, time, or a lost session:

  • โญ Star the repo โ€” the single best way to help others find it
  • ๐Ÿ› Report a bug โ€” especially extraction misses
  • ๐Ÿ“ฃ Share your before/after token numbers (tokenmizer stats) โ€” real usage data shapes the roadmap

License

MIT ยฉ Shweta Mishra


Built for developers who spend too much time re-explaining their projects to AI.

GitHub stars

Related MCP Servers

modelcontextprotocol/server-memoryVerified

๐Ÿ“‡ ๐Ÿ  - Knowledge graph-based persistent memory system for maintaining context

๐Ÿง  Knowledge & Memory2 views
0xshellming/mcp-summarizer

๐Ÿ“• โ˜๏ธ - AI Summarization MCP Server, Support for multiple content types: Plain text, Web pages, PDF documents, EPUB books, HTML content

๐Ÿง  Knowledge & Memory0 views
20alexl/claude-engram

๐Ÿ ๐Ÿ  - Persistent memory and session intelligence for Claude Code. Auto-tracks mistakes, decisions, and context via hooks. Mines session history for patterns and cross-session search. Loop detection, pre-edit warnings, context compaction survival. Runs locally with Ollama.

๐Ÿง  Knowledge & Memory0 views
a2cr/a2cr

๐Ÿ โ˜๏ธ ๐Ÿ  ๐ŸŽ ๐ŸชŸ ๐Ÿง - MCP server for AI-agent handoffs. Saves client-encrypted WorkBaton checkpoints and WorkStash notes so Codex, Claude Code, Roo Code, and other MCP clients can resume work without passing full chat history.

๐Ÿง  Knowledge & Memory0 views

Engagement

Views
0
Installs
0
Upvotes
0

Views and upvotes are unique per visitor network (hashed IP). Installs count copy actions.

Status

Health: Not checked yet

We have not completed a health check for this listing yet.

No check timestamp yet.

Unclaimed listing (imported or pending owner verification). Claim it โ†’
โ˜… Spotlight Slot

Feature Your MCP Server

Get maximum visibility for your server across our directory, search results, and detail pages.

Spotlight Your Server

Own this project?

This directory is pre-filled from public sources. Claim via GitHub README, site badge, or DNS TXT to get the verified badge and attach your website.

Claim this listing

Promote this listing

Optional paid placement. Free listings stay free forever.

Share & Embed

Add our SVG badge (dark/light directory styles) or embeddable widget to your site.