Guide · AWS CloudWatch · Log Analysis

CloudWatch Contributor Insights for MCP Servers — Find Top-N Error Sources in Logs

CloudWatch Contributor Insights continuously evaluates rules against your CloudWatch Logs streams and produces real-time top-N reports identifying which endpoints, tool names, source IPs, or error codes are contributing the most events — without you needing to write and re-run Logs Insights queries manually. For AliveMCP probe workers that log one structured JSON record per probe result, a Contributor Insights rule can instantly surface the answer to "which MCP endpoints account for the most probe failures this hour?" — the kind of operational question that normally requires a dashboard query. For querying logs ad-hoc, see CloudWatch Logs Insights for MCP server debugging; for threshold alarms on probe metrics, see CloudWatch Alarms for MCP servers.

TL;DR

Create a Contributor Insights rule that targets your probe result log group (/mcp/probe-results), filters for error events ($.status IN ["error", "timeout", "auth_failure"]), and aggregates on the $.endpoint key. CloudWatch samples ~25% of log events (or 100% if you enable full scan) and shows a continuously updated chart of the top-100 endpoints by error count — updated every minute. You pay $0.02/hour per active rule plus $0.035 per million sampled log events.

Contributor Insights vs. Logs Insights for operational questions

Both services analyze CloudWatch Logs data, but they answer different question types:

Question typeLogs InsightsContributor Insights
Ad-hoc investigation: "what happened at 3:42 PM?"Excellent — query historical data for any time rangeNot suitable — reports only show top-N contributors, not individual events
Operational monitoring: "which endpoint is failing most right now?"Requires repeated manual queriesExcellent — continuous real-time top-N updates
Dashboard widget: "top-10 error sources this week"Can embed via metric math, but expensive at high volumeNative top-N charts embeddable in CloudWatch dashboards
Alert on a specific contributor crossing a thresholdNot possible nativelySupported via Contributor Insights metric alarms (requires full-scan mode)
Cost at 100M log events/day$0.005/GB scanned (charged per query)$0.035/million sampled events (~$3.50/day at 100M events)

For AliveMCP's probe worker logging, Contributor Insights is the right tool for the "which servers are currently flapping most?" operational dashboard — and Logs Insights is the right tool for post-incident investigation queries like "show me every probe for api.mcp-broken.com in the last 2 hours."

Rule structure

A Contributor Insights rule is a JSON document with five main fields:

{
  "Schema": {
    "Name": "CloudWatchLogRule",
    "Version": 1
  },
  "LogGroupNames": ["/mcp/probe-results"],   // up to 5 log groups
  "LogFormat": "JSON",                        // JSON or CLF (Apache access log)
  "Contribution": {
    "Keys": ["$.endpoint"],                   // group-by fields (up to 4 keys)
    "ValueOf": "$.latency_ms",                // optional: sum/max this field (omit for Count)
    "Filters": [                              // AND-combined filters
      {
        "Match": "$.status",
        "In": ["error", "timeout", "auth_failure"]
      }
    ]
  },
  "AggregateOn": "Count"                      // Count or Sum (requires ValueOf for Sum)
}

The Keys array defines the contributor identifier — CloudWatch creates one time-series per unique combination of key values. With Keys: ["$.endpoint"], each unique endpoint URL is a separate contributor. With Keys: ["$.endpoint", "$.region"], each endpoint-region pair is a contributor — useful for identifying region-specific failures on multi-region MCP deployments.

Maximum cardinality: Contributor Insights tracks up to 10,000 unique contributor values per rule per hour. For MCP endpoint monitoring with <10,000 registered servers, this limit is not a concern.

Creating rules for MCP probe logs

Assuming your probe worker writes structured JSON log lines like this to CloudWatch Logs:

// Example probe result log line (one per probe execution)
{
  "timestamp": "2026-10-31T08:00:01.234Z",
  "endpoint": "https://api.mcp-example.com/mcp",
  "server_slug": "mcp-example",
  "region": "us-east-1",
  "status": "error",
  "http_code": 503,
  "latency_ms": 8432,
  "error_class": "upstream_timeout",
  "registry": "mcp.so"
}
# Rule 1: Top endpoints by error count
aws cloudwatch put-insight-rule \
  --rule-name "mcp-top-failing-endpoints" \
  --rule-state ENABLED \
  --rule-definition '{
    "Schema": {"Name": "CloudWatchLogRule", "Version": 1},
    "LogGroupNames": ["/mcp/probe-results"],
    "LogFormat": "JSON",
    "Contribution": {
      "Keys": ["$.endpoint"],
      "Filters": [{"Match": "$.status", "In": ["error", "timeout", "auth_failure"]}]
    },
    "AggregateOn": "Count"
  }'

# Rule 2: Top endpoints by total accumulated latency (finds slow but not erroring servers)
aws cloudwatch put-insight-rule \
  --rule-name "mcp-top-slow-endpoints" \
  --rule-state ENABLED \
  --rule-definition '{
    "Schema": {"Name": "CloudWatchLogRule", "Version": 1},
    "LogGroupNames": ["/mcp/probe-results"],
    "LogFormat": "JSON",
    "Contribution": {
      "Keys": ["$.endpoint"],
      "ValueOf": "$.latency_ms",
      "Filters": [{"Match": "$.status", "NotIn": ["error"]}]
    },
    "AggregateOn": "Sum"
  }'

