Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PBI_POLL_MSNoInterval between poll probes in milliseconds. Default: 1000
PBI_OUTPUT_DIRNoDirectory for screenshots and baselines. Default: <os tmpdir>/pbi-webview2-output
PBI_DESKTOP_EXENoExplicit path to PBIDesktop.exe for direct-launch fallback.
PBI_CDP_ENDPOINTNoCDP endpoint to attach to. Always 127.0.0.1, never localhost. Default: http://127.0.0.1:9222
PBI_DESKTOP_BRIDGENoExplicit path to Microsoft's powerbi-desktop bridge CLI entry (.js, .cmd, .bat, or .exe). Used by pbi_launch.
PBI_EVAL_BUDGET_MSNoPer-page.evaluate time budget in milliseconds. Default: 30000

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
pbi_launchA

Launch Power BI Desktop on a .pbip WITH the CDP debug port. Resolves a launcher in order: PBI_DESKTOP_BRIDGE env → powerbi-desktop on PATH → direct PBIDesktop.exe (reported as launcher: bridge-env|bridge-path|direct). Injects the WebView2 remote-debugging env var into Desktop's own process, spawns detached, waits until the CDP port answers. If the port is already up, reports the running instance instead of launching a second one. Pre-flight warns about orphaned PBIDesktop/msmdsrv. After it returns cdpUp:true, call pbi_wait_for {text:""} — the canvas is still rendering.

pbi_statusA

Connect to Power BI Desktop over CDP and report status: build, title bar, active page, page count, zoom, canvasReady. Returns {connected:false,...} if unreachable.

pbi_pagesA

List all report page tabs as [{name, active}].

pbi_goto_pageA

Navigate to a page by EXACT name. Returns as soon as the tab switches (the canvas may still be rendering — use pbi_wait_for before reading values); waitReady:true blocks until visuals are painted. On not-found returns closest candidates.

pbi_deselectC

Clear visual/group selection via the neighbour-page-and-back trick (never blind-clicks the canvas). Returns {selectedBefore, selectedAfter, page}.

pbi_state_probeB

Batched scorecard: {activePage, toggles, cards, badges, selectedCount, slicerItemsVisible, visibleVisualCount}.

pbi_read_cardsA

Parsed card visuals as [{title, value}].

pbi_clickA

Generic tag-then-act click by text | ariaLabel | selector (ctrl for action buttons; index disambiguates). Overlay-intercept coordinate fallback. Returns {clicked, method, matchedLabel, candidateCount}.

pbi_set_slicerA

Set a slicer: kind "button" (buttonSlicerVisual, returns aria-pressed before/after) or "item" (list slicer item, returns a fresh state probe).

pbi_fire_bookmarkA

Fire ANY bookmark by name via the View > Bookmarks pane (trusted coordinate click; optional group; expandable groups auto-expanded). Returns {fired, landedPage, warning?}.

pbi_read_matrixA

Read a matrix/grid fully as {columns, rows:[{header, cells}], ariaRowCount, ariaColCount, complete}. Scrolls virtualized grids and merges by row header.

pbi_matrix_expandB

Expand or collapse a matrix hierarchy row (by rowHeader). Grid re-renders; returns {rowsBefore, rowsAfter}.

pbi_cross_filter_testB

Click a data point and judge whether a cross-filter FIRED (highlights rose OR card fingerprint changed). Optional restore re-clicks and verifies baseline. Returns {fired, highlightsBefore, highlightsAfter, changedCards, restored}.

pbi_hover_tooltipA

Trusted mouse-move hover to a point (offsetX/offsetY to aim off-center, e.g. donut ring) and read the tooltip text. Returns {tooltipText} or {tooltipText:null}.

pbi_scan_errorsA

Scan visible visuals for broken/errored surfaces + recent non-benign console errors. Excludes the permanent favicon.ico error (reported as benignFaviconCount).

pbi_perf_analyzerA

Run the Performance Analyzer lane: per-visual render ms; optional captureQueryFor grabs one visual DAX via clipboard (clobbers clipboard). Restores pane + ribbon.

pbi_page_sweepA

HEAVY, deliberately renders every page: each page switch makes Desktop re-query all its visuals (blank/busy for that page’s real load time, often 10-30s+). Run as an intentional health sweep (≤2 pages per call; user warned/away), never casually. Iterates pages, waits canvas-ready (cap 30s/page), records loadMs + error scan + cards fingerprint; restores the original page.

pbi_baselineA

Capture / compare / list value baselines. capture: store {cards, badges, visibleVisualCount} per page (default current; pages:["*"]=all) to /baselines/.json. compare: re-capture + diff. list: available baseline names.

pbi_wait_forB

Poll body innerText until text appears (text) or disappears (textGone). Returns {satisfied, elapsedMs}.

pbi_evalA

Escape hatch: evaluate a function-body or arrow-fn string in the reportView page. Rejects any code referencing powerBIAccessToken. Returns the JSON-serialized result. NOTE: the powerBIAccessToken rejection is a best-effort textual guard (a regex on the code string), not a sandbox.

pbi_run_codeA

