A Model Context Protocol server for marketing campaign automation workflows.
This server demonstrates moderate effort in tool definition but falls short of production readiness. All 4 tools have names starting with action verbs (generate, optimize, create, analyze), which is good. However, critical gaps exist: parameter descriptions in the source code are visible but schemas lack comprehensive type validation for complex nested types (Dict, List, None unions). The tools accept complex enums (MetricType, OptimizationGoal, ToneOfVoice, SegmentCriteria) that are imported but their definitions are not visible in the provided code excerpt, making it impossible to verify they are proper enums vs inferred types. Output schemas are partially documented in the model imports but not fully visible. Error handling is present via blocked_* functions (returning ExecutionStatus.BLOCKED with blocked_reason and warnings), which shows awareness of the pattern, but these are defensive fallbacks rather than actionable recovery guidance. Tool composition is reasonable, each tool has a single clear responsibility, but parameter interdependencies and constraints are not well documented (e.g., the relationship between constraints and optimization_goal in optimize_campaign_budget).
Analyze audience segments in deterministic demo mode or return a structured live-mode block.
Generate campaign copy variants through the configured AI provider or deterministic demo mode.
Generate campaign performance reports using live platform data or deterministic demo mode.
Reallocate campaign budget using live platform metrics and provider-backed optimization logic.
Complex parameter types (MetricType, OptimizationGoal, ToneOfVoice, SegmentCriteria) are referenced but their enum definitions are not visible in the provided source. Cannot verify these are properly constrained enums vs inferred types. LLMs cannot select from unknown enum values.
Parameter descriptions lack actionable constraints. E.g., 'historical_days' has no documented range (1-365?), 'max_length' for copy has no guidance on practical limits, 'min_segment_size' has no validation message if violated. LLMs cannot self-correct invalid inputs.
Output schemas are inferred from model imports (AnalyzeAudienceSegmentsOutput, etc.) but the actual field definitions are not visible in the code excerpt. Cannot verify that all required chaining IDs (e.g., campaign_id, contact_list_id) are returned for downstream tool calls.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 51 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Error responses return ExecutionStatus.BLOCKED with blocked_reason and warnings, but no recovery guidance. E.g., 'Live mode not configured' tells the LLM nothing about how to recover. Should include: 'Try running in demo mode by setting AI_DEMO_MODE=true, or configure live credentials via...'
Tool descriptions do not clearly distinguish when to call each tool vs a similar one. E.g., 'generate_campaign_report' vs 'analyze_audience_segments', when would an LLM pick one over the other? Descriptions lack 'When to use' context.
Optional parameters with complex defaults (constraints dict defaulting to {}, keywords defaulting to []) lack guidance on what happens when omitted. Does empty constraints mean no limits? Does empty keywords mean skip keyword incorporation? Undocumented defaults cause silent misuse.