{
    "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
    "name": "com.plainrouter/mcp",
    "version": "1.0",
    "serverUrl": "https://plainrouter.com/mcp",
    "protocolVersion": "2026-07-28",
    "serverInfo": {
        "name": "Plainrouter",
        "title": "Plainrouter MCP Server",
        "version": "0.4.0"
    },
    "description": "Inspect Meta account and signal data; propose changes with approval for supported creative work.",
    "documentationUrl": "https://plainrouter.com/quickstart-mcp.md",
    "transport": {
        "type": "streamable-http",
        "endpoint": "https://plainrouter.com/mcp"
    },
    "remotes": [
        {
            "type": "streamable-http",
            "url": "https://plainrouter.com/mcp"
        },
        {
            "type": "streamable-http",
            "url": "https://plainrouter.com/mcp/sandbox"
        }
    ],
    "capabilities": {
        "tools": {
            "listChanged": false
        },
        "resources": {
            "listChanged": false
        },
        "extensions": {
            "io.modelcontextprotocol/ui": {}
        }
    },
    "authentication": {
        "required": true,
        "schemes": [
            "bearer",
            "oauth2"
        ]
    },
    "instructions": "Use Plainrouter to work with the single advertising account approved by the human user. Start with get_account_state. get_signal_health is diagnostic only and is not evidence for spend-affecting proposals; use get_performance as the admissible source for stored reconciliation-derived performance evidence. Budget and status proposals are recommendations only; their execution is disabled in this release. Supported JPEG/PNG uploads and paused ad copies require human approval in every execution mode and pass workspace policy checks. Suggest-only approval never executes them. Creative proposals use the approved account library, and every new ad is created paused; no activation action is exposed.",
    "tools": [
        {
            "name": "get_account_state",
            "title": "Get Account State",
            "description": "Return the authorized advertising account, workspace, connection, Signal destination, and currently available read-only capabilities.",
            "inputSchema": {
                "type": "object",
                "properties": {}
            },
            "annotations": {
                "readOnlyHint": true,
                "idempotentHint": true
            },
            "_meta": {
                "ui": {
                    "resourceUri": "ui://resources/account-state-app",
                    "visibility": [
                        "model",
                        "app"
                    ]
                }
            }
        },
        {
            "name": "get_signal_health",
            "title": "Get Signal Health",
            "description": "Diagnostic view of first-party event flow, Meta delivery outcomes, match quality, and reconciliation gaps from Plainrouter stored measurements. Not admissible evidence for spend-affecting proposals. Does not call the Marketing API.",
            "inputSchema": {
                "properties": {
                    "days": {
                        "description": "Trailing window in days. One of 7, 30, 90.",
                        "default": 7,
                        "enum": [
                            7,
                            30,
                            90
                        ],
                        "minimum": 7,
                        "maximum": 90,
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "annotations": {
                "readOnlyHint": true,
                "idempotentHint": true
            }
        },
        {
            "name": "get_performance",
            "title": "Get Performance",
            "description": "Admissible proposal evidence comparing Meta-reported conversions with gateway-verified accepted conversions, plus the latest stored daily Meta spend and delivery metrics.",
            "inputSchema": {
                "properties": {
                    "days": {
                        "description": "Number of reporting days to compare, from 1 to 90.",
                        "default": 7,
                        "minimum": 1,
                        "maximum": 90,
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "annotations": {
                "readOnlyHint": true,
                "idempotentHint": true
            }
        },
        {
            "name": "verify_signal_ingestion",
            "title": "Verify Signal Ingestion",
            "description": "Verify server-side Signal ingestion by writing one idempotent, identity-free modeled event for the authorized workspace. This confirms ledger receipt but does not count as real arrival evidence or complete onboarding. No spend capability.",
            "inputSchema": {
                "type": "object",
                "properties": {}
            },
            "annotations": {
                "idempotentHint": true
            }
        },
        {
            "name": "propose-actions",
            "title": "Propose Actions",
            "description": "Propose a batch of budget, status, upload, or creative-duplication actions for the approved ad account. Budget and status proposals are recommendations only; their execution is disabled in this release. Supported JPEG/PNG uploads and paused ad copies require human approval and workspace policy checks. Suggest-only approval never executes them.",
            "inputSchema": {
                "properties": {
                    "actions": {
                        "description": "One to twenty-five typed action objects.",
                        "minItems": 1,
                        "maxItems": 25,
                        "items": {
                            "anyOf": [
                                {
                                    "additionalProperties": false,
                                    "properties": {
                                        "type": {
                                            "description": "Action type.",
                                            "enum": [
                                                "adjust_budget"
                                            ],
                                            "type": "string"
                                        },
                                        "target_entity": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "type": {
                                                    "enum": [
                                                        "ad_account",
                                                        "campaign",
                                                        "ad_set",
                                                        "ad"
                                                    ],
                                                    "type": "string"
                                                },
                                                "id": {
                                                    "description": "Platform-native entity ID.",
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "description": "Optional human-readable entity name.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "type",
                                                "id"
                                            ]
                                        },
                                        "params": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "new_daily_budget_minor": {
                                                    "description": "New daily budget in the account currency minor unit.",
                                                    "minimum": 1,
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "new_daily_budget_minor"
                                            ]
                                        },
                                        "rationale": {
                                            "description": "Plain-language reason and expected outcome for this action.",
                                            "type": "string"
                                        }
                                    },
                                    "type": "object",
                                    "required": [
                                        "type",
                                        "target_entity",
                                        "params",
                                        "rationale"
                                    ]
                                },
                                {
                                    "additionalProperties": false,
                                    "properties": {
                                        "type": {
                                            "description": "Action type.",
                                            "enum": [
                                                "set_status"
                                            ],
                                            "type": "string"
                                        },
                                        "target_entity": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "type": {
                                                    "enum": [
                                                        "ad_account",
                                                        "campaign",
                                                        "ad_set",
                                                        "ad"
                                                    ],
                                                    "type": "string"
                                                },
                                                "id": {
                                                    "description": "Platform-native entity ID.",
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "description": "Optional human-readable entity name.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "type",
                                                "id"
                                            ]
                                        },
                                        "params": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "status": {
                                                    "description": "New delivery status.",
                                                    "enum": [
                                                        "active",
                                                        "paused"
                                                    ],
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "status"
                                            ]
                                        },
                                        "rationale": {
                                            "description": "Plain-language reason and expected outcome for this action.",
                                            "type": "string"
                                        }
                                    },
                                    "type": "object",
                                    "required": [
                                        "type",
                                        "target_entity",
                                        "params",
                                        "rationale"
                                    ]
                                },
                                {
                                    "additionalProperties": false,
                                    "properties": {
                                        "type": {
                                            "description": "Action type.",
                                            "enum": [
                                                "duplicate_ad_with_creative"
                                            ],
                                            "type": "string"
                                        },
                                        "target_entity": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "type": {
                                                    "enum": [
                                                        "ad_account",
                                                        "campaign",
                                                        "ad_set",
                                                        "ad"
                                                    ],
                                                    "type": "string"
                                                },
                                                "id": {
                                                    "description": "Platform-native entity ID.",
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "description": "Optional human-readable entity name.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "type",
                                                "id"
                                            ]
                                        },
                                        "params": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "asset_id": {
                                                    "description": "Creative-library asset reference.",
                                                    "type": "string"
                                                },
                                                "status": {
                                                    "description": "Required paused delivery status for the new ad.",
                                                    "enum": [
                                                        "paused"
                                                    ],
                                                    "type": "string"
                                                },
                                                "name_suffix": {
                                                    "description": "Optional suffix for the duplicated ad name.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "asset_id",
                                                "status"
                                            ]
                                        },
                                        "rationale": {
                                            "description": "Plain-language reason and expected outcome for this action.",
                                            "type": "string"
                                        }
                                    },
                                    "type": "object",
                                    "required": [
                                        "type",
                                        "target_entity",
                                        "params",
                                        "rationale"
                                    ]
                                },
                                {
                                    "additionalProperties": false,
                                    "properties": {
                                        "type": {
                                            "description": "Action type.",
                                            "enum": [
                                                "upload_asset"
                                            ],
                                            "type": "string"
                                        },
                                        "target_entity": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "type": {
                                                    "enum": [
                                                        "ad_account",
                                                        "campaign",
                                                        "ad_set",
                                                        "ad"
                                                    ],
                                                    "type": "string"
                                                },
                                                "id": {
                                                    "description": "Platform-native entity ID.",
                                                    "type": "string"
                                                },
                                                "name": {
                                                    "description": "Optional human-readable entity name.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "type",
                                                "id"
                                            ]
                                        },
                                        "params": {
                                            "additionalProperties": false,
                                            "properties": {
                                                "staged_asset_id": {
                                                    "description": "Durable staged asset reference.",
                                                    "type": "string"
                                                },
                                                "asset_type": {
                                                    "description": "Creative type.",
                                                    "enum": [
                                                        "image",
                                                        "video"
                                                    ],
                                                    "type": "string"
                                                },
                                                "filename": {
                                                    "description": "Original staged filename.",
                                                    "type": "string"
                                                },
                                                "content_sha256": {
                                                    "description": "Content digest.",
                                                    "pattern": "^[a-f0-9]{64}$",
                                                    "type": "string"
                                                },
                                                "mime_type": {
                                                    "description": "Detected MIME type for a staged upload.",
                                                    "type": "string"
                                                },
                                                "size_bytes": {
                                                    "description": "Staged asset size in bytes.",
                                                    "minimum": 1,
                                                    "type": "integer"
                                                }
                                            },
                                            "type": "object",
                                            "required": [
                                                "staged_asset_id",
                                                "asset_type",
                                                "filename",
                                                "content_sha256"
                                            ]
                                        },
                                        "rationale": {
                                            "description": "Plain-language reason and expected outcome for this action.",
                                            "type": "string"
                                        }
                                    },
                                    "type": "object",
                                    "required": [
                                        "type",
                                        "target_entity",
                                        "params",
                                        "rationale"
                                    ]
                                }
                            ]
                        },
                        "type": "array"
                    },
                    "rationale": {
                        "description": "Why this batch should be considered together.",
                        "type": "string"
                    },
                    "idempotency_key": {
                        "description": "Stable key reused when retrying the same proposal.",
                        "type": "string"
                    },
                    "evidence": {
                        "description": "One to three approved server-re-read evidence citations; action-bound sources require action_index.",
                        "minItems": 1,
                        "maxItems": 3,
                        "items": {
                            "additionalProperties": false,
                            "properties": {
                                "source_tool": {
                                    "description": "Read tool that returned the cited evidence.",
                                    "enum": [
                                        "get_account_state",
                                        "get_signal_health",
                                        "get_performance",
                                        "get-creative-library",
                                        "staged-asset-manifest"
                                    ],
                                    "type": "string"
                                },
                                "fields_used": {
                                    "description": "Exact dot-paths from the cited tool response used in the rationale.",
                                    "minItems": 1,
                                    "maxItems": 50,
                                    "items": {
                                        "type": "string"
                                    },
                                    "type": "array"
                                },
                                "action_index": {
                                    "description": "Required action-array index for an action-bound evidence source.",
                                    "minimum": 0,
                                    "type": "integer"
                                }
                            },
                            "type": "object",
                            "required": [
                                "source_tool",
                                "fields_used"
                            ]
                        },
                        "type": "array"
                    },
                    "target_source": {
                        "description": "How the target was selected. Human-supplied establishes selection only, never current target state.",
                        "enum": [
                            "human_supplied"
                        ],
                        "type": "string"
                    }
                },
                "type": "object",
                "required": [
                    "actions",
                    "rationale",
                    "idempotency_key",
                    "evidence",
                    "target_source"
                ]
            },
            "annotations": {
                "idempotentHint": true
            }
        },
        {
            "name": "get-creative-library",
            "title": "Get Creative Library",
            "description": "Return Meta image and video assets with the ads and last-30-day performance historically associated with each asset.",
            "inputSchema": {
                "properties": {
                    "asset_type": {
                        "description": "Limit results to images or videos. Defaults to all.",
                        "default": "all",
                        "enum": [
                            "all",
                            "image",
                            "video"
                        ],
                        "type": "string"
                    },
                    "limit": {
                        "description": "Maximum assets returned per requested asset type.",
                        "default": 25,
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer"
                    },
                    "cursor": {
                        "description": "Opaque Meta cursor returned by a previous call.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "annotations": {
                "readOnlyHint": true,
                "openWorldHint": true
            }
        },
        {
            "name": "upload-asset",
            "title": "Upload Asset",
            "description": "Stage a JPEG/PNG image and submit a canonical upload action through the policy and approval gate.",
            "inputSchema": {
                "properties": {
                    "asset_type": {
                        "description": "The creative asset type. M2 supports images only.",
                        "enum": [
                            "image"
                        ],
                        "type": "string"
                    },
                    "filename": {
                        "description": "Bare filename with a matching .jpg, .jpeg, or .png extension, such as spring-hero.jpg. Path separators are rejected: send a name, not a path. The asset is never written to a filesystem path built from this value.",
                        "maxLength": 100,
                        "type": "string"
                    },
                    "content_base64": {
                        "description": "Raw base64 content for image uploads. Do not use a data URI prefix.",
                        "type": "string"
                    },
                    "rationale": {
                        "description": "Why this asset should be added to the creative library.",
                        "minLength": 1,
                        "maxLength": 1000,
                        "type": "string"
                    },
                    "idempotency_key": {
                        "description": "Stable key reused when retrying this upload proposal.",
                        "maxLength": 64,
                        "type": "string"
                    }
                },
                "type": "object",
                "required": [
                    "asset_type",
                    "filename",
                    "rationale",
                    "idempotency_key"
                ]
            },
            "annotations": {
                "readOnlyHint": false,
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true
            }
        },
        {
            "name": "duplicate-ad-with-creative",
            "title": "Duplicate Ad With Creative",
            "description": "Submit a canonical proposal to duplicate a source Meta ad with a different creative asset. Approved copies are always created PAUSED.",
            "inputSchema": {
                "properties": {
                    "source_ad": {
                        "description": "Numeric Meta ID of the ad to duplicate.",
                        "pattern": "^\\d+$",
                        "type": "string"
                    },
                    "asset_id": {
                        "description": "Asset ID returned by upload-asset or get-creative-library.",
                        "pattern": "^(image|video):.+$",
                        "type": "string"
                    },
                    "rationale": {
                        "description": "Why this new creative variant should be created.",
                        "minLength": 1,
                        "maxLength": 1000,
                        "type": "string"
                    },
                    "name_suffix": {
                        "description": "Optional suffix for the copied ad name.",
                        "maxLength": 100,
                        "type": "string"
                    },
                    "idempotency_key": {
                        "description": "Stable key reused when retrying this duplicate proposal.",
                        "maxLength": 64,
                        "type": "string"
                    }
                },
                "type": "object",
                "required": [
                    "source_ad",
                    "asset_id",
                    "rationale",
                    "idempotency_key"
                ]
            },
            "annotations": {
                "readOnlyHint": false,
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true
            }
        },
        {
            "name": "show_spend_cap_approval",
            "title": "Show Spend Cap Approval",
            "description": "Render the static spend-cap approval preview card. Reads and writes nothing.",
            "inputSchema": {
                "type": "object",
                "properties": {}
            },
            "annotations": {
                "readOnlyHint": true,
                "idempotentHint": true
            },
            "_meta": {
                "ui": {
                    "resourceUri": "ui://resources/spend-cap-approval-app",
                    "visibility": [
                        "model",
                        "app"
                    ]
                }
            }
        },
        {
            "name": "revoke_grant",
            "title": "Revoke Grant",
            "description": "Revoke an active workspace grant. The caller must hold the revoke_grant scope in the same workspace or be the human delegator of the granted agent.",
            "inputSchema": {
                "properties": {
                    "grant_id": {
                        "description": "The ULID of the grant to revoke.",
                        "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
                        "type": "string"
                    }
                },
                "type": "object",
                "required": [
                    "grant_id"
                ]
            },
            "annotations": {
                "idempotentHint": true
            }
        }
    ],
    "resources": [
        {
            "name": "plainrouter-account-state",
            "title": "Plainrouter account state",
            "description": "Render the authorized Plainrouter advertising account, Signal connection, and read-only capability state.",
            "mimeType": "text/html;profile=mcp-app",
            "uri": "ui://resources/account-state-app",
            "_meta": {
                "ui": {
                    "domain": "ed0eba39c98c4b8b7bc436dc4b4f1a4b.claudemcpcontent.com",
                    "prefersBorder": true
                }
            }
        },
        {
            "name": "plainrouter-spend-cap-approval",
            "title": "Spend-cap approval",
            "description": "Render the static spend-cap approval preview card.",
            "mimeType": "text/html;profile=mcp-app",
            "uri": "ui://resources/spend-cap-approval-app",
            "_meta": {
                "ui": {
                    "domain": "ed0eba39c98c4b8b7bc436dc4b4f1a4b.claudemcpcontent.com",
                    "prefersBorder": true
                }
            }
        }
    ],
    "prompts": []
}