
Microsoft now ships three Power BI-related MCP endpoints that do different jobs, and a REST API that has existed for years. They overlap on one thing, running DAX against a semantic model, and diverge on almost everything else. The MCP server can read a model's schema so an agent writes correct DAX; it cannot start a refresh. The REST API can refresh, rebind, deploy and grant access; it cannot tell the agent what columns exist. This guide compares what each path lets an agent do, the Entra identity each one puts you on, and how to run either across many customer tenants in production.
Your agent needs to answer questions from your customers' Power BI: what drove last quarter's margin, which semantic model failed its overnight refresh, who has access to the Finance workspace. Microsoft ships hosted MCP servers for Power BI and a REST API that has existed for years. They overlap on one thing, running DAX against a semantic model, and diverge on almost everything else. The MCP server can read a model's schema so the agent writes correct DAX; it cannot start a refresh. The REST API can refresh, rebind, deploy, and grant access; it cannot tell the agent what columns exist. Then the tenant settings and Entra consent rules land on top. Here's how to pick.
Microsoft's Power BI MCP servers overview splits the job in two. For consumption, it points to Fabric IQ MCP, a remote, Microsoft-hosted server at https://fabriciq.svc.cloud.microsoft/v1/mcp/fabriciq over Streamable HTTP. Microsoft's docs state that it is generally available. It is read-only and works against Power BI reports and semantic models; dashboards, paginated reports, and Power BI apps are not supported. Auth is delegated OAuth 2.0 through Microsoft Entra ID, and no Power BI tenant setting gates it. Docs: Get started with the Fabric IQ MCP server.
For building, the Power BI Authoring MCP server creates and changes tables, measures, relationships, calculation groups, and security roles. It runs hosted at https://api.fabric.microsoft.com/v1/mcp/powerbi/authoring (preview) or locally from the @microsoft/powerbi-modeling-mcp package (GA). Microsoft's guidance is explicit: don't use it for consumption. Docs: Power BI Authoring MCP server.
The earlier Power BI Consumption MCP endpoint at https://api.fabric.microsoft.com/v1/mcp/powerbi remains in preview for existing integrations. It needs the tenant setting "Users can use the Power BI Model Context Protocol server endpoint (preview)". Docs: remote MCP server tools.
The Power BI REST API at https://api.powerbi.com/v1.0/myorg/ has 17 operation groups: Groups (workspaces), Datasets (semantic models), Reports, Dashboards, Dataflows, Apps, Capacities, Gateways, Imports, Pipelines, Push Datasets, Embed Token, Admin, and more. Every call carries a Microsoft Entra ID bearer token. You can get that token as a user through delegated permissions on an Entra app registration (Dataset.Read.All, Report.Read.All, Workspace.Read.All, and their ReadWrite variants), or as a service principal, where Entra scopes don't apply and access is managed through workspace roles and Fabric tenant settings.
The split is clean. Fabric IQ MCP is the analyst's surface: find the model, learn its shape, ask it a question. The REST API is the operator's surface: keep models fresh, move content between stages, control who sees what. Model editing belongs to a third surface, the Authoring MCP server or the XMLA endpoint, and neither of the other two touches it.
DAX is unforgiving. A query against 'Sales'[Amount] fails when the column is 'Fact Sales'[Net Amount], and a filter on "EMEA" returns nothing when the stored value is "Europe, Middle East & Africa". Fabric IQ MCP gives the model the context to get both right before it runs anything: GetSemanticModelSchema returns tables, columns, measures, relationships, and hierarchies, and ValueSearch resolves the literal. Writing the schema is the hard part. Not the API call.
On the REST API, the agent gets microsoftpowerbi_dataset_get (name, storage mode, refreshability) and a DAX endpoint. Discovering structure means either running exploratory EVALUATE TOPN(...) queries against tables whose names it guesses, or your team writing per-model context into the prompt. That works for one model. It does not survive a customer with 40.
The tradeoff is what MCP will not do. Fabric IQ queries one semantic model per ExecuteQuery call, holds no state between calls, and returns 250 rows by default, with larger results delivered as an embedded CSV resource that not every client handles.
Fabric IQ MCP uses delegated OAuth 2.0 with two Power BI Service scopes: Item.Read.All and Item.Execute.All. Microsoft states that service principal and app-only auth are not supported, and that there is no administrator-impersonation path. Every call runs as the signed-in user, which means row-level security and object-level security apply as they would in the Power BI portal. What the user can't do, the agent can't do.
Two Entra details shape deployment. The scopes don't require admin consent by default, but a tenant admin can restrict user consent or route requests through the admin approval workflow, so the first user at a regulated customer may hit a consent wall. And Entra ID does not support Dynamic Client Registration; Microsoft notes that some clients need a single-tenant app registration with a client-specified redirect URI. The hosted Authoring server has the same limitation, plus a tenant toggle a Fabric admin must enable.
The legacy Consumption endpoint behaves differently: it requires Build permission on the model, and Microsoft notes RLS is not enforced under service principal authentication. Fabric IQ requires neither a workspace role nor Build permission.
The REST API accepts the same delegated Entra tokens, scoped to Power BI Service permissions such as Dataset.Read.All for executeQueries and Dataset.ReadWrite.All for refreshes. It also accepts a service principal: an Entra app authenticating with its own client credentials, gated by the Fabric tenant setting "Service principals can call Fabric public APIs" and by workspace role assignments. That is the only way to run a Power BI agent with no user in the loop.
It comes with a hard edge. Microsoft's executeQueries reference says service principals are not supported for datasets with RLS or with SSO enabled, regardless of tenant settings. The impersonatedUserName parameter evaluates RLS as another UPN, which is useful for testing and dangerous as a default. An agent running on a service principal either cannot query your RLS-protected models or is querying models that have no RLS. Both outcomes deserve a design review.
executeQueries also needs the tenant setting "Dataset Execute Queries REST API" enabled under Integration settings, plus Build permission on the model. Plan for both in your customer onboarding checklist.
In a multi-tenant B2B agent, MCP's OAuth flow gives you a token per user. Direct API calls give you a credential per user. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.
Power BI adds a tenant boundary to both. Each customer has its own Entra tenant, its own consent policy, and its own tenant settings. A user token from Contoso's tenant cannot reach Fabrikam's workspaces, and an agent that serves both needs both tokens, stored separately and never confused.
Recommended reading: OAuth vs API keys for AI agents
Microsoft owns the tool schemas, the DAX execution, and the endpoint. You own the Entra token per user, and you own how the client reacts when the tool surface changes. Microsoft tells clients to call tools/list instead of hard-coding schemas, tolerate additive tools and fields, and send the X-Variants: Fabric.Routing.FabricIQ.V1 header on every request to pin the tool contract. Power BI service throttling applies to metadata and DAX calls through MCP, and rate-limit errors are retryable with backoff.
Region is a quiet blocker. Fabric IQ MCP requires a tenant home region that supports all Fabric workloads; it is not available in Power BI-only regions or sovereign clouds. Some customers cannot use it at all, and your agent needs a fallback path for them.
You own everything: schemas, pagination, retries, and every limit. executeQueries allows 120 query requests per minute per user regardless of the dataset, one query per call, one table per query, 100,000 rows or 1,000,000 values, and 15 MB per response. An agent that loops "refine the query" five times per question and serves 30 concurrent questions from one user account will hit 120 per minute quickly. Throttled calls return HTTP 429; back off before retrying.
Refresh is where licensing shows up. On shared capacity, a semantic model can start at most eight refreshes per day, counting scheduled refreshes, and enhanced refresh (table-level refresh, commit modes, parallelism) is not supported. On Premium capacity, the daily count is bounded by available resources, and a refresh fails if throttling exceeds one hour. An agent that "just refreshes the model" before every answer burns a Pro customer's daily budget by lunch.
Refreshes are asynchronous. microsoftpowerbi_dataset_refresh returns 202 Accepted; the agent has to poll microsoftpowerbi_dataset_refresh_history_list until the status leaves Unknown. That is a pipeline concern, not a chat concern.
The MCP surface is moving fast. Microsoft has already repositioned the original consumption endpoint as legacy, made Fabric IQ the supported consumption server, and split authoring into hosted and local variants with different auth options. Microsoft's own tools page warns that preview tool definitions, request formats, and response schemas may change. Pin the contract header, pin the tool names your agent depends on, and alert on unknown-tool errors.
The REST API is versioned at v1.0 and changes additively, but the semantics shift underneath it. Datasets became semantic models in the UI while the API kept the datasets path, tenant settings were renamed as Power BI moved into Fabric, and workspace permission changes can take time to show up in API calls. None of these break a request outright. All of them break an agent's assumptions.
Pick MCP and every user produces a delegated Entra grant with a refresh token, issued by their own tenant under their tenant's consent policy. Pick the API and you get the same delegated grants, plus a service principal secret or certificate per customer tenant for headless work. Neither path hands you a vault, a refresh scheduler, or a revocation hook.
Run the numbers. 30 customers with 8 analysts each is 240 Entra grants across 30 tenants. Each one must be encrypted at rest, bound to its user and tenant, refreshed before expiry, and invalidated when the analyst leaves or the customer's admin revokes consent. The tempting shortcut, one service principal per customer shared by every user of the agent, collapses 240 credentials into 30. It also turns off RLS for every query the agent runs, because service principals cannot query RLS models at all, and every action lands in the Power BI activity log under one app identity. Fewer secrets, larger blast radius per secret.
Scalekit's Power BI connector handles the Entra OAuth flow, token storage, and refresh per user, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; the token never enters the agent runtime or the LLM context.
Recommended reading: why a token vault matters for AI agent workflows
Scalekit's microsoftpowerbi connector is an API-path connector with 77 Power BI REST API tools: 56 read-only and 21 write, with no destructive tools. It authenticates with OAuth against your own Entra app registration: each user signs in with their Microsoft work account once, and Scalekit stores and refreshes their tokens. Every tool call runs as that user, so their workspace roles and RLS apply.
Create a Microsoft Power BI connection in AgentKit > Connections in the Scalekit dashboard and copy its redirect URI. Register an app in Microsoft Entra ID, add that redirect URI, grant the delegated Power BI Service permissions your agent needs, and enter the app's client ID and client secret on the connection. The name you give the connection is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error.
For DAX tools, the customer's Fabric admin must enable "Dataset Execute Queries REST API", and the user needs Build permission on the semantic model. Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env.
get_or_create_connected_account returns the user's connected account. If it is not ACTIVE, get_authorization_link returns a Microsoft sign-in and consent link. The agent never sees the token.
This is not a catalog load. The agent asks for the tools this user's connected account is authorized to call, narrowed to the seven a reporting Q&A agent needs. Loading all 77 would put microsoftpowerbi_workspace_user_add and microsoftpowerbi_report_rebind in front of a model whose job is to read.
Note that Scalekit labels microsoftpowerbi_dataset_execute_queries as a write tool because the underlying call is a POST. It reads data and changes nothing, so it belongs in a read-only agent.
The loop sends the question, executes whatever tools the model asks for as this user, and feeds results back until the model answers in plain text. The system prompt compensates for the REST API's missing schema operation by telling the model to probe before it aggregates.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. This job runs a fixed DAX query against a known model as the connected user, so RLS applies to the result.
The same call pattern covers the operational surface MCP does not have. This check pulls the last five refreshes for the model so a monitoring job can flag a Failed status with its serviceExceptionJson.
The connector covers the Power BI REST API, not the Admin group or report export. If your agent needs ExportTo or tenant-wide admin scans, register a custom connector for that surface and make proxied calls through actions.request(), keeping the same connected account and vault model.
The microsoftpowerbi connector has 77 tools. At roughly 200 tokens per tool definition, that is about 15,400 tokens before the agent reads a question, and the decision space includes granting workspace access and deploying pipelines. The fix is not better prompting. It is surface reduction. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one user's connected accounts. It also gives MCP-native clients a Power BI endpoint that can do what Fabric IQ cannot, such as reading refresh history. Docs: set up a virtual MCP server.
One server definition serves every user. Before each run, check that the user's Power BI and Slack accounts are active, then mint a short-lived session token scoped to them. Any MCP client that speaks streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters).
The agent sees four tools. The endpoint is static; the identity is per-user.
Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one of your users in one customer tenant. When a customer asks which agent run rebound a report or triggered the refresh that ate their last slot of the day, the answer is a lookup, not an investigation. Power BI's own activity log records the operation under the Entra identity that made it; your execution log records which user, which run, and which prompt asked for it.
A shared service principal breaks both halves. The activity log shows one app identity for every user, your side can only prove the shared credential did it, and RLS-protected models were never queryable in the first place. Shared credentials are a single-user solution. They do not survive a second user.
Recommended reading: audit trails for agent auth
If your agent answers business questions from semantic models inside Copilot or your own agent, and the customer's tenant region supports it, use Fabric IQ MCP. It gives the model the schema and value context that makes DAX correct, and it enforces RLS by construction. If your agent keeps Power BI running, refreshing models, monitoring failures, managing access, or deploying content, use the REST API; MCP has no tools for any of that, and only the API supports a headless identity. Many production agents will need both: MCP for the question, the API for the operations behind it.
Either way, the credential problem is the same, and that's what needs production-grade infrastructure. One delegated Entra grant per user, per customer tenant, stored, refreshed, and revoked on your side.
Yes, three. Fabric IQ MCP is the generally available, read-only consumption server with six tools for finding reports and semantic models, reading schema, searching values and running DAX. The Power BI Authoring MCP server edits semantic models, hosted in preview and generally available locally. The earlier Power BI consumption endpoint remains in preview for existing integrations and needs a tenant setting.
Operations: trigger and monitor refreshes, manage refresh schedules and Power Query parameters, audit and grant workspace access, deploy content through pipelines, push rows into a push dataset, list dashboards and apps, and export reports. MCP has no tools for any of that, and only the API supports a headless identity through a service principal.
No. Fabric IQ MCP accepts only delegated Microsoft Entra ID OAuth, with no app-only auth and no administrator impersonation, so every call runs as the signed-in user and row-level security applies as it does in the portal. The REST API accepts service principals, but Microsoft states they are not supported for datasets with row-level security or single sign-on enabled.
The DAX query endpoint allows 120 requests per minute per user, one query per call, one table per query, 100,000 rows or one million values, and 15 MB per response, returning 429 when throttled. Refreshes are limited too: a semantic model on shared capacity can start at most eight refreshes a day, so an agent that refreshes before every answer burns a customer's budget by lunch.
When it runs headless on a schedule, such as a nightly job that checks refresh history across workspaces and posts failures; when the work is operational, such as refreshes, parameter updates, report rebinding or pipeline deployments; when it needs governance actions like auditing workspace admins; or when the customer's tenant sits in a region where Fabric IQ MCP is unavailable.
The Power BI connector exposes 77 REST API tools on per-user Entra OAuth against your own app registration. Each user signs in with their Microsoft work account once, Scalekit stores and refreshes the tokens in the token vault, every call runs as that user so their workspace roles and row-level security apply, a virtual MCP server narrows the tools per agent role, and every execution is attributed to that user and tenant.
Browse the Scalekit Microsoft Power BI connector and the Power BI connector docs with the full tool list. See Scalekit pricing, or talk to us.