What is configurable
Three values, all stored in browser localStorage. No server-side configuration, no .env for the UI.
| Setting | Storage key | Default |
|---|---|---|
| Anthropic API key | kb_anthropic_key | "" |
| Serper API key | kb_serper_key | "" |
| Claude model | kb_model | "claude-opus-4-6" |
| Theme (dark/light) | kb_theme | system preference |
| Disclaimer dismissed | kb_disclaimer_dismissed | false |
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.