Customer support KB

~4 min read

Customer support knowledge base

Turn raw support tickets and Q&A into reusable, searchable, publishable knowledge-base articles.

What it does

  1. You forward / paste a resolved support thread into a new note under Inbox/.

  2. A trigger splices a > [!ai] directive into the new note describing the job.

  3. A connected MCP agent picks the directive up (via pending_directives) and extracts the core question and the resolution.

  4. It searches KB/ for an existing article on the same topic.

  5. If one exists: it proposes updating it with any new context.

  6. If not: it creates KB/<slug>.md with a question-and-answer structure.

  7. Once the KB is full, lettuce publish exposes it for self-service.

Setup

1. The trigger

A trigger fires on file:created and splices a > [!ai] <prompt> directive into the new note. It does no work itself — whatever MCP agent you have connected sees the directive through pending_directives and does the extraction, search, and writes (proposing them if its key is propose-only).

# .lettuce/triggers.yml
- when: "file:created:Inbox/*.md"
  prompt: |
    This is a resolved support thread.

    1. Identify the core question (likely the first user message).
    2. Identify the resolution (likely the last support agent message).
    3. Generate a short, searchable title for the question.
    4. Search KB/ for an existing article addressing this question.
       If a strong match exists, propose adding a "## Also seen in"
       section with a wikilink back to this thread.
    5. If no match, write a new note at KB/<slug>.md:

       ---
       title: "<Q: question>"
       tags: [kb, support, <area>]
       published: true
       ---

       # <Question>

       ## Answer

       <Resolution, paraphrased for clarity.>

       ## Also seen in

       - [[this thread]]

The when is the only event the trigger engine supports (file:created with a glob), and splicing the prompt is the only action — there are no if/predicates, no provider/model/mode fields, and no {{ }} templating.

2. Convention

Drop support threads as new notes under Inbox/ so the glob matches. A bit of frontmatter keeps them organised — note these are your own keys for your own reference; Lettuce reads title, published, tags, aliases, date, updated, and description, and ignores the rest:

---
ticket: SUP-1234
customer: "<email>"
date: 2026-05-28
---

Publishing

Any note with published: true in its frontmatter is included when you build the site — there is no separate config file to maintain. The KB articles above already set published: true, so they ship automatically:

lettuce publish && lettuce deploy

Tag pages let visitors browse by area, e.g. articles tagged kb/auth.

Variants

Slack threads

If your support happens in Slack, use a Slack-to-Markdown extractor to drop threads as .md files into Inbox. Pattern is the same from there.

Email-driven

A small script that reads a support inbox via IMAP and writes each email thread to Inbox/email-<id>.md with frontmatter:

# tools/email-to-inbox.py
import imaplib, email, datetime, os

# ... fetch unread, write to Inbox/email-<msgid>.md with frontmatter type: support

Run nightly via launchd. The existing trigger picks them up.

Multi-product

If your product has multiple “areas”, extend the trigger’s prompt so the agent files by area:

# .lettuce/triggers.yml
- when: "file:created:Inbox/*.md"
  prompt: |
    ... identify the area (auth / billing / api / ui / ...) ...
    Tag the KB article with `kb/<area>` and save it to KB/<area>/<slug>.md.

Search-first KB

Add a self-service portal: build the static site, embed Lettuce’s client-side search (it’s automatic). Customers ⌘K to find answers without filing a ticket.

Privacy

KBs from real support data often contain customer-specific details. Two ways to handle:

  1. Sanitisation prompt step: have the agent strip emails, names, account IDs in the same write_note it proposes.

  2. Two vaults: keep raw tickets in a private vault and KB articles in a public one, and publish only the public vault. Mark the articles you want to share with published: true, then build/host the public site:

    lettuce publish ~/Notes-public --out ~/share/kb     # only published: true notes
    # or push it to GitHub Pages: lettuce deploy ~/Notes-public --repo you/kb --token $GITHUB_TOKEN