What is configurable

Three values, all stored in browser localStorage. No server-side configuration, no .env for the UI.

SettingStorage keyDefault
Anthropic API keykb_anthropic_key""
Serper API keykb_serper_key""
Claude modelkb_model"claude-opus-4-6"
Theme (dark/light)kb_themesystem preference
Disclaimer dismissedkb_disclaimer_dismissedfalse

useSettings

KB/src/hooks/useSettings.ts:20–48. Returns { settings, updateSettings, hasAnthropicKey }.

loadSettings() reads all three keys synchronously on first render via the useState initializer (useSettings.ts:25). updateSettings(patch) merges into state and writes any present field to localStorage. hasAnthropicKey is a derived boolean — drives the amber dot on the floating “Ask Claude” button when no key is set.

<SettingsModal>

KB/src/components/SettingsModal.tsx. Modal dialog. Three controls:

  • Anthropic key — <input type="password"> with link to https://console.anthropic.com.
  • Serper key — <input type="password"> with link to https://serper.dev.
  • Model select — three options:
    • claude-opus-4-6 — “Most capable” (default)
    • claude-sonnet-4-6 — “Balanced”
    • claude-haiku-4-5-20251001 — “Fast”

Modal local state is seeded from settings when the modal opens (SettingsModal.tsx:23–30). Save button triggers onSave({ anthropicKey, serperKey, model }), then displays “Saved” check for 2 seconds. Escape key closes.

The modal does not auto-close after Save — the user must hit Cancel/Close. This is intentional (lets users verify the “Saved” indicator).

Warning

Help text in the modal claims keys “are never transmitted to our servers” (SettingsModal.tsx:203). That is technically false: keys travel as request headers (X-Anthropic-Key, X-Serper-Key) to the Bun server, which uses them to call Anthropic and Serper directly. The keys are not persisted server-side, but they do transit the local KB server.

useTheme

KB/src/hooks/useTheme.ts:24–44. Returns { isDark, toggleTheme }.

On mount, reads localStorage["kb_theme"]; if absent, falls back to window.matchMedia("(prefers-color-scheme: dark)").matches. Applies by toggling the .dark class on <html> (useTheme.ts:15–22) — Tailwind v3 darkMode: "class" then takes over.

<ThemeToggle> renders a sun (when dark) or moon (when light) icon. Located in the sidebar footer.

See also

KB Architecture, KB UI Components, KB Chat Flow.

See also