Skip to main content
Glama
user-vik
by user-vik

fabric-mcp-server

Microsoft Fabric as an MCP server and as a CLI, from one tool registry.

  • The MCP server gives Claude Code, Claude Desktop, or any Model Context Protocol client typed, permission-gated access to Fabric.

  • The fabric CLI exposes the exact same tools from a shell, so you can pipe large results through jq or PowerShell, loop over workspaces in one call, and run unattended from a scheduled task with no model in the loop.

Both talk to the public Fabric REST API (api.fabric.microsoft.com), the Power BI REST API (api.powerbi.com), and the OneLake DFS endpoint, authenticating with @azure/identity.

Features

  • Resolve workspaces, items, pipelines, deployment pipelines, folders, and semantic models by display name or GUID.

  • Continuation-token paging, HTTP 429 retry (honors Retry-After), and long-running-operation polling built in.

  • Read-only by default. Every mutating tool is gated behind FABRIC_MCP_MODE=write on both surfaces and audit-logged to stderr.

  • Safety rails on the dangerous operations: deploy_stage and commit_to_git refuse blanket "everything" runs; update_item_definition and delete_item snapshot the live definition first for one-call rollback.

Related MCP server: PowerBI MCP Server

Which surface when

Situation

Use

Ad hoc question in a Claude session, small result

MCP

A write operation you want permission-gated per tool by the MCP client

MCP

Result is large and you only need a slice (OneLake listing, run history, item definition)

CLI piped through a filter

Sweep across many workspaces or items

CLI in one shell call

Anything that runs without a model (scheduled task, CI step)

CLI

Fabric access from Claude Desktop or another MCP host

MCP

Tools

Tool names and parameters are identical on both surfaces. On the CLI, list_item_runs is fabric list-item-runs (either spelling works) and each parameter is a --flag.

Tool

Mode

Description

list_workspaces

read

All workspaces the signed-in identity can see.

list_items

read

Items in a workspace, optional type filter; includes folderId.

list_folders

read

Workspace folders as a flat list with full paths.

list_workspace_roles

read

Role assignments on a workspace.

list_sql_databases

read

SQL databases in a workspace with connection properties.

list_pipelines

read

Data pipelines in a workspace.

list_pipeline_runs

read

Run history for a pipeline, most-recent first, optional status filter.

get_pipeline_run

read

One pipeline run by job instance ID, including failureReason.

list_item_runs

read

New. Run history for any item type (notebooks, Spark jobs, dataflows), with status/job-type filters.

get_item_run

read

New. One job instance of any item: terminal status, timings, full failureReason.

list_schedules

read

Job schedules on an item, including each schedule's owner (spot ownership drift).

execute_dax

read

Read-only DAX query against a semantic model (Power BI executeQueries).

get_refresh_history

read

Recent refresh history for a semantic model.

get_dataset_datasources

read

New. Power BI data sources of a model with gateway binding (gatewayId/datasourceId, bound).

get_item_connections

read

New. Fabric connections an item is bound to; connectivityType: Automatic means unbound.

get_git_status

read

Items changed between the workspace and its Git branch, plus workspaceHead / remoteCommitHash.

get_item_definition

read

Definition parts of an item (TMDL, notebook, report). Manifest by default; decoded content for one part.

list_deployment_pipelines

read

Deployment pipelines the identity can see.

list_deployment_stages

read

Stages of a deployment pipeline; optionally a stage's items for deploy_stage.

list_onelake

read

Files/tables under an item in OneLake via the DFS API.

read_onelake_file

read

Read a small OneLake file as text, size-capped.

add_workspace_role

write

Grant a principal a workspace role.

create_folder / move_item / delete_folder

write

Workspace folder management.

run_pipeline / cancel_pipeline_run

write

Trigger or cancel a pipeline run; run_pipeline now returns jobInstanceId.

run_notebook

write

Run a notebook and wait, or detach with wait=false. Changed: pass job_instance_id to attach to an existing run instead of starting another.

create_schedule / update_schedule / delete_schedule

write

Schedule management.

refresh_dataset

write

