MCP server for performance marketing workflows, enabling agents to manage ad campaigns, performance analytics, keywords, ad copy, and budgets across multiple advertising platforms
This server has severe definition quality issues across nearly all dimensions. Tool definitions are inferred from shell scripts (scripts/validate.sh) and markdown files rather than from actual source code or explicit schema registration. No JSON schemas are visible. Descriptions are minimal or absent from the schema perspective. All 16 tools lack verifiable input/output schemas in the source code provided. The repository appears to be a plugin installer/configuration framework rather than a functioning MCP server with proper tool definitions.
Tools (16)
add_meta_ad_setwriteauth32/100
Routed tool for adding ad sets to Meta (Facebook/Instagram) campaigns (requires router via list_tools)
audit_conversion_trackingread onlyauth35/100
Audits and validates conversion tracking setup across advertising platforms
create_search_campaignwriteauth32/100
Routed tool for creating search advertising campaigns (requires router via list_tools)
echo_testread only30/100
Test tool for verifying Adspirer MCP server connectivity
NO INPUT SCHEMAS VISIBLE: All 16 tools lack verifiable JSON Schema definitions in the source code. Tool definitions are inferred from validate.sh and markdown files, not from explicit MCP server code. This violates the hard scoring rule: if no input schema is visible, schema score MUST be 0.
INFERRED TOOL DEFINITIONS: Tools are documented in shell scripts and markdown (shared/commands/*.md, scripts/validate.sh) rather than registered in actual MCP server code.
Recommendations
IMMEDIATELY: Provide actual MCP server implementation code (Python/TypeScript/Go). The current repo is a shell-script installer and plugin configuration framework, not a functional MCP server. Until there is explicit tool registration with JSON schemas, no scoring above 50 is justifiable.
ADD COMPLETE JSON SCHEMAS: For each tool, define input_schema and output_schema in proper JSON Schema format. Include 'type', 'required', 'properties', and per-property descriptions. Example for get_campaign_performance: {"type": "object", "properties": {"campaign_id": {"type": "string", "description": "The ID of the campaign to fetch (obtain from search_campaigns or get_campaigns first)"}, "platform": {"type": "string", "enum": ["meta", "google", "linkedin"], "description": "The advertising platform"}, "date_range_days": {"type": "integer", "minimum": 1, "maximum": 365, "description": "Number of days of historical data to retrieve (default 30)"}}, "required": ["campaign_id", "platform"]}.
EXPAND DESCRIPTIONS TO 50 - 200 CHARACTERS: Rewrite all tool descriptions to answer WHAT, WHEN, and PREREQUISITES. Example: 'Retrieve performance metrics (impressions, clicks, spend, conversions) for an advertising campaign across all platforms. Call search_campaigns first to find campaign IDs. Returns aggregated daily metrics with optional filtering by date range.' Current descriptions lack this guidance.
CONSOLIDATE PLATFORM-SPECIFIC TOOLS: Replace 'get_meta_campaign_performance', 'get_linkedin_campaign_performance', etc. with a single 'get_campaign_performance' tool that accepts a 'platform' enum parameter (meta|linkedin|tiktok|amazon|google_ads|chatgpt). This reduces LLM reasoning waste and makes the API more composable. Each platform can have specialized tools only where the API surface truly differs.
Score history
Overall score trend
First recorded score · v2 rubric
37/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-21
F
37
2026-07-28+
v2
get_connections_status
read onlyauth32/100
Checks the authentication and connection status of linked advertising platform accounts
MISSING PARAMETER DESCRIPTIONS: No visible parameter schemas with descriptions. Tools like 'get_campaign_performance' and 'create_search_campaign' have no documented input parameters or constraints (e.g. campaign_id format, required fields, enum values).
NO OUTPUT SCHEMAS: Tool responses are undocumented. Agents cannot infer what fields to expect from 'get_campaign_performance' (does it return metrics, budget, status?) or 'get_connections_status' (account status, connection state, credentials?). Per pattern:tool, output schemas must be documented.
GENERIC/MINIMAL DESCRIPTIONS: Tool descriptions are 15 - 40 characters (far below the 50 - 200 baseline for good LLM-optimized descriptions). E.g. 'Entry point for Adspirer setup; directs users through initial configuration' (start_here, ~75 chars after concatenation) lacks specifics on what 'initial configuration' entails.
NO ERROR HANDLING GUIDANCE: No visible error responses, recovery hints, or actionable error messages. If a 'switch_primary_account' call fails (e.g. invalid account ID), the LLM receives no guidance on what to do next (retry? ask user? check status?). Per pattern:recovery-guide, error responses must tell the agent what to do next.
MISSING IDEMPOTENCY & CONFIRMATION FOR DESTRUCTIVE OPERATIONS: 'switch_primary_account' (WRITE) and 'create_search_campaign' (WRITE) have no documented confirmation flow or idempotency guarantees. Per pattern:confirmation-request, irreversible operations should support dry-run or confirmation. Per pattern:idempotent-operation, agents need to know if repeated calls with the same input produce the same result or cause duplicate side effects.
NO PAGINATION SUPPORT DOCUMENTED: Tools like 'get_campaign_performance' and audit results likely return lists but have no documented limit, offset, page_size, or next_cursor parameters. Per pattern:paginated-result, list-returning tools must support pagination to avoid context window exhaustion.
MISSING TOOL-CHAINING REFERENCES: No documented response fields that enable downstream tool calls. E.g. if 'get_campaign_performance' returns campaign data, does it include 'campaign_id' so 'create_search_campaign' can reference it? Per pattern:tool-chain, output must contain the IDs and references downstream tools need.
NO RESOURCE FIELD NAMING STANDARDIZATION: Tool parameters and responses lack consistency. No evidence of which tools accept 'account_id' vs 'account' vs 'account_name', or which return 'status' vs 'connection_status' vs 'auth_status'. Per pattern:tool, mismatched naming forces LLMs to guess at field mappings, increasing errors.
PLATFORM-SPECIFIC TOOLS NOT DIFFERENTIATED BY PARAMETER: Tools like 'get_meta_campaign_performance', 'get_linkedin_campaign_performance', 'get_tiktok_campaign_performance', 'get_amazon_campaign_performance' are separate tools for what could be a single parameterized 'get_campaign_performance' with a 'platform' enum parameter. This violates pattern:tool (avoid multiple tools that do the same thing differently). Causes LLM reasoning waste and increases hallucination risk.
DOCUMENT ALL PARAMETER CONSTRAINTS: For every parameter, specify type, format, allowed values (enum), min/max for numbers, length limits for strings, and regex patterns if applicable. Example: 'account_id (string, 2-50 alphanumeric chars, required): The primary advertising account ID from get_connections_status or switch_primary_account history.'
ADD PAGINATION PARAMETERS & LIMITS: For list-returning tools (search_tools, get_campaign_performance, audit_conversion_tracking), add 'limit' (default 20, max 100) and 'offset' or 'cursor' parameters. Document the response structure (total_count, next_cursor, items array). Cap default results at 20 - 50 items to avoid context window exhaustion.
DOCUMENT OUTPUT SCHEMAS WITH EXAMPLES: For each tool, specify the response structure. Example for get_campaign_performance: "Returns an object with keys: { campaign_id, campaign_name, platform, date_range, metrics: { impressions, clicks, spend_usd, conversions, ctr_percent, cpc_usd }, status_code (200|404|500), error_message (if applicable) }. Dates are ISO 8601 strings."
ADD ERROR HANDLING WITH RECOVERY HINTS: Every tool should document common error cases and recovery actions. Example for switch_primary_account: 'Error 404 (Account not found): Call get_connections_status to list available accounts and verify the account_id. Error 403 (Permission denied): Verify your Adspirer authentication is current (recent login within 24 hours).'
ADD IDEMPOTENCY & DRY-RUN DECLARATIONS: For WRITE tools (switch_primary_account, create_search_campaign, add_meta_ad_set), document whether repeated calls with identical parameters produce the same result (idempotent) or cause duplicate side effects (non-idempotent). Add a 'dry_run' boolean parameter (default false) to support confirmation workflows: 'Set dry_run=true to preview the operation without committing changes.'
ADD TOOL ANNOTATIONS: Use MCP tool annotations to declare read-only vs destructive semantics. Example: 'get_campaign_performance' should have readOnlyHint=true. 'switch_primary_account' and 'create_search_campaign' should have destructiveHint=true. These guide agents toward safer behavior and improve tooling.
STANDARDIZE FIELD NAMING: Use consistent suffixes for ID fields (_id), enum fields (_type, _status), and text fields (_name, _text). Document the resource naming convention in a server README. Example: campaign_id (not campaign, not campaign.id), platform_type (not platform), connection_status (not status or auth_status).
CREATE A DISCOVERY TOOL: Provide a 'get_server_schema' or 'describe_all_tools' endpoint that returns a comprehensive inventory of all available tools with their input/output schemas in a machine-readable format. This enables agents to self-discover and adapt to API changes.
IMPLEMENT RATE LIMITING & TIMEOUT HINTS: Document per-tool rate limits (calls per minute) and timeout expectations (typical response time). Example: 'get_campaign_performance typically returns in 2 - 5 seconds. Rate limit: 100 calls/minute per account. If you hit the rate limit, wait 60 seconds before retrying.'
ADD PERMISSION SCOPE DECLARATIONS: Document what permissions each tool requires. Example: 'get_campaign_performance requires read:campaigns scope. switch_primary_account requires write:account_settings. This enables least-privilege agent configuration.'
PROVIDE EXAMPLES IN PARAMETER DESCRIPTIONS: Use enum values and regex patterns instead of prose examples. E.g., instead of 'e.g. 2024-01-15', use 'ISO 8601 date string (format: YYYY-MM-DD)'. Agents frequently misinterpret prose examples as the only valid values.