Baseline
Establishes the X% commitment baseline. Three gates must pass before a commitment-grade configuration runs:
- Reporter age — at least 7 days of metrics (avoids cold-start noise)
- Coverage — observed GB/day ≥ 80% of stated daily volume when supplied
- Anomaly window — no single day > 4× rolling 7-day median in the lookback window
When all gates pass, returns: current monthly spend, no-action 90d projection, top-10 contributing patterns, and a recommended_target_range band derived from the compactable share.
When a gate fails, returns status: 'not_ready' with not_ready_reason and a remediation string.
Example
You
baseline on splunk
Log10x
Baseline ready: target band 25-55% (expected 40%) · 18.2 GB/day p50 · $2,730/mo current, $3,120/mo projected 90d no-action.
More to ask
- "baseline with 90d window"
- "baseline, our Splunk rate is $0.42/GB"
- "baseline — we ingest 30 GB/day, confirm coverage"
Prerequisites
Reporter deployed with at least 7 days of metrics.
Schema and samples
Input schema
Agent-facing JSON Schema (the canonical shape the MCP server publishes via tools/list):
{
"type": "object",
"properties": {
"horizon": {
"type": "string",
"enum": [
"30d",
"90d"
],
"default": "30d",
"description": "Lookback window for the baseline. 30d is the default and what `recommended_target_range` is calibrated against; 90d trades freshness for stability on lower-volume tenants."
},
"destination": {
"type": "string",
"enum": [
"splunk",
"datadog",
"elasticsearch",
"clickhouse",
"cloudwatch",
"azure-monitor",
"gcp-logging",
"sumo"
],
"description": "Destination SIEM. Required to project dollar baselines and decide which top contributors are compactable. Auto-detected from `env.analyzer` when omitted; falls back to `not_ready/no_destination` if neither is available."
},
"statedDailyGb": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Customer-stated daily SIEM ingest in GB. When supplied, the coverage gate compares observed bytes against this number; ≥80% passes, <80% returns `not_ready/coverage_low`. Omit to skip the coverage gate (the result still surfaces observed coverage as informational)."
},
"effectiveIngestPerGb": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Customer-negotiated $/GB for the destination. When supplied, baseline dollar projections use this rate and `rate_source` resolves to `customer_supplied`. Omit to fall back to vendors.json list pricing for the resolved destination (`rate_source: list_price`); omit BOTH this and `destination` to get a percent-first envelope (`rate_source: unset`, dollar fields null)."
},
"environment": {
"type": "string",
"description": "Environment nickname for multi-env setups."
},
"view": {
"type": "string",
"const": "summary",
"default": "summary",
"description": "Output format. Always \"summary\" — the typed envelope. Field retained for backward-compat with callers that still pass `view: \"summary\"`."
}
},
"additionalProperties": false
}
Source: src/tools/baseline.ts.
Output schema
The data block inside the StructuredOutput envelope:
interface ToolData {
status: 'ready' | 'not_ready';
not_ready_reason?: 'reporter_too_new' | 'coverage_low' | 'anomaly_window' | 'no_destination' | 'no_data';
reporter_age_days: number;
coverage_pct: number;
destination: string | null;
horizon: '30d' | '90d';
rate_source: 'list_price' | 'customer_supplied' | 'unset';
current: {
bytes_window: number;
bytes_per_day_p50: number;
bytes_per_day_p90: number;
monthly_usd: number | null;
};
projection_no_action_90d: {
monthly_usd_in_90d: number | null;
growth_pct: number;
};
top_contributors: Array<{
pattern_hash: string;
pattern: string;
service: string;
severity: string;
share_pct: number;
monthly_usd: number | null;
avg_event_size_bytes: number;
compactable: boolean;
}>;
recommended_target_range?: { low_pct: number; expected_pct: number; high_pct: number };
remediation?: string;
}
Envelope-level fields: summary.headline, actions[], schema_epoch.