Trigger an on-demand semantic model refresh.

bind_dataset_to_gateway

write

New. Power BI BindToGateway: fixes the "default data connection without explicit credentials" refresh failure after a git sync.

takeover_item

write

New. Power BI TakeOver for a semantic model or paginated report; unblocks NotPaginatedReportOwner deploy errors.

bind_semantic_model_connection

write

New. Fabric bindConnection: explicit connection_id + type + path, or copy_from a bound sibling model in the same workspace. Every deployment-pipeline leg resets these bindings.

update_from_git

write

Pull repo into workspace. Changed: conflict_policy (PreferRemote default, PreferWorkspace to re-baseline) and wait.

commit_to_git

write

New. Commit workspace items to Git. Selective by item name/GUID; mode=All is an explicit opt-in.

update_item_definition

write

Deploy a definition from a local folder, snapshotting the live one first.

create_item / delete_item

write

Create (optionally from a definition) or delete an item, with best-effort snapshot.

refresh_sql_endpoint_metadata

write

New. Force a lakehouse SQL analytics endpoint to re-sync table metadata now, optionally scoped to tables or with recreate_tables.

deploy_stage

write

Selective stage-to-stage deployment; explicit item list required.

Requirements

  • Node.js >= 20

  • An Entra identity with access to the target workspaces.

  • For execute_dax: Build permission on the semantic model and the tenant's "Dataset Execute Queries REST API" setting enabled.

  • For bind_semantic_model_connection: the caller must own the model (takeover_item first if not).

Install

git clone <this-repo-url> fabric-mcp-server
cd fabric-mcp-server
npm install
npm link        # optional: puts `fabric` and `fabric-mcp-server` on your PATH

Configuration

All configuration is via environment variables (see .env.example). Both surfaces read the same variables.

Variable

Required

Purpose

FABRIC_AUTH_MODE

no (default interactive)

interactive, device-code, cli, azure-powershell, service-principal, managed-identity, or default.

AZURE_TENANT_ID

for interactive / device-code / service-principal

Entra tenant ID.

AZURE_CLIENT_ID

for service-principal

App registration client ID.

AZURE_CLIENT_SECRET

for service-principal

App registration secret.

FABRIC_MCP_MODE

no (default read)

read or write. Gates the write tools on both surfaces.

FABRIC_TOKEN_CACHE

no

memory (MCP default) or persistent (CLI default). Persistent uses the OS secure store so each CLI process reuses the last sign-in.

FABRIC_TOKEN_CACHE_NAME

no

Cache partition name (default fabric-mcp-server).

Auth modes

  • interactive — opens a browser; best for desktop/AVD. With the persistent cache, the CLI signs in once and then runs silently.

  • device-code — prints a code + URL to stderr; for SSH / WSL / headless.

  • cli — reuses your az login session.

  • azure-powershell — reuses your Connect-AzAccount session.

  • service-principal — non-interactive; the right choice for scheduled tasks.

  • managed-identity — for hosting on Azure.

  • default — tries env → managed identity → CLI → browser in turn.

Use as an MCP server

Add to your MCP client config (~/.claude.json for Claude Code, claude_desktop_config.json for Claude Desktop):

{
  "mcpServers": {
    "fabric": {
      "command": "node",
      "args": ["/absolute/path/to/fabric-mcp-server/index.js"],
      "env": {
        "FABRIC_AUTH_MODE": "interactive",
        "AZURE_TENANT_ID": "<your-entra-tenant-id>"
      }
    }
  }
}

Add "FABRIC_MCP_MODE": "write" to the env block to expose the write tools. Existing v1.x client configs keep working unchanged.

Use as a CLI

fabric tools                                  # every tool with its mode
fabric help list-item-runs                    # a tool's flags
fabric list-workspaces
fabric list-item-runs --workspace BI-Prod --item brz_nb_clean --status Failed --top 5
fabric get-item-definition --workspace BI-Prod --item "Sales Model" --out sales-model.json

