Skai Reports MCP
Overview
Skai is an AI-powered omnichannel marketing platform that unifies digital advertising across retail media (Amazon, Walmart, Target, Instacart), paid search (Google), and paid social (Meta, TikTok). The Reports MCP provides tools to query marketing performance data, investigate operational changes, and analyze competitive positioning.
Available Tools
| Tool | Purpose |
|---|---|
get_today | Get today's date (YYYY-MM-DD) |
relevant_columns | Discover available columns and metadata for an entity before fetching reports |
fetch_report | Fetch marketing performance data with filtering, sorting, grouping, and period comparison |
get_change_log | Find who changed what on campaigns, ad groups, keywords, and ads |
get_competitive_context | Get client brand and competitor brand mappings (required before competitive analysis) |
Key Marketing Terms
| User says | Use this column | Group |
|---|---|---|
| Publisher / Platform (Google, Amazon) | ChannelName | ATTRIBUTES |
| Channel / Medium (Search, Social) | ChannelCategory | ATTRIBUTES |
| Spend | Cost | PERFORMANCE |
| ROAS | ROI (if ROAS unavailable) | PERFORMANCE |
| Product | Use PRODUCT_ASSET entity | — |
| Creative / Ad | Use AD entity (default) or CREATIVE_ASSET only for images/videos | — |
Entity Types
All entity names are UPPERCASE:
CAMPAIGN, ADGROUP, KEYWORD, AD, PROFILE, PRODUCT_ASSET, SEARCH_TERM, CREATIVE_ASSET, COMPETITIVE_INSIGHTS, COMPETITIVE_INSIGHTS_KEYWORD_DRILLDOWN, SOV_SEARCH_TERM, NEGATIVE_KEYWORDS
PROFILE limitation: Does NOT support group_bys. Use CAMPAIGN entity if you need segmentation.
Core Workflow
1. relevant_columns(entity) -> discover exact column names and groups
2. fetch_report(entity, fields, date_range, ...) -> get data
3. Analyze, then fetch more if neededAlways call relevant_columns first to get exact column names and groups. Column names are PascalCase (e.g., CampaignName, Clicks, AverageCPC). Every column has a group (ATTRIBUTES, PERFORMANCE, TIME_SEGMENT, DIMENSIONS, etc.) that MUST be specified.
fetch_report Reference
Parameter Structure
{
"entity": "CAMPAIGN",
"date_range": {"start_date": "2025-10-07", "end_date": "2025-10-13"},
"fields": [
{"name": "CampaignName", "group": "ATTRIBUTES"},
{"name": "Clicks", "group": "PERFORMANCE"},
{"name": "Cost", "group": "PERFORMANCE"}
],
"filters": [
{"field": "ChannelName", "operator": "IN", "values": ["Amazon", "Google"], "group": "ATTRIBUTES"}
],
"sort": {"field": "Clicks", "group": "PERFORMANCE", "order": "DESCENDING"},
"breakdown_type": "FLAT",
"limit": 20
}Critical Rules
fields— Array of{name, group}objects. Max 100 columns. Use exact names fromrelevant_columns.breakdown_type— Required."FLAT"for flat data,"GROUP"when usinggroup_bys.group_bys— Array of{name, group}objects. Max 3. Requiresbreakdown_type: "GROUP".filters— Array of{field, operator, values, group}objects. Operators:IN,EQUALS,NOT_EQUALS,GREATER_THAN,LESS_THAN,CONTAINS, etc.sort— Object:{field, group, order}. Order:"ASCENDING"or"DESCENDING".limit— Max 20,000 rows (default).
TIME_SEGMENT Rule
Time columns (DAY, Week, Month, Quarter, Year) MUST appear in BOTH fields AND group_bys:
{
"fields": [{"name": "DAY", "group": "TIME_SEGMENT"}, ...],
"group_bys": [{"name": "DAY", "group": "TIME_SEGMENT"}, ...],
"breakdown_type": "GROUP"
}Period-Over-Period Comparison
Use previous_date_range — do NOT make separate calls:
{
"entity": "CAMPAIGN",
"date_range": {"start_date": "2025-11-01", "end_date": "2025-11-30"},
"previous_date_range": {"start_date": "2025-10-01", "end_date": "2025-10-31"},
"fields": [
{"name": "CampaignName", "group": "ATTRIBUTES"},
{"name": "Revenue", "group": "PERFORMANCE"}
],
"filters": [
{"comparison_type": "PERCENTAGE_DELTA", "field": "Revenue", "group": "PERFORMANCE", "operator": "GREATER_THAN", "values": ["0.5"]}
],
"sort": {"field": "Revenue", "group": "PERFORMANCE", "order": "DESCENDING", "comparison_type": "ABSOLUTE_DELTA"},
"breakdown_type": "FLAT"
}When previous_date_range is provided, these columns are auto-generated (do NOT request them in fields):
<column>Previous— value from previous period<column>AbsoluteDelta— absolute difference<column>PercentageDelta— percentage change (as decimal, so 0.5 = 50%)
You can filter and sort on these using comparison_type: "PREVIOUS", "ABSOLUTE_DELTA", or "PERCENTAGE_DELTA".
Date Range Options
Explicit: {"start_date": "2025-01-01", "end_date": "2025-03-31"}
Preset: {"preset": "LAST_7_DAYS"} or {"preset": "THIS_MONTH", "as_of": "2025-06-15"}
Available presets: LAST_7_DAYS, THIS_MONTH, LAST_QUARTER, etc. Default if user doesn't specify a range: previous calendar week.
Composite Filters (PRODUCT_ASSET only)
Products lack direct relationship columns. Use compositeFilters to link products to other entities:
{
"compositeFilters": [
{
"entity": "PRODUCT_ASSET",
"type": "ANY_MATCH",
"filters": [
{"field": "Product Id", "operator": "EQUALS", "values": ["5678"], "group": "PRODUCT_IDENTIFIERS"}
]
}
]
}Response Structure
fetch_report returns:
records— List of data rows (limited bylimit). May be partial.summary— Aggregation across ALL matching entities (not just visible records).total— Total entity count matching filters. Use this for counts, never count visible records.- CSV download URL — Pre-signed S3 URL (expires 30 min).
get_change_log Reference
Queries Snowflake for operational changes. Supported entities: campaign, adGroup, keyword, ad (lowercase).
Filterable fields: daily_budget, budget, bid_adjustment, desktop_bid_adjustment, tablet_bid_adjustment, mobile_bid_adjustment, placements, name, status, cpa_goal.
Change operators: ADD, REMOVE, MODIFY, BID_CHANGES, UPLOAD, etc.
Returns: timestamp, username (who made change), entity details, field changes with old/new values. Default 500 rows, max 1000. Set exclude_noisy_fields=False to include sync/update noise.
get_competitive_context Reference
Must call before using COMPETITIVE_INSIGHTS entities. Returns client brands ("my brands") and competitor brand mappings per publisher.
After getting context, use the brand names to filter COMPETITIVE_INSIGHTS or COMPETITIVE_INSIGHTS_KEYWORD_DRILLDOWN entities in fetch_report.
COMPETITIVE_INSIGHTS— Brand-level share of voice (SOV). Always usebreakdown_type: "GROUP", default sort bySovAndPos, default filterPageSection="FULL_PAGE".COMPETITIVE_INSIGHTS_KEYWORD_DRILLDOWN— Product-level SOV within keywords. Despite the name, shows products not keywords. Always group byAsinAndMarketplace.SOV_SEARCH_TERM— Lists keywords/search terms used in CI. No performance data.
Best Practices
- Always start with
relevant_columnsto discover exact column names and groups. Never guess column names. - Use
previous_date_rangefor comparisons — don't make separate calls and calculate manually. - Use
group_bysinstead of fetching flat data and aggregating yourself. - Use
summaryandtotalfrom response for aggregate counts — records may be partial due to limits. - Prefer fetching more data over calculating from existing partial data.
- Parallel tool calls — when fetching multiple independent reports, call them simultaneously.
- Names verbatim — display entity names exactly as returned, without abbreviation.
- Empty results — when filtering returns
records: [], filters are too restrictive, not missing activity. Ask user to verify filter values. Do NOT suggest trying different time periods. - Date handling — always use ISO 8601 (YYYY-MM-DD). Convert user terms (e.g., "Q2 2025" = 2025-04-01 to 2025-06-30). Default to previous calendar week if unspecified.
Common Mistakes
| Mistake | Correct approach |
|---|---|
| Using lowercase entity names | Always UPPERCASE: CAMPAIGN, KEYWORD |
| Guessing column names | Call relevant_columns first |
Omitting group from fields/filters/sort | Every column reference needs {name, group} |
| Making two calls for period comparison | Use previous_date_range in single call |
Requesting delta columns in fields | They're auto-generated when previous_date_range is set |
Using breakdown_type: "FLAT" with group_bys | Must use breakdown_type: "GROUP" |
| Forgetting TIME_SEGMENT in group_bys | Time columns must be in BOTH fields AND group_bys |
| Counting visible records for totals | Use total field from response |
Using ChannelName when user means channel type | ChannelName = publisher (Google), ChannelCategory = medium (Search) |