Support inbox agent
A Claude Code skill that triages your support inbox and drafts replies for human review. Works with any support tool that ships an MCP server.
npx -y skills add sitespeakai/support-inbox-agentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 19 days oldThe repository was created 19 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when doing the daily support-inbox pass - checking the support chatbot inbox for new visitor issues and questions and preparing personalized email drafts for human review. Triggers on "/support-inbox-agent", "support inbox pass", "draft support replies".
SKILL.md
7.8 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it
Support Inbox Agent
Read new threads from the support inbox, investigate each issue or question until verified, then create one personalized email draft per visitor. Drafts only - a human reviews and sends.
Safe to run daily (or more often): the state file prevents duplicate drafts.
Placeholders - fill these in
<INBOX_ID>- your support chatbot/inbox id<EMAIL_ACCOUNT>- the email account drafts are created in<DOCS_URL>- your public docs, used to verify how-to answers<REPO_PATHS>- local paths to the codebases the agent may read when investigating- MCP tool names below are examples (SiteSpeak inbox, Sentry, Superhuman). Swap them for your stack's equivalents.
Config
- State file:
state/processed.json- JSON object mappingvisitor_idto{ "processed_at": ISO UTC, "action": "drafted" | "skipped", "reason"?: string, "email"?: string, "draft_id"?: string, "draft_thread_id"?: string }. Missing file = empty object.
Steps
1. Load state and list threads
Read the state file. Then list open inbox threads (e.g. list_inbox_threads with chatbot_id: <INBOX_ID>, status: "open"), newest first.
Keep a thread when BOTH:
- its last activity is within the last 7 days (self-heals skipped days), AND
- the thread is not in state, OR its last activity is later than its
processed_atin state (the visitor wrote again since the last run - this applies to previously skipped threads too)
If nothing qualifies, report "No new inbox activity" and stop.
2. Read each thread and classify
For each kept thread, fetch the full conversation (e.g. get_thread_messages). Read the visitor's own messages, not just the bot's answers.
Classify - and bias toward replying. When in doubt between "skip" and "follow up", follow up; a short personal email from a real person converts, and a human reviews every draft before sending anyway:
- Issue - something broken, wrong answer, billing problem, frustrated customer, asked for a human
- Question / prospect - how-to, pricing, "can it do X", evaluating the product. Any thread with a plausible email gets a follow-up draft even if the bot answered fully
- Throwaway-looking email with real buying questions: still draft, but flag the address in the summary so the human decides whether to send
- Noise - empty sessions, spam, tests, or no email captured at all. No draft possible.
Long-history threads (returning customers): only the messages since the last run need action; earlier exchanges are context.
3. Find the visitor's email
In order: the thread/lead fields returned by the inbox tools, an email typed inside the visitor's messages, then the leads endpoint (e.g. list_leads) matched by visitor id. No email found = no draft possible; mention it with its gist in the summary (it still gets archived in step 6).
4. Investigate before drafting
Never guess. Every claim in a draft must be verified this session or absent from the draft.
- Bug / "it doesn't work": search the error tracker for matching errors (production environment only - local noise reports there too); read the relevant code in
<REPO_PATHS>. Reproduce the claim against the code before agreeing or disagreeing with it. - How-to / feature question: verify the answer against code or the live docs at
<DOCS_URL>. Only cite features that actually exist. Unsure a feature exists? Check the code; still unsure = leave it out of the draft and flag in the summary. - Account-specific / billing: production data is not reachable from here. Draft acknowledges the issue, asks for the account email if not evident, and says you are looking into it. Do not assert account state.
If investigation finds a real product bug, note it in the summary as a candidate issue - do NOT create tickets or change any code; this skill is read-only outside email drafts.
5. Check for an existing email thread - BEFORE drafting anything
Search the email client for threads from the visitor's address in the last 30 days (e.g. list_threads with from: [<visitor email>]). Read the snippets. Three outcomes:
- Already handled: the visitor emailed about the same topic and already got a reply. SKIP the draft entirely and record it in state with the email thread id. Visitors often email support minutes after the chatbot tells them a human will follow up - a fresh draft here duplicates a conversation that is already ahead of you.
- Open thread, same or related topic, no reply yet: draft as a reply in that thread.
- No relevant thread: draft as a new email.
6. Create the draft
Create the draft (e.g. create_or_update_draft) with an exact body - if your email tool has an AI-writer "instructions" mode, do not use it; write the body directly so the style rules hold.
Style rules:
- Open with
Hi <first name>,orHi,when no name - Direct answer in the first sentence or two. Short. No "thanks for reaching out" padding, no marketing
- Zero internals: no table names, code paths, schema, thresholds, or vendor/service names
- No em-dashes. Plain language, no corporate idioms
- Honest phrasing only: no promised fix dates, no claims that were not verified in step 4
- End with your standard signoff and nothing after it if your client auto-adds a signature
If the visitor wrote again after a previous draft (state hit with newer activity), update the stored draft in place using the saved draft_id instead of creating a second one - but only if it is still unsent; if the draft no longer exists, create a new one.
Close every processed thread: archive it in the support tool (e.g. update_thread_status with status: "archived"). Archive threads that got a draft AND threads where no reply is needed (noise, no email captured, already handled by email). The goal: the inbox is empty after each run, with every reachable visitor covered by a draft. Record the archival in state.
7. Save state and summarize
Record EVERY processed thread in the state file, drafted or skipped - skipped entries stop tomorrow's run from re-reading the same noise. For drafts, store the returned draft and thread ids; processed_at = now (from date -u +%Y-%m-%dT%H:%M:%SZ, never invented).
Final summary, one row per thread: who (name/email), classification, what the investigation found (one line, verified facts only), and draft created / skipped-why. Flag anything needing a human decision (unverifiable claims, candidate bugs, no-email threads).
Hard limits
- NEVER call the send tool. Drafts only, always.
- Archiving is allowed ONLY for threads processed this run. Never touch threads outside this run's list, and NEVER trash threads, mark spam, or discard drafts.
- NEVER edit code or create tickets from this skill; report candidates in the summary instead.
- A claim that could not be verified this session must not appear in an email.
Common mistakes
| Mistake | Fix |
|---|---|
| Letting an AI-writer feature compose the body | Write the exact body directly |
| Explaining internals to the customer | Direct answer only; internals stay in the summary |
| Drafting for a thread twice | Check state first; visitor-wrote-again = update stored draft |
| Answering from memory ("the product supports X") | Verify in code/docs this session or leave it out |
| Skipping threads with no lead record | Email is often typed inside the chat messages - read them |
| Drafting a topic the visitor already emailed about | Step 5 first, always - if it was answered by email, skip and record |
| Only recording drafted threads in state | Record skipped ones too, or every run re-reads the same noise |
What ships with it: 4 files
6.8 KB alongside SKILL.md, 1 of them executable
examples/
- launchd.plist929 B
- run.shruns781 B