Spring til hovedindhold
All Power BI tools are read-only and are called via tools/call over POST /power-bi/mcp. The connector reads the Microsoft Power BI service through the Power BI REST API (not Microsoft Graph) and is connected through OAuth with a Microsoft work or school account (see Connect Power BI). Your organization needs access to Power BI (a subscription, or a plan that covers it, see What decides access), and your user must hold a seat or plan licence (assigned under Team in the portal, see Team).
Endpoint: https://mcp.consile.ai/power-bi/mcp. Power BI is its own named connector with only its own tools. Tool names are namespaced power-bi__<tool> (e.g. power-bi__list_workspaces); the bare names are used below for readability. A bare name in a request returns Unknown tool.The connector is multi-instance: one instance is one connected Microsoft user in one Microsoft Entra tenant, and it sees what that user can see in Power BI. An administrator adds further connections (agreements, aftaler, in the portal), each served at its own endpoint, e.g. https://mcp.consile.ai/power-bi-2/mcp, with tools named power-bi-2__<tool>.
For an account with access to Power BI, tools/list returns the twelve power-bi__* tools plus the unprefixed system tool connect_account. Without access only connect_account is listed, and the initialize result includes instructions explaining how to get access. A user without a seat still sees the tools, but every call is refused. Every tool has a title and the annotations readOnlyHint: true, destructiveHint: false and openWorldHint: false. A successful result contains the payload twice: as JSON text in content and as the same object in structuredContent. The examples below show that payload.

Authorization and read-only enforcement

The account is connected through Microsoft’s OAuth sign-in. Only work or school accounts can connect; Microsoft refuses a personal Microsoft account. The requested delegated Power BI Service permissions are all read permissions:
  • https://analysis.windows.net/powerbi/api/Workspace.Read.All
  • https://analysis.windows.net/powerbi/api/Report.Read.All
  • https://analysis.windows.net/powerbi/api/Dataset.Read.All
  • https://analysis.windows.net/powerbi/api/Dashboard.Read.All
  • https://analysis.windows.net/powerbi/api/App.Read.All
  • https://analysis.windows.net/powerbi/api/Dataflow.Read.All
  • offline_access (keeps the connection alive)
All six Power BI permissions must be granted, or the connect is refused. The connect is also refused if Microsoft’s grant contains permissions for another resource than the Power BI API (for example Microsoft Graph). The standard sign-in scopes (openid, profile, email) are accepted. In many Entra tenants an administrator must consent to the permissions first. On top of the read-only grant:
  • The connector has no write tools.
  • Consile sends only read requests to the Power BI API.
  • DAX queries can only read: a query must start with EVALUATE, optionally preceded by DEFINE. DAX queries run as the connected user; no other identity can be named.
Access is renewed automatically. Consile never hands the token to the MCP client, and the MCP client’s own token is never forwarded to Microsoft. No Power BI data is stored at Consile; every call reads live.

Shared conventions

workspaceId and “My workspace”

Power BI addresses content by a workspace id. The signed-in user’s personal “My workspace” has no id.
string (GUID)
Workspace id from list_workspaces. Optional on every tool that takes it: omit it to read “My workspace”. Required on list_dataflows, because dataflows live only in workspaces.
string (GUID)
Dataset (semantic model) id from list_datasets, or the datasetId of a report or a dashboard tile.
Ids are validated as GUIDs. An id that does not exist, or that belongs to another workspace than the one named, returns a 404 error (see Errors).

Result context

Every result except list_workspaces and list_apps echoes a context object with the workspaceId it was read from (null for “My workspace”). Fields Power BI does not return are null. @odata.* annotation keys are removed. Collections are returned in full; the list tools take no paging arguments.

Typical call order

  1. list_workspaces (skip it for “My workspace”).
  2. list_reports or list_datasets in the workspace, to find the datasetId.
  3. get_dataset_schema, to learn the exact table, column and measure names.
  4. execute_dax_query with an aggregating query.

list_workspaces

Lists the Power BI workspaces the signed-in user is a member of, up to 5,000. “My workspace” is not in the list. Arguments: none.
array
Each item has id (the workspaceId), name, type, isReadOnly, isOnDedicatedCapacity and state.

list_apps

Lists the Power BI apps the signed-in user has installed. An app the user never installed is not listed. A 403 can mean that the tenant has apps turned off; it says nothing about the other tools. Arguments: none.
array
Each item has id, name, description, publishedBy and lastUpdate.

list_dataflows

Lists the dataflows in one workspace. A 403 can mean that the tenant has dataflows turned off.
string (GUID)
påkrævet
array
Each item has objectId, name, description, configuredBy and modifiedDateTime.

list_reports

Lists the reports in a workspace, or in “My workspace” when workspaceId is omitted.
string (GUID)
array
Each item has id, name, webUrl, datasetId (the dataset the report reads from), reportType (PowerBIReport or PaginatedReport) and isOwnedByMe.

get_report

