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>.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.Allhttps://analysis.windows.net/powerbi/api/Report.Read.Allhttps://analysis.windows.net/powerbi/api/Dataset.Read.Allhttps://analysis.windows.net/powerbi/api/Dashboard.Read.Allhttps://analysis.windows.net/powerbi/api/App.Read.Allhttps://analysis.windows.net/powerbi/api/Dataflow.Read.Alloffline_access(keeps the connection alive)
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 byDEFINE. DAX queries run as the connected user; no other identity can be named.
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.404 error (see Errors).
Result context
Every result exceptlist_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
list_workspaces(skip it for “My workspace”).list_reportsorlist_datasetsin the workspace, to find thedatasetId.get_dataset_schema, to learn the exact table, column and measure names.execute_dax_querywith 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. A403 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. A403 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” whenworkspaceId 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’sdatasetId 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” whenworkspaceId 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’sdatasetId 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” whenworkspaceId 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 beforeexecute_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
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.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
Errors
Tool failures come back as a normaltools/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:
maxRowsdefault 200, maximum 2,000 per query. DAX text: at most 20,000 characters. - Refresh history:
topdefault 20, maximum 100.get_datasetshows 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.
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.