| name | sales-analytics |
| description | Answer questions about monthly sales performance from the local sales database. Query revenue, deals, and gross margin by year/region/segment; detect significant revenue drops; escalate anomalies for human review. Keywords: sales, revenue, deals, margin, anomaly, region, segment, enterprise, mid-market, EMEA, North America, monthly performance. |
| license | MIT |
| metadata | {"author":"Leandro Pessini","version":"0.1.0"} |
Sales Analytics
Overview
This skill helps the agent answer natural-language questions about monthly sales performance and flag anomalies for human review. All data lives in a local SQLite database surfaced through MCP tools — never invent numbers, always query.
Use this skill when the user asks about:
- Monthly revenue, deal counts, or gross margin
- Trends across a region (e.g. EMEA, North America) or segment (e.g. Enterprise, Mid-Market)
- Anomalies, drops, or unusual months
- Comparisons across regions or segments
Do not use this skill for:
- Forecasting (the data is historical only)
- Customer-level detail (the database is monthly aggregate)
- Anything outside the calendar year(s) seeded in the database
Available tools
These tools come from the sales_db MCP server, declared via EXTERNAL_MCP_SERVERS_JSON at agent boot:
query_monthly_sales(year, region, segment) — returns rows with month, month_num, region, segment, revenue, deals, gross_margin. Always pass year (default 2025); region and segment are optional.
list_regions() / list_segments() — enumerate the distinct values in the database. Call these when you're unsure whether the user's region/segment string is valid before passing it to query_monthly_sales.
detect_revenue_anomalies(monthly_sales, threshold=0.18) — flags months whose revenue dropped by more than threshold versus the previous month. Pass the list returned by query_monthly_sales as the monthly_sales argument; the tool is stateless and cannot see prior tool results. Returns [] when no anomaly is found.
You also have access to:
request_human_review(title, summary, options_json, payload_json) — pause execution and surface a decision card to the human operator. Use ONLY in the conditions described under Anomaly escalation below.
Standard workflow
For every sales question, follow this sequence. Do not skip steps.
- Validate filters. If the user mentions a region or segment that you're not certain matches the database, call
list_regions() and/or list_segments() first. Spell the values back to the user exactly as the database has them.
- Query. Call
query_monthly_sales(year, region, segment) with the validated filters. If the user did not specify a region/segment, call without those args to return all rows.
- Analyze for anomalies. Pass the list returned by step 2 to
detect_revenue_anomalies(monthly_sales=...) (default threshold 0.18). This is mandatory whenever the user asks for trends, performance, or "show me X" — anomalies should always be surfaced even when not explicitly requested.
- Compose the response — BEFORE escalating. Emit a short 2–3 sentence prose summary as a regular assistant message before you call
request_human_review. Mention the highest and lowest months, and any anomaly. Keep it skimmable — this becomes the lead paragraph at the top of the dashboard. Do not include bullet lists, headings, or a long analysis here; the long follow-up belongs to the post-resume turn (see Anomaly escalation). The UI will render charts from your query_monthly_sales tool result automatically — do not try to ASCII-draw charts in your response.
- Escalate if anomaly found. See Anomaly escalation below.
Anomaly escalation
When detect_revenue_anomalies returns a non-empty list, call request_human_review with the following arguments:
title: A short label, e.g. "Revenue anomaly review".
summary: One sentence describing the anomaly. Use the message field from the first anomaly verbatim, or paraphrase it. Example: "Revenue dropped 30.8% from Aug ($172,000) to Sep ($119,000) in North America Enterprise."
options_json: A JSON-encoded list with exactly two options:
[
{"value": "investigate", "label": "Investigate", "variant": "default"},
{"value": "dismiss", "label": "Dismiss", "variant": "outline"}
]
payload_json: A JSON-encoded dict carrying the first anomaly object (the dict from detect_revenue_anomalies). The UI uses this to render the anomaly metric cards.
Wait for the response. The graph pauses until the human responds; the tool returns a JSON-encoded ReviewDecision. Parse it:
-
If value == "investigate": produce a follow-up message proposing concrete next steps. Format it with markdown so the dashboard renders it as a structured plan rather than a paragraph blob:
- Use
## Section headings (e.g. ## What I did, ## Findings, ## Recommended next steps).
- Use
- bulleted lists for findings and one-off items.
- Use
1. 2. 3. numbered lists for ordered steps.
- Keep paragraphs short. Blank line between sections.
Do not call any more tools — the response message is the final word for this turn.
-
If value == "dismiss": acknowledge briefly ("Dismissed — no further action.") and stop. No markdown needed for dismiss.
Do not call request_human_review more than once per conversation turn.
Examples
User: Show me 2025 enterprise sales and investigate any anomalies.
Plan:
- Call
query_monthly_sales(year=2025, segment="Enterprise").
- Call
detect_revenue_anomalies(monthly_sales=<step 1 result>) — finds the Aug→Sep drop.
- Compose a 2-sentence summary.
- Call
request_human_review with the Aug→Sep anomaly as payload.
User: How are EMEA Mid-Market sales doing this year?
Plan:
- Call
list_regions() to confirm "EMEA" is the right spelling — it is.
- Call
query_monthly_sales(year=2025, region="EMEA", segment="Mid-Market").
- Call
detect_revenue_anomalies(monthly_sales=<step 2 result>) — returns []. No escalation.
- Compose a 2-sentence trend summary.
User: Compare North America and EMEA enterprise revenue.
Plan:
- Call
query_monthly_sales(year=2025, segment="Enterprise") once (returns both regions; the rows include a region field).
- Call
detect_revenue_anomalies(monthly_sales=<step 1 result>) — note that the function compares consecutive rows, so when both regions are mixed it may produce noisy results. For comparisons, prefer to call it once per region's slice if the result looks suspect.
- Compose a 2–3 sentence comparison.
- Escalate only if a clear anomaly emerges from one of the per-region slices.
Things to avoid
- Never invent data. If
query_monthly_sales returns [], say so plainly — don't fabricate plausible-looking rows.
- Never escalate without an anomaly.
request_human_review interrupts the user's flow. Only call it when detect_revenue_anomalies actually returned something.
- Never describe a chart in prose. The UI builds charts from your tool result automatically. Repeating the data in text is wasted tokens.