ROADMAP: PATTTTERNS Chatbot (MCP-backed)
Status: 🟠 In Progress
Updated: April 2026
Goal
A design pattern assistant embedded on docs.patttterns.com and optionally on patttterns.com itself. The chatbot uses the existing /mcp endpoint as its backend — no new AI infrastructure, no third-party training on private data.
Architecture
User types question
→ Chatbot widget (browser JS)
→ POST /mcp (tools/call → search_patterns)
→ search-index.json (static, ~instant)
→ returns matching patterns + URLs
→ widget formats + renders reply
No LLM required for basic search mode. Optionally pipe results through an LLM for natural language answers.
Phases
Phase 1 — Embedded Search Widget (No LLM)
What it does: Accepts a text query, calls search_patterns via MCP, renders results as cards with title + description + link.
Files to create:
docs/assets/js/chatbot.js— widget logic (vanilla JS, no deps)docs/assets/css/chatbot.scss— widget styles matching branddocs/_includes/head_custom.html— injects script + styles
MCP call pattern:
const res = await fetch('https://patttterns.com/mcp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: {
name: 'search_patterns',
arguments: { query: userInput, limit: 5 }
}
})
});
UI: Floating button (bottom-right), slide-up panel, input + results list. PATTTTERNS blue #0267FF accent.
Effort: ~1 day
Dependencies: /mcp endpoint live (✅ done)
Phase 2 — Natural Language Mode (LLM layer) ✅ Implemented
What it does: Takes search results from Phase 1, sends them + the user question to Gemini Flash 1.5, returns a streamed synthesized answer with rich pattern cards (cover image + description + link).
Provider: Google Gemini 1.5 Flash — fast, cost-efficient, streaming via SSE.
Architecture:
User query
→ chatbot.js: POST /mcp (search_patterns, limit 8)
→ returns patterns[] with title, description, url, coverImage
→ chatbot.js: POST /.netlify/functions/chatbot-proxy
body: { query, patterns[] }
→ Gemini 1.5 Flash (server-side, API key never exposed)
→ streams back: { answer, citations[] }
→ widget renders: AI answer text + rich pattern cards
Feature flags (env vars): | Variable | Description | |—|—| | GEMINI_API_KEY | Google AI API key (required for Phase 2) | | ENABLE_AI_CHAT | Set to "true" to activate LLM mode. If absent/false, widget falls back to Phase 1 search-only mode |
Rich card rendering:
- Cover image (from
search-index.json— already present per pattern) - Pattern title + description
- Clickable link to
patttterns.com/... - AI-generated answer text above the cards with citations
Embed targets:
docs.patttterns.com— viadocs/_includes/head_custom.html(Phase 1 already wired)patttterns.com— viasrc/app/layout.tsx, lazy-loaded (Phase 3)
Files created/updated:
netlify/functions/chatbot-proxy.ts— Gemini proxy (serverless, streaming SSE)netlify/edge-functions/mcp.ts— updated to includecoverImageinsearch_patternsresultsdocs/assets/js/chatbot.js— AI mode: streaming answer + rich cover-image cardsdocs/assets/css/chatbot.scss— cover image + AI answer styles
Effort: ~2 days
Dependencies: Phase 1 complete ✅, GEMINI_API_KEY + ENABLE_AI_CHAT=true as Netlify env vars
Phase 3 — Embed on patttterns.com
What it does: Same widget injected into the main site via src/app/layout.tsx.
Considerations:
- Load lazily (only after interaction) to avoid LCP impact
- Gate LLM calls to avoid abuse (rate limit by IP at the Netlify Function level)
- Show only on pattern pages (
/patterns/*,/ux-patterns/*)
Effort: ~0.5 days (reuse Phase 1/2 assets)
Phase 4 — MCP Resources (Pattern content)
What it does: Extend the /mcp endpoint to serve full pattern page content via resources/read, not just search index metadata.
Agents and the chatbot can then answer “what does the user-feedback pattern say?” with actual content, not just a URL.
Implementation: Edge function reads from /public/.notion-cache/{id}.json (already built by build:content).
Files to update:
netlify/edge-functions/mcp.ts— addresources/listandresources/readmethods
Effort: ~1 day
Dependencies: .notion-cache populated (✅ exists)
Widget UX Design
┌─────────────────────────────────┐
│ Ask about design patterns… │ ← input
├─────────────────────────────────┤
│ ● User Feedback │
│ Ratings, scores or votes… │
│ patttterns.com/ux-patterns/… │
│ │
│ ● Call to Action │
│ Pricing, sign-up, paywalls… │
│ patttterns.com/ux-patterns/… │
└─────────────────────────────────┘
- Trigger: floating
?button, bottom-right, brand blue - Panel: 360px wide, slides up, search-first, no modal overlay
- Results: max 5, each a clickable card
- Keyboard:
Escapecloses,Entersubmits, arrow keys navigate results - Empty state: “Try searching for ‘onboarding’, ‘checkout’, or ‘navigation’”
Decision Log
| Decision | Rationale |
|---|---|
| MCP backend over third-party (Kapa/Inkeep) | No data leaves the site; consistent with agent readiness work |
| Vanilla JS widget | No framework dependency; loads in docs and main site equally |
| Phase 1 first (no LLM) | Instant value, zero ongoing cost, validates UX before adding AI cost |
| Netlify Function proxy for LLM | API key stays server-side; rate limiting easier than edge |
| Extend MCP resources in Phase 4 | Full content already cached; natural extension of existing architecture |