edit_widget
Edit an existing report widget using plain language, e.g. "make the sessions chart weekly", "show the cost table for last quarter", "turn the donut into a bar chart", "sort the queries table by impressions", or set KPI targets: "set targets of 500 leads and a cost per lead of 180 € on the totals card" (the card then shows attainment, and for sums in a running period the linear pace and projection). Same catalog validation as add_widget — an impossible change is refused with a reason, never a wrong widget. Returns a deterministic receipt of what changed plus the widget's previous configuration (so you can restore it with another edit). Pass widgetId (from get_report) to pin the target; otherwise it is identified from your description. GRANULARITY: on a time-series chart, "by/per/each ", "one bar per ", "monthly/weekly/daily" (pro/je Monat, monatlich, wöchentlich, täglich…) are read deterministically into its time scale (Search Console, AI Visibility and All channels charts; a Day/Week/Month table switches its time bucket); a period ("last 12 months"), "a week ago", "month-over-month" or "monthly budget" is never one; a chart by Campaign, Device… is left alone; one a widget cannot show (by quarter, or weekly on a daily-only source) is refused, nothing changed. The receipt compares the widget before and after field by field: it says nothing changed only when no field differs. MOVE ONE WIDGET: with widgetId and move {position, anchorId} (no AI): after / before a widget, section_start / section_end of a section, or start / end of the report — or with widgetId and an instruction like "move this widget so it sits directly after the Top campaigns table": a move verb and a placement that names an existing widget or section are read without AI, so the preview shows from/to too (without widgetId the AI picks the widget and only the receipt names the positions). The widget keeps its configuration and joins the section it lands in; the receipt names the old and the new position, the result carries undo (the move that puts it back); an anchor that is not in the report is refused. Also handles SECTION ops on the report layout: "add a section called Paid Media above the Google Ads table", "rename the first section to Overview", "move the SEO section to the end", "remove the Awareness section but keep its widgets" (a section moves with its widgets; removal keeps them unless asked). TEXT widgets (type "text", free-text blocks) are not edited by instruction: to change one, write the new text yourself and pass it as text together with its widgetId (no instruction needed). The body is replaced exactly as given, with no AI — HTML (p, br, strong, em, u, s, ul, ol, li, h2–h4, blockquote, a href) or plain text, at most 50,000 characters. Scripts, event handlers, javascript: links, iframes, images and any inline style other than text-align are removed before saving, and the preview says so. Styling is carried by attributes, never inline styles: (text colour), (highlight), , (a tinted box around one block) and (a divider); each is painted with the report theme's own colours in light and dark mode and in the PDF. Title, width and hideTitle stay unchanged; the result carries the previous widget, so passing previous.body back as text undoes it. An instruction is read by AI: the preview's aiCost says who pays for it (the workspace's own AI key, billed by its provider, or CrunchJunkie's at no charge); text uses no AI. Requires MCP write actions; without confirm:true it returns a preview.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| move | No | Move the widget given by widgetId, deterministically (no AI; instruction is not needed and is ignored). A section moves with its widgets through an instruction instead. | |
| text | No | TEXT widgets only: the complete new body of the text widget given by widgetId, as HTML or plain text (at most 50,000 characters). Replaces the body as given, with no AI and no rewording; unsafe markup is removed. Title, width and hideTitle are kept. | |
| confirm | No | Set true to apply. Omit for a preview of what will be interpreted. With confirm:true, also pass the preview's previewToken. | |
| reportId | Yes | Report id (from list_reports). | |
| widgetId | No | Exact widget id (from get_report) to pin the target. Required with text. | |
| instruction | No | The change, in plain language. Can also remove a widget ('remove the donut'). Required unless you pass text. | |
| previewToken | No | With confirm:true: the previewToken from this tool's preview (valid 15 minutes, once, for exactly the previewed arguments). |