# Rule 3: Top error classes by registry (which MCP registry has worst server quality?)
aws cloudwatch put-insight-rule \
  --rule-name "mcp-error-class-by-registry" \
  --rule-state ENABLED \
  --rule-definition '{
    "Schema": {"Name": "CloudWatchLogRule", "Version": 1},
    "LogGroupNames": ["/mcp/probe-results"],
    "LogFormat": "JSON",
    "Contribution": {
      "Keys": ["$.registry", "$.error_class"],
      "Filters": [{"Match": "$.status", "In": ["error"]}]
    },
    "AggregateOn": "Count"
  }'

Querying rule results via API

Rule results are viewable in the CloudWatch console under "Contributor Insights," but you can also query them programmatically to feed a dashboard or build automated reports:

// Query top-10 failing endpoints for the last 1 hour
const { GetInsightRuleReportCommand } = require('@aws-sdk/client-cloudwatch');

const report = await cloudwatch.send(new GetInsightRuleReportCommand({
  RuleName: 'mcp-top-failing-endpoints',
  StartTime: new Date(Date.now() - 3600 * 1000),
  EndTime: new Date(),
  Period: 3600,         // aggregate over the full hour into one data point
  MaxContributorCount: 10,
  Metrics: ['UniqueContributors', 'MaxContributorValue', 'SampleCount', 'Sum'],
  OrderBy: 'Sum',       // sort by total error count descending
}));

report.Contributors.forEach(contributor => {
  const endpoint = contributor.Keys[0];
  const totalErrors = contributor.Approximation;
  console.log(`${endpoint}: ${totalErrors} errors in last hour`);
});

// report.AggregateValue = total errors across ALL contributors (not just top-10)
console.log('Total errors across all endpoints:', report.AggregateValue);

The Approximation field name reflects that sampled mode (default) provides statistical approximations, not exact counts. At the default 25% sampling rate, the approximation is ±15% at the 95th confidence level. For exact counts, enable full-scan mode with InsightRuleSamplingPercentage: 100 when creating the rule — this doubles the cost per log event analyzed.

Alarming on top contributor values

In full-scan mode, Contributor Insights publishes CloudWatch metric data that you can alarm on. This enables alerts like "fire if any single endpoint accounts for more than 5% of all probe errors" — a signal that a single bad actor endpoint is skewing your overall health metrics:

# Step 1: Update rule to full-scan mode to get CloudWatch metric data
aws cloudwatch put-insight-rule \
  --rule-name "mcp-top-failing-endpoints" \
  --rule-state ENABLED \
  --rule-definition '{
    "Schema": {"Name": "CloudWatchLogRule", "Version": 1},
    "LogGroupNames": ["/mcp/probe-results"],
    "LogFormat": "JSON",
    "Contribution": {
      "Keys": ["$.endpoint"],
      "Filters": [{"Match": "$.status", "In": ["error", "timeout", "auth_failure"]}]
    },
    "AggregateOn": "Count",
    "InsightRuleSamplingPercentage": 100
  }'

# Step 2: Alarm on MaxContributorValue — fires if any single endpoint spikes
# CloudWatch publishes metrics under namespace "CloudWatchLogs" for Contributor Insights rules
aws cloudwatch put-metric-alarm \
  --alarm-name "mcp-single-endpoint-error-spike" \
  --namespace "CloudWatchLogs" \
  --metric-name "MaxContributorValue" \
  --dimensions Name=RuleName,Value=mcp-top-failing-endpoints \
  --statistic Maximum \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 100 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:mcp-alerts

Sampling vs. full-scan cost analysis

ModeAccuracyCost per million log eventsUse case
Sampled (default, 25%)~±15% for high-volume contributors; good for top-10 trends$0.035 (~$0.00875 for 25% sample)Operational dashboard, rough top-N identification
Full scan (100%)Exact counts$0.07Alarming on exact contributor values; compliance reporting; exact audits

At 50M probe log events per day (AliveMCP scale at ~580 probes/second across 2,000 endpoints), sampled mode costs approximately $0.00875 × 50 = $0.44/day per rule, or $13/month. Full-scan doubles this to $26/month per rule. For a 3-rule setup, expect $39–$78/month — modest for the operational visibility gained.

Failure modes

SymptomCauseFix
Rule shows no contributors; rule state is ENABLEDLog group name is wrong, log group has no events in the selected time window, or the JSON filter path ($.status) does not match the actual log line structureVerify log group name with aws logs describe-log-groups; test filter path with aws logs filter-log-events --log-group-name ... --filter-pattern '{ $.status = "error" }'
Contributor Insights rule rejects JSON definition at creationEmbedded JSON rule definition needs escaping when passed as a CLI string; $. paths with array indexing or bracket notation may not be supportedSave the rule definition to a file and pass via --rule-definition file://rule.json; test rule definition syntax in the CloudWatch console before automating
Top-N chart shows endpoints but counts look too lowSampled mode is active (default 25%); reported counts are approximations scaled from the sampleExpected behavior for sampled mode; switch to full-scan (InsightRuleSamplingPercentage: 100) for exact counts if accuracy is critical
CloudWatch Logs / namespace metrics not available for alarmingMetrics are only published by Contributor Insights rules in full-scan mode; sampled rules do not emit CloudWatch metricsUpdate rule to full-scan mode; allow 5–10 minutes for metrics to start appearing after mode change
Rule exceeds 10,000 unique contributors per hourHigh-cardinality key combination (e.g., endpoint + request ID) or legitimate explosion in unique endpointsRemove high-cardinality fields from the Keys array; use bounded keys like server registry, error class, or region instead of per-request fields