Reads one report’s metadata and its pages. It does not render visuals; query the report’s datasetId with execute_dax_query for the numbers.
string (GUID)
string (GUID)
påkrævet
Report id from list_reports.
object
The same fields as a list_reports item, at the top level of the result.
array
Each page has name, displayName and order.

list_dashboards

Lists the dashboards in a workspace, or in “My workspace” when workspaceId is omitted.
string (GUID)
array
Each item has id, displayName, isReadOnly and webUrl.

list_dashboard_tiles

Lists the tiles pinned on one dashboard. Tiles carry no values; query the tile’s datasetId with execute_dax_query for the numbers.
string (GUID)
string (GUID)
påkrævet
Dashboard id from list_dashboards.
array
Each item has id, title, subTitle, reportId, datasetId, rowSpan and colSpan. The result also echoes dashboardId.

list_datasets

Lists the datasets (semantic models) in a workspace, or in “My workspace” when workspaceId is omitted.
string (GUID)
array
Each item has id (the datasetId), name, configuredBy, isRefreshable, isEffectiveIdentityRequired, isOnPremGatewayRequired, createdDate and targetStorageMode.

get_dataset

Reads one dataset’s details, its data sources and its last 5 refreshes. Use it to see where the data comes from and whether the latest refresh succeeded before trusting a number.
string (GUID)
string (GUID)
påkrævet
object
The same fields as a list_datasets item, at the top level of the result.
array | null
Each item has datasourceType and connectionDetails (for example server and database, as Power BI returns them; never credentials). null when Power BI does not return the data sources.
array | null
The last 5 refreshes, in the shape of list_dataset_refresh_history. null when Power BI does not return the history.
string[]
Present only when datasources or refreshes could not be read, with the reason (for example datasources unavailable: <message>).

get_dataset_schema

Reads a dataset’s model: tables, columns with data type, and measures with their DAX expression. Call it before execute_dax_query so names are spelled exactly as the model has them ('Sales'[Amount], [Total Revenue]). It needs a current Power BI dataset; a push dataset or a very old dataset is answered with an explanatory error, and a hand-written execute_dax_query still works there.
string (GUID)
string (GUID)
påkrævet
boolean
standard:"false"
Include hidden tables, columns and measures.
array
Each item has name, description and isHidden.
array
Each item has table, name, dataType and isHidden.
array
Each item has table, name, expression (cut at 500 characters, ending in …), description and isHidden.

execute_dax_query

Runs a read-only DAX query against a dataset and returns the rows of the first result table. The query runs as the connected user, who needs Build permission on the dataset.
string (GUID)
string (GUID)
påkrævet
string
påkrævet
The DAX query. It must start with EVALUATE, optionally preceded by DEFINE for query-scoped measures or variables. At most 20,000 characters.
integer
standard:"200"
Rows to return, 1 to 2000. Rows above it are cut and truncated is set.
string[]
The column keys of the first row, in Power BI’s order. Columns come back as Table[Column], a measure or a named expression as [Name]. Empty when there are no rows.
array
The rows, as objects keyed like columns. Nulls are included.
integer
The number of rows returned.
boolean
true when the query returned more than maxRows rows and the rest were cut. Narrow or aggregate the query rather than raising maxRows.
Keep results small: aggregate in DAX with SUMMARIZECOLUMNS, TOPN, FILTER and CALCULATETABLE instead of EVALUATE 'BigTable'.

list_dataset_refresh_history

Lists a dataset’s refresh history, newest first. A dataset that is not refreshable (DirectQuery, live connection) has no history.
string (GUID)
string (GUID)
påkrævet
integer
standard:"20"
Refreshes to return, 1 to 100.
array
Each item has refreshType (for example scheduled, on demand or via API), status (Completed, Failed, or Unknown while in progress), startTime, endTime and hasServiceException (true when a failure carried an error; the error itself is not returned).

connect_account

connect_account is a system tool that the Power BI endpoint lists next to the twelve tools. It takes no arguments and its name has no power-bi__ prefix. It returns { "connect_url": "…", "instructions": "…" }. The user opens connect_url in a browser and is sent to Microsoft to sign in and approve access. The link expires after 10 minutes. It only works for accounts that subscribe to Power BI and for users who have accepted Consile’s terms in the portal. Use it to reconnect after the access expired or was removed: completing the link connects the account again with the new Microsoft sign-in.
Request
Replacing an existing connection requires a Consile administrator; for other users the link is refused.

Errors

Tool failures come back as a normal tools/call result with isError: true and one text block, not as a JSON-RPC error. The connector returns explanatory messages for the common failures:

Limits

  • DAX rows: maxRows default 200, maximum 2,000 per query. DAX text: at most 20,000 characters.
  • Refresh history: top default 20, maximum 100. get_dataset shows the last 5.
  • Measure expressions in get_dataset_schema: cut at 500 characters.
  • Power BI applies its own request limits per user. Aggregate in DAX instead of fetching raw rows.
Requests to the endpoint are also rate-limited per account and connector. When the limit is exceeded you get HTTP 429 (JSON-RPC error -32029, Retry-After: 1) instead of a tool result. See Errors & limits for the current limits and the protocol-level errors shared by all connectors.