TRUSTED escape hatch (browser_run_code_unsafe equivalent). Runs an async JS function with the live Playwright reportView page — page.mouse/page.keyboard give REAL trusted input (unlike pbi_eval, which is page.evaluate and cannot do trusted clicks/keys). Use for rediscovery + interactions the canned tools do not cover. The code string must be an async arrow/function taking (page); its return value is JSON-serialized. Rejects powerBIAccessToken. UNSAFE: arbitrary automation — mutating clicks change report state, so restore after. The powerBIAccessToken rejection is a best-effort textual guard (a regex on the code string), not a sandbox. NOTE inside page.evaluate sandboxes setTimeout is undefined — use page.waitForTimeout(ms).

pbi_snapshotA

Accessibility-tree snapshot of the reportView page (browser_snapshot equivalent) for structure discovery when a selector drifts. Returns the ARIA snapshot (roles + accessible names, indented) as lines. selector scopes to a sub-tree (default "body"); filter (regex string) keeps only matching lines (with their indent); maxLines caps output. Read-only.

pbi_typeA

Type text into an editable element (input/textarea/contenteditable/searchbox/textbox) via TRUSTED keyboard input. Target resolution: selector > element whose aria-label includes ariaLabel > first visible search/text input. Focuses the input IN-PAGE and ABORTS (typed:false) if focus does not land on it — never sends keystrokes to the canvas. clear empties the input via its own value (no global select-all); submit presses Enter. Returns {typed, matchedLabel, cleared, submitted}. WARNING: real typing mutates report state — restore/clear when testing.

pbi_search_slicerA

Type into a slicer's search box and (optionally) click the matching result. Focuses the box IN-PAGE and ABORTS (searched:false) if focus does not land on it — never sends keystrokes to the canvas (a mis-focused select-all+delete once removed all page visuals). Clears via the input's own value, types query, polls for filtered .slicerItemContainer items, returns them as matches. With pick, clicks the item equalling (then including) pick. Returns {searched, picked, pickedLabel?, matches} or {searched:false, reason}. Mutates a filter when pick clicks — restore after.

pbi_context_menuA

Right-click a data point / visual to open its context menu and read the items (drillthrough, Show as a table, Summarize, …). Right-clicks at the on-path point for SVG (else bbox center). With click, invokes the menu item matching (exact then contains) it and returns {opened, items, clicked, clickedItem}. Without click, reads items then presses Escape to CLOSE the menu (leaves no menu open). Returns {opened:false, reason} if no menu appeared.

pbi_screenshotA

Screenshot the reportView page to the output dir (never the repo). Optional filename + fullPage. With visualTitle, clips the shot to the matching visual (exact then case-insensitive contains on the same title logic as pbi_visuals) and returns {clippedTo}; on a miss returns {saved:false, reason, candidates}. Returns {path}.

pbi_visualsA

List every visible visual on the active page as [{title, type, x, y, width, height, hasError}]. type is a class-token heuristic (barChart, slicer, card, tableEx, pivotTable, donutChart, …; null when unknown); title from the container/descendant aria-label or .visualTitle; hasError reuses the broken-visual scan. Coordinates are getBoundingClientRect() rounded. Read-only.

pbi_read_dax_editorA

Read the DAX query view editor text (Monaco). Reaches the daxQueryView CDP target (a SEPARATE page from reportView); returns {ok:false, reason} if that view has never been opened in Desktop (open it via the DAX query view tab first — this tool will NOT open ribbon views). Read-only.

pbi_read_tmdlA

Read the TMDL view editor text (Monaco). Reaches the tmdlView CDP target (a SEPARATE page from reportView); returns {ok:false, reason} if that view has never been opened in Desktop (open the TMDL view tab first — this tool will NOT open ribbon views). Read-only.

pbi_dax_queryA

Write DAX into the DAX query view editor and RUN it, then read the results grid. Reaches the daxQueryView CDP target (SEPARATE from reportView); {ok:false, reason} if the view has never been opened in Desktop (open the DAX query view tab first — this tool will NOT open ribbon views). Runs via F5 on the focused editor, falling back to a visible "Run" button. Returns {ran, columns, rows, rowCount, error?}. CAVEAT: this OVERWRITES whatever DAX the user had in the query editor — prior text is NOT restored (unrecoverable). Use a throwaway query view.

pbi_dialogA

Automate a Desktop dialog (desktopDialogHost CDP target — exists ONLY while a dialog is showing). action:"read" returns {open, text, buttons}; action:"click" trusted-clicks the button matching button (exact, then case-insensitive contains). Returns {open:false, reason:"no dialog showing"} when none is up. SAFETY: a button labelled "Save" (any case) is refused UNLESS the button param is EXACTLY "Save" (case-sensitive) — protects against accidentally saving the report.

pbi_deep_snapshotA

Raw-CDP deep inspection of the reportView page. what:"axtree" (default) = a compact {role,name} projection of the full accessibility tree (capped to maxNodes, totalNodes reported); "dom" = a DOMSnapshot size probe ({documentCount, note}); "heap" = V8 heap usage ({usedMB, totalMB}). Read-only; safe.

pbi_emulate_themeA

Force the WebView media query prefers-color-scheme to light/dark/no-preference (via page.emulateMedia). Returns {emulated, scheme}. NOTE (verified 2026-07-15): the signal flips correctly (matchMedia reflects it) but Power BI Desktop reports do NOT restyle on prefers-color-scheme — report theming is driven by theme.json + app settings, not this CSS signal — so this is effectively INERT for PBI report canvases (it would matter only for a generic web app). Kept for completeness; do not expect a visual change. RESET to "no-preference" when done.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bibiibjorn/pbi-webview2'

If you have feedback or need assistance with the MCP directory API, please join our Discord server