The complete capability inventory — organized by what the product does, not by when we shipped it. If you want the release-by-release timeline instead, the changelog tracks that.
📨 PO Processing
Inbound purchase orders from Gmail into structured line items.
Gmail inbox scanningsince v0.9
Pulls unread emails matching PO patterns (subject keywords, attachments, body anchors). Zero-config — works on day one without a Gmail filter. list_incoming_pos
PDF text extractionsince v0.9
Pulls every PDF attachment, classifies each as primary PO / secondary PO / cover letter / spec sheet, extracts lines only from primary & secondary docs. Dedupes lines across duplicated attachments.
OCR + vision fallbacksince v0.10
When PDFs are scanned or handwritten, the parser runs through Tesseract first, then Azure Document Intelligence (if configured), then falls through to Claude's vision pass on page images. Structural-trust scoring rejects garbled output before it pollutes the line set.
Image attachmentssince v0.10
PNG, JPEG, WEBP, HEIC attachments treated like single-page PDFs — same vision passthrough. Handles photos of handwritten POs taken on a phone.
Promotional email filtersince v0.15.26, hardened v0.15.32
Marketing emails ("🔥 Win A Beretta…", newsletters, contest entries, Mailchimp / SendGrid / Klaviyo senders) short-circuit before any parsing work or quota consumption. Never logged as po_processed.
Customer matching by domainsince v0.12
Sender email domain → QB customer lookup. Surfaces the right QB customer on parse with zero operator input. lookup_customer_by_domain
Intent classificationsince v0.13
Quote vs Order vs Reorder vs Ask — per-customer classifier with memory that grows as operators label intents. Drives auto-acknowledgment routing.
Auto-acknowledgment draftssince v0.13
Drafts a "we received your order, on it" reply in Gmail as a Draft (never sent). Operator clicks Send when ready. Opt-in via SIDEQUEST_AUTOACK=true.
📝 Drafts & Review
Every parsed PO becomes a local draft. Human review before anything reaches QuickBooks.
Local-first drafts
Drafts live in local SQLite, never auto-submitted. Operator reviews lines, prices, and customer match before submit. list_drafts get_draft
SKU matching
Match path priority: exact SKU → cross-reference → description fuzzy match → unmatched. Returns top-N candidate alternates with confidence scores when no exact hit.
Auto-learning cross-referencessince v0.8, fully wired v0.15.34
Every time an operator resolves an unmatched line by assigning a SKU, that fix gets written to your cross-reference table as a permanent rule. The next PO from the same customer with the same part auto-matches at 100% confidence. Your match rate compounds week over week instead of resetting on Monday.
Requires CROSS_REFERENCE_CSV in your .env — see the
quick-start auto-learn section for setup. Run
setup_health_check to confirm it's on.
Price variance check
PO unit price vs current QB unit price — flags lines where the variance crosses a threshold so the operator doesn't accidentally honor a stale customer quote.
Line-level editssince v0.11, hardened v0.15.34
Add, remove, or update lines on a draft. Quantity changes, item swaps, price overrides — all locked locally before submit. Shared input gate rejects negative quantities (use a credit-note marker for returns instead), out-of-range discount percents, and the silent "both percent and dollar discount passed" trap. add_draft_line update_draft_line remove_draft_line
Document discountsince v0.15.25, fixed v0.15.29
Apply a percent or fixed-dollar discount across the whole order. Freight excluded by construction — QB stores the exact computed amount. set_draft_doc_discount
Customer-facing reply drafts
Drafts a "here's your quote / order confirmation" reply with the matched lines, totals, and validity dates. Gmail Draft only — operator sends. draft_reply_to_buyer
Bulk submit clean draftssince v0.14
Submit every draft that passed all gates (no missing customer, no unmatched lines, no price variance) to QuickBooks in one call. Confidence-gated — anything risky stays in review. bulk_submit_clean
Bulk discard cleanupsince v0.15.34
Wipe out accumulated draft junk in one call instead of discarding 30 drafts one by one. Filters compose: by age, by customer, by status. Defaults to dry-run so you see the preview list before you commit. Submitted drafts are always skipped — this tool never touches anything that already reached QuickBooks. bulk_discard_drafts
❤️ Customer Health Score
CRM-lite over your QB data. Score every active customer 0-100, surface who needs attention this week.
The Customer Health card on the operations dashboard. At Risk customers sort first — the morning callsheet.
Four-signal scoringsince v0.15.31
Recency (30 pts, days since last order), Frequency (20 pts, drafts in last 90d), AR Health (30 pts, overdue balance + oldest days overdue), Match Quality (20 pts, auto-clean rate). Total 0-100.
Four health bucketssince v0.15.31
At Risk (<50, active — your callsheet), Watch (50-79 — early warning), Dormant (no activity 180d+ — re-engage or remove), Healthy (80+).
Actionable recommendationssince v0.15.31
1-3 specific recommendations per customer — "Collect $4,200 — oldest invoice 78d overdue", "Only 30% of drafts auto-clean. Add cross-references for their most-used parts", "Hasn't ordered in 50d (was a regular). Check in before they churn."
Dashboard health cardsince v0.15.31
Bucket-summary pills + per-bucket customer tables with score, days since last seen, overdue amount, and top recommendation. customer_health
💰 Pricing Intelligence
Find the money you're leaving on the table. Four buckets of pricing patterns surfaced from your QB catalog and draft history.
The Pricing Intelligence card on the operations dashboard. High Leverage findings show what a 2% bump is worth annualized; Below List quantifies the gap to your list price per customer.
High leveragesince v0.15.36
Top revenue items, ranked. For each one the report annualizes the period revenue and quantifies what a 2% list-price bump is worth in annual dollars. "Pricing Widget X up 2% = +$1,847/yr." Where to focus the next price review.
Below list customerssince v0.15.36
Customers whose paid prices ran materially under your QuickBooks list across five or more lines in the lookback window. Surfaces the dollar gap to list. Either intentional contract pricing the operator forgot to formalize, or a leak — now you know which.
Variable pricingsince v0.15.36
Items where the same SKU sold at materially different prices across four or more customers (≥15% spread around the median). Some intentional, some not. The card shows the price range and the lowest-paying customers so you can decide.
Stale listsince v0.15.36
Items where every recent order paid exactly list price, no overrides. Strong signal the list has been frozen for a long time and probably hasn't kept up with cost movement. pricing_intelligence
🧹 Catalog Hygiene Assistant
Audit the QuickBooks item catalog for drift that silently degrades matcher quality.
Catalog Hygiene card. Five bucket pills at the top, per-finding tables grouped by bucket with a one-line fix hint each.
Duplicate detectionsince v0.15.30
Groups items by normalized name (lowercase, strip punctuation). Catches Brass Elbow 1/2" vs BRASS ELBOW 1/2 as the same item.
Orphan detectionsince v0.15.30
Items never referenced in any draft within the lookback window (default 365 days). Skipped on fresh installs and for Service / NonInventory items (which don't behave like stocked SKUs).
Missing SKU flagsince v0.15.30, fixed v0.15.31
Inventory items where the QB Sku field is genuinely empty. Service items (labor, refunds) skipped — they don't have SKUs by design.
Weird pricing detectorsince v0.15.30
$0, negative, or 10× / 0.1× the same-category median price. Catches decimal-point typos like a $123 item entered as $12300.
Per-finding fix hintssince v0.15.30
Every flagged item carries a one-line operator instruction telling them exactly what to do in QuickBooks — merge, mark inactive, fix the price, fill the SKU. audit_catalog
📊 Operations Dashboard
Self-contained HTML snapshot — no server, no JS framework, opens with one command.
Dashboard header (v0.15.33). Freshness badge live-updates every minute; refresh button copies the regenerate command to clipboard.
↻ Refresh buttonsince v0.15.33
One-click copies sidequest dashboard to clipboard. Paste in terminal, reload. Works on file:// URLs via execCommand fallback.
Live freshness badgesince v0.15.33
"Generated 5 min ago" updates every minute without reload. Goes amber + bold after 1 hour so stale snapshots are impossible to miss.
Time saved estimatorsince v0.15.19
Hours saved this period × labor rate = dollars recovered. Defaults to 12 min/PO × $30/hr; both tunable per call.
KPI cardssince v0.15.19
POs processed, auto-clean → submitted rate, submitted $ value, AR open balance. All last-30-day.
Period-over-period comparisonsince v0.15.21
Last 30d vs the prior 30d for POs processed and estimates submitted, with delta arrows.
Auto-clean trend sparklinesince v0.15.22
30-day daily auto-clean rate. Hover shows the day. Variance against the 7-day moving average flagged.
Month-end forecastsince v0.15.22
Projected POs for the calendar month based on current pace. Useful for capacity planning and license-tier sizing.
Customer concentrationsince v0.15.22
Top customers as % of total $ value processed. Surfaces dependency risk before it becomes a problem.
Top items + top customerssince v0.15.21
Ranked tables — most-ordered items, biggest customers by $ volume — for the current period.
Top unmatched partssince v0.15.21
Customer part numbers that keep coming in but have no QB SKU mapping. Cross-reference these to lift auto-clean rate.
License cardsince v0.15.22
Current tier, month-to-date usage, quota remaining, days left in cycle. No more surprise quota errors.
Review queuesince v0.15.21
Drafts that need a human decision before submit — missing customer, unmatched line, price variance, low confidence. Ranked by age.
Recent activity feedsince v0.15.22
Last 10 events with relative timestamps. POs parsed, estimates submitted. Promotional false positives auto-filtered.
Raw data exportsince v0.15.19
Every metric on the page is also embedded as JSON at the bottom for export, audit, or piping into a BI tool.
💰 AR Assistant
Drafts collection follow-up emails for overdue invoices. Drafts only — operator sends.
Aged AR sweepsince v0.14
Scans every customer's open invoices, identifies overdue balances, drafts a Gmail follow-up tuned to age (gentle reminder < 30d, firm at 30-60d, demand letter > 60d). run_ar_followup_sweep
Opt-in only
AR sweep is gated behind SIDEQUEST_AR_FOLLOWUP=true in .env. Off by default so the connector never surprises operators with collection emails.
Per-customer tone control
Customer custom field overrides the default template — for VIPs you can suppress AR mode entirely, or escalate sooner.
Dashboard AR snapshot
Total open AR balance + aging buckets (current / 30 / 60 / 90+) on the dashboard so the operator sees collection exposure at a glance.
Gmail Draft only — never sent
Like every email path in SideQuest: gmail.modify scope writes Drafts only. Operator reviews and sends. We never have gmail.send permission.
📈 Reports & Analytics
Every metric behind the dashboard is also available as a structured tool call.
POs processed
Count over a time window with optional customer filter. report_pos_processed
Time saved
Hours + dollars recovered, with tunable per-PO minutes and hourly rate. report_time_saved
Match quality
Auto-clean / review / unmatched rates over a window. report_match_quality report_match_quality_by_customer
Top items
Ranked by $ volume or count, local or QB-sourced. report_top_items report_qb_top_items
Top customers
Ranked by $ volume, local or QB-sourced. report_top_customers report_qb_top_customers
Review queue
Every draft awaiting human decision, ranked by age + risk. report_review_queue
QB reports passthrough
Run any QB report (P&L, BalanceSheet, AgedReceivables, etc.) directly from a chat prompt. run_qb_report
Customer health reportsince v0.15.31
Per-customer 0-100 score with recommendations. customer_health
Catalog audit reportsince v0.15.30
Five-bucket hygiene findings with fix hints. audit_catalog
✉️ Email Workflow
Gmail integration — strictly gmail.modify scope. Drafts only, never auto-sent.
Smart label management
Configurable Gmail label for matched POs. Auto-creates if missing. Auto-applies on confidence-gated matches. auto_label_unprocessed
Mark email processed
After submit, label the source thread so it doesn't re-appear in the next inbox scan. mark_email_processed
Overnight queue processingsince v0.15.5
Runs the full scan → parse → match → label → draft loop unattended. Configured to run pre-business-hours; results land in the operator's review queue. process_overnight_queue
Customer-facing replies
Quote / order acknowledgment drafts with line items, totals, and validity dates. Always Drafts, always reviewed before send.
AR follow-up drafts
Collection emails for overdue balances, age-tuned tone. Opt-in only. See AR Assistant above.
No gmail.send permission, ever
SideQuest only requests gmail.modify from Google's OAuth flow. Even if a bug or prompt tried to send an email, the API call would fail at Google's permission boundary.
🔗 QuickBooks Integration
Read + write to QuickBooks Online via the official API. OAuth2 with self-rotating refresh tokens.
Estimate creation
Submit matched draft to QB as an Estimate (QB's sales-order surrogate). Returns the QB Estimate ID + DocNumber for audit. submit_estimate_to_qb propose_estimate
Item catalog lookup
Browse the full catalog, search by SKU or name substring. Cached locally for fast matcher operations. list_items refresh_catalog
Price updates
Update an item's unit price in QB. Hard guards against negative prices, non-numeric, empty IDs, and prices over a sanity cap. update_qb_item_price
Customer lookup
By name, by domain, or by QB ID. Used by the matcher and the AR sweep.
Open invoice queries
Pull every open invoice across all customers, or for a specific customer. Drives AR sweep and the dashboard's AR snapshot.
Discount + freight on Estimatessince v0.15.25, fixed v0.15.29
Doc-level discount excludes freight. Computed as fixed-dollar to dodge QB's percent-applies-to-whole-document quirk. Local total agrees with QB stored total to the penny.
Customer risk gate
Before submitting an Estimate, check the customer's CreditLimit vs current Balance + the proposed Estimate total. Block if it would push them over.
QB Desktop bridgesince v0.13
Optional control-plane companion app speaks to QB Desktop installations over a local socket. Same MCP surface — Claude doesn't know whether it's Online or Desktop on the other end.
🔐 Reliability & Auth
The connector self-heals, audit-logs, and surfaces problems before they bite.
Self-rotating QB refresh tokenssince v0.15.13, hardened v0.15.27
Every token rotation — ours or python-quickbooks' internal ones — persists back to .env automatically. The chain stays alive across process restarts.
Friendly auth-failure errorssince v0.15.27
Every QB tool wraps eight different auth failure markers (AuthorizationException, errorCode 003200, "Token expired", etc.) into the same actionable "run sidequest reauth-qb" message. No raw stack traces in chat.
Auth audit logsince v0.15.27
Every token rotation, persist event, and refresh failure logged to ~/.qb-distributor-mcp/auth.log with redacted token tails. Rotates at 1 MB.
Installer preserves .envsince v0.14.4
Re-running the installer keeps every existing QB credential, license tier, and custom env var. Only license bookkeeping gets rewritten.
Doctor + setup probessince v0.15.15
sidequest doctor exercises the full QB refresh chain end-to-end and prints exact reseed commands when something's broken. The same probe runs at the end of sidequest setup.
Quota with hard cutoff
License tier enforces monthly PO processing limit. Hard cutoff prevents silent overruns. Dedup on message_id means retrying the same PO doesn't double-bill.
This page is updated on every release. If you spot something missing or wrong, it's a bug — let us know via
contact or just ship a fix. The
changelog tracks the timeline; this page tracks the current state.