foundry-copilot-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@foundry-copilot-mcpAsk the agent to summarize last month's sales trends"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
foundry-copilot-mcp
Bring a Microsoft Foundry agent — and your Power BI semantic models — into GitHub Copilot Chat, over MCP.
Your agent already works in the Foundry playground. Your analysts already live in VS Code. This is the ~400 lines of glue in between, written to be read: three bridges, each one small enough to hold in your head.
Everything runs as the signed-in user, never a service principal. That is a design decision, not an omission — see Security.
The three bridges
1. A Foundry agent as a Copilot tool
The whole bridge, minus error handling:
project = AIProjectClient(endpoint=PROJECT_ENDPOINT, credential=DefaultAzureCredential())
client = project.get_openai_client(agent_name=AGENT_NAME) # pre-bound to your agent
reply = client.responses.create(input=prompt).output_textNo model name, no system prompt on the client. The instructions, tools and model deployment stay server-side in Foundry, so you change the agent in the portal and every user picks it up on their next message — no redeploy, no version drift across machines.
2. An MCP server that is also an MCP client
Plenty of people write MCP servers. Far fewer write a client — and that is where the interesting architecture lives. This server launches Microsoft's official Power BI modeling MCP server as a child process, speaks JSON-RPC to it over stdio, and re-exposes the result as one opinionated tool.
You get to add policy at the boundary: the child is launched --read-only by default, so no chain of LLM calls can quietly mutate a production model.
StdioMcpClient is generic — point it at any MCP server, not just this one.
3. Fabric GUIDs → names
The modeling server connects by name. What the user has in front of them is a Fabric URL full of GUIDs. So we resolve them against the Fabric REST API instead of asking people to go hunting for display names.
Related MCP server: Microsoft Fabric MCP Server
Tools exposed to Copilot
Tool | What it does | Writes? |
| Puts a question to your Foundry agent | no |
| Connects to a semantic model and summarises it | no |
| Shows the current DAX of one measure | no |
| Rewrites a measure | yes — needs |
| Turns the GUIDs in a Fabric URL into names | no |
Getting started
Requirements: Python 3.11+, VS Code with GitHub Copilot, az login done. Node.js only if you want the Power BI tools (it runs the official server via npx).
git clone https://github.com/Nambu89/foundry-copilot-mcp
cd foundry-copilot-mcp
python -m venv .venv
.venv/Scripts/activate # macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
cp .vscode/mcp.json.sample .vscode/mcp.json # then fill in your endpoint and agent nameCheck the Foundry connection before you trust it — and definitely before you demo it:
python -m foundry_mcp.server --selftest "Hello, who are you?"Then open VS Code, switch Copilot Chat to Agent mode, and the tools show up. Ask it something like "ask the agent what it can do" or "inspect the model in samples/sample-model".
No Foundry project yet? The Power BI and TMDL parts work standalone, and samples/sample-model is a small semantic model you can point them at.
Security
Four decisions worth copying into whatever you build:
The user's identity, not a service principal. DefaultAzureCredential and the modeling server's interactive sign-in mean every read runs as the person asking. Row-level security therefore applies. Wire a service principal in and RLS is silently bypassed — users see rows they should not, with no error to warn you. That is the quietest data leak on this list.
Read-only by default. The one writing tool (update_measure_dax) needs an explicit confirm=True, and shows the current and proposed DAX first so a human can compare them.
Validation stays with the engine. Measure updates go through the official server's measure_operations/Update, so the tabular engine rejects invalid DAX. Hand-patching TMDL text would happily write a broken model.
No secrets in the repo. Configuration is environment variables in .vscode/mcp.json, which is gitignored. Only .vscode/mcp.json.sample is tracked.
Tests
pytest21 tests, no network, no Azure, no Node.js — including fake MCP servers that exercise the real JSON-RPC framing, the notification handling and the timeout.
Talk
This repo backs a talk on connecting Microsoft Foundry agents to Copilot Chat over MCP. Slides and video will be linked here after the conference.
Licence
MIT — see LICENSE.
Available Tools
5 toolsask_agent_toolA
Ask the Microsoft Foundry agent a question and return its answer.
Use this for anything the agent is specialised in — its instructions, knowledge and tools all live server-side in Foundry, so you do not need to know how it works. Pass the user's request in plain language.
Do NOT use this to read a Power BI model: inspect_model does that directly and faster.
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It adds useful context by explaining that the agent's instructions, knowledge, and tools live server-side, so the caller does not need to understand its internals. It does not mention potential latency, side effects, or authentication requirements, but for a straightforward ask-and-answer interaction this is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core purpose is in the first sentence, followed by brief usage context and a clear exclusion. Every sentence adds value; there is no redundant or repeated information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with an output schema and few siblings, the description provides sufficient context: what it does, when to use it, how to phrase input, and when to avoid it. The explicit alternative and clear scope make it safe for an AI agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has only a `prompt` string with no description (0% coverage). The description compensates by instructing the agent to pass the user's request in plain language and clarifying that the agent handles the domain semantics. This adds meaningful guidance for the single parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Ask the Microsoft Foundry agent a question') and the result ('return its answer'). It also distinguishes itself from sibling tools by explicitly warning against using it for Power BI model reads, for which `inspect_model` is the appropriate alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells the agent when to use the tool ('anything the agent is specialised in') and how ('Pass the user's request in plain language'). It also provides an explicit exclusion: 'Do NOT use this to read a Power BI model' and names the better alternative, `inspect_model`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_modelA
Connect to a Power BI semantic model and summarise what is in it.
Accepts either a Fabric workspace and semantic model (by display name OR by the GUIDs from
the Fabric URL), or the path to a local PBIP / .SemanticModel folder.
Read-only: it never modifies the model. Authentication is the user's own, so their
permissions and row-level security apply. Run this before show_measure.
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | ||
| folder | No | ||
| workspace | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description fully carries behavioral disclosure. It explicitly states the tool is read-only ('never modifies the model'), explains authentication and row-level security implications, and mentions the summarisation behavior. No contradictions with annotations exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core purpose, followed by parameter modes and safety/usage notes. Every sentence adds value, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, usage modes, safety (read-only), authentication effects, and sequencing. The output schema exists, so return values do not need elaboration. For a tool with 3 optional parameters and two usage modes, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description compensates fully by explaining the two modes: workspace+model (by display name or GUID) or folder path. This directly maps to the three parameters (workspace, model, folder) and gives meaningful context for each.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool connects to a Power BI semantic model and summarises its contents. It distinguishes itself from siblings by explicitly noting it runs before `show_measure`, which helps differentiate it from related operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Run this before `show_measure`' indicates the appropriate timing. It also explains the two possible input modes (Fabric workspace+model or local folder), giving clear guidance on when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_fabric_idsA
Turn the GUIDs in a Fabric URL into the display names the tools need.
Use when the user pastes a Fabric Studio link instead of typing names.
| Name | Required | Description | Default |
|---|---|---|---|
| model_id | No | ||
| workspace_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden. It discloses the core conversion behavior but does not explicitly state whether the operation is read-only, requires authentication, or has any side effects. The non-destructive nature is implied but not clearly disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the verb, and every word serves a purpose. No waste or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the description covers purpose and usage, but there are gaps: parameter semantics are not explained and the return behavior is not described beyond 'display names.' The output schema exists but is not referenced or enriched. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage. The description mentions GUIDs and URLs, but it does not map workspace_id or model_id to specific URL components or explain what model_id (the optional parameter) is for. Users are left to guess parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Turn' and clearly states the resource: GUIDs in a Fabric URL converted to display names. It distinguishes this as a resolver tool from sibling tools like inspect_model or show_measure.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'when the user pastes a Fabric Studio link instead of typing names.' It does not mention when not to use or list alternatives besides the implied direct-name input, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_measureA
Show the current DAX expression of one measure, and the table it belongs to.
Call inspect_model first. Accepts Table[Measure], [Measure] or just the measure name,
so you can paste a reference straight from an analysis report.
| Name | Required | Description | Default |
|---|---|---|---|
| measure | Yes | ||
| model_label | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the dependency on inspect_model and the flexible input formats, which is useful. However, it does not explicitly state that the operation is read-only or describe any side effects, although 'Show' strongly implies non-mutating. It also omits error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, with the purpose in the first sentence and supporting details following. No redundant phrases, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately covers the main required parameter and the prerequisite call, and the output schema presumably handles return values. The only notable gap is the lack of explanation for 'model_label', but for a read-only display tool this is a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It thoroughly explains the 'measure' parameter with accepted formats. However, the optional 'model_label' parameter is not mentioned at all, leaving a gap for a two-parameter tool. The partial explanation earns a score below the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Show the current DAX expression of one measure') and the resource ('the table it belongs to'). This distinguishes it from sibling tools like 'update_measure_dax' (which modifies) and 'inspect_model' (which inspects the whole model).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit prerequisite ('Call inspect_model first') which is a clear usage guideline. It also specifies the accepted input formats, helping the agent invoke it correctly. It does not explicitly mention alternatives, but the dependency and format hints are sufficient for typical use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_measure_daxA
Write a new DAX expression for a measure. MODIFIES THE MODEL.
Read-only is the default everywhere else in this server; this is the one exception, and it is
opt-in twice over: the caller must pass confirm=True, and the user needs write access
(Contributor plus a read/write XMLA endpoint). Always show the user the current expression
with show_measure and get their agreement before calling this.
The tabular engine validates the DAX, so an invalid expression is rejected rather than saved.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| measure | Yes | ||
| model_label | No | ||
| new_expression | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully owns the behavioral disclosure. It highlights the model-modifying nature, the double opt-in (confirm flag and write access), and the validation behavior ('an invalid expression is rejected rather than saved'), providing essential context beyond any schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the core action and a prominent warning, and every sentence contributes value. It covers purpose, permissions, workflow, and validation in five sentences without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple mutation tool and the presence of an output schema, the description provides all essential context: what it does, when to use it, prerequisites, and safety behavior. The inclusion of permission requirements and validation makes it complete enough for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has zero property descriptions (0% coverage), so the description must compensate. It explicitly explains the critical confirm parameter ('must pass confirm=True') and implies measure/new_expression through the main sentence, but it does not mention model_label or provide format/syntax details. Partial coverage, not comprehensive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Write a new DAX expression for a measure.' It also clearly flags 'MODIFIES THE MODEL,' which distinguishes this from the read-only siblings like show_measure. This is unambiguous and differentiates the tool's intent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to use show_measure first: 'Always show the user the current expression with show_measure and get their agreement before calling this.' It also details the exact conditions required (confirm=True and write access), making it clear when and how to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
5 tool updates
v0.1.0- First observed
ask_agent_tool - First observed
inspect_model - First observed
resolve_fabric_ids - First observed
show_measure - First observed
update_measure_dax
TDQS
Each tool has a clear role: agent questions, model inspection, measure lookup, measure update, and ID resolution. The only potential ambiguity is ask_agent_tool could be used for model tasks, but its description explicitly directs direct inspection to inspect_model.
All tools follow a consistent verb_first snake_case pattern (ask_, inspect_, show_, update_, resolve_). Names clearly indicate action and target.
5 tools is ideal for a focused server—enough to cover core operations without bloat.
Covers inspect and update workflows for measures, but lacks create/delete measure operations. The agent can fill gaps, but as a direct tool surface it is slightly incomplete.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
- BasedashOAuthcom.basedash
Governed BI MCP. Ask questions of live company data and list workspace sources via OAuth.
Let AI agents query data and act across all your business apps via MCP.
Official Microsoft MCP Server to query Microsoft Entra data using natural language
Governed app access for AI agents: 1,000+ apps & 12,000+ tools via Code Mode MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceIntegrates Microsoft 365 enterprise data into GitHub Copilot and Claude Desktop using Microsoft 365 Copilot APIs. It enables natural language queries across SharePoint, OneDrive, emails, calendars, and Teams meetings while maintaining full enterprise permission enforcement.510MIT
- AlicenseBqualityDmaintenanceEnables 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.6222MIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Power BI and Fabric through MCP tools, including workspace discovery and semantic model queries, with an agent loop and HTTP endpoints for Next.js backends.47MIT
- AlicenseNot gradedqualityDmaintenanceEnables natural language interaction with Power BI Desktop via MCP, allowing DAX authoring, measure optimization, and model inspection.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Nambu89/foundry-copilot-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server