Conventions:

  • Flags mirror tool parameters; --job_instance_id and --job-instance-id are equivalent.

  • Object and array parameters take inline JSON or @path/to/file.json. String arrays also take comma-separated values: --items "Notebook A,Notebook B".

  • Booleans: --wait, --wait=false, --no-wait.

  • Output is JSON on stdout. --compact for one line, --out <file> to write to disk and print a short receipt instead.

  • Exit codes: 0 success, 1 the tool failed (message on stderr), 2 usage problem.

  • Write tools need FABRIC_MCP_MODE=write in the environment. The CLI will not accept it as a flag, so the same safety property holds on both surfaces.

Filtering large results in the shell

The point of the CLI is that filtering happens before anything reaches a model or your eyes.

# Which tables in the lakehouse have not been written today?
fabric list-onelake --workspace BI-Prod --item Bronze --directory Tables/dbo |
  ConvertFrom-Json | Select-Object -Expand paths |
  Where-Object { [datetime]$_.lastModified -lt (Get-Date).Date } |
  Select-Object name, lastModified
# Failed runs across every pipeline in a workspace, last 24 hours
fabric list-pipelines --workspace BI-Prod | jq -r '.pipelines[].displayName' | while read -r p; do
  fabric list-pipeline-runs --workspace BI-Prod --pipeline "$p" --status Failed --top 5 --compact |
    jq -c --arg p "$p" '.runs[] | select(.startTimeUtc > (now - 86400 | todate)) | {pipeline: $p, startTimeUtc, failureReason}'
done

Scheduled tasks

Use service-principal auth (or seed the persistent cache with one interactive sign-in under the task's account) and FABRIC_MCP_MODE=write only when the task needs it.

# Morning health check written to a share, no model involved
$env:FABRIC_AUTH_MODE = "service-principal"
fabric list-pipeline-runs --workspace BI-Prod --pipeline Nightly-Load --status Failed --top 3 --compact |
  Set-Content "\\share\reports\fabric-health-$(Get-Date -f yyyyMMdd).json"

Deployment recipes the new tools cover

Semantic model promoted through a deployment pipeline will not refresh. Every leg resets its connections to Automatic.

get_item_connections   (target model)  -> confirm paths point at the target stage, unboundCount > 0
bind_semantic_model_connection copy_from=<a bound model in the same workspace>
refresh_dataset

Git-synced model fails with "default data connection without explicit credentials".

get_dataset_datasources (a working sibling) -> gatewayId + datasourceId values
bind_dataset_to_gateway  gateway_id=... datasource_ids=[...]

Notebook just wrote to a lakehouse but the SQL endpoint still shows the old schema.

refresh_sql_endpoint_metadata --workspace W --item Lakehouse --tables dbo.lp_waterusage

Commit one item from a workspace with other people's dirty items.

get_git_status   -> see what is dirty
commit_to_git    items=["my_notebook"] comment="..."   (Selective; nothing else moves)

Development

npm test          # node --test: registry, CLI arg mapping, helpers, polling

Tools live in src/tools/*.js as plain { name, description, mode, schema, handler } objects. src/mcp/register.js wraps them for MCP; src/cli/main.js maps each schema field to a flag. Adding a tool means adding one object; both surfaces pick it up.

Security notes

  • No secrets are stored in the repo. Credentials come from environment variables at runtime; .env is git-ignored.

  • Write tools are only registered (MCP) or runnable (CLI) under FABRIC_MCP_MODE=write, and each logs an [AUDIT] line to stderr.

  • The persistent token cache uses the OS secure store via @azure/identity-cache-persistence. If the native module is unavailable the process falls back to the in-memory cache and says so on stderr.

  • list_onelake / read_onelake_file use the Azure Storage token audience; the same credential acquires it.

  • execute_dax uses the Power BI executeQueries API, which only runs read-only DAX.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI assistants to interact with Microsoft Fabric and Power BI services through the Model Context Protocol. Users can manage workspaces, execute DAX queries, refresh datasets, and create Fabric notebooks using natural language.
    6
    14 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables read-only analysis of Power BI China reports and semantic models through the China REST API, supporting report discovery, metadata retrieval, and DAX query execution.
    MIT