Learn how to build and ship a dedicated Fabric IQ declarative agent for Microsoft 365 Copilot Chat with GitHub Copilot and the Microsoft 365 Agents Toolkit.
Did you know Microsoft 365 Copilot Chat natively supports Fabric IQ? You can query your Power BI reports and semantic models right from the general chat, without any custom setup.
Ask a business question in plain English, and M365 Copilot automatically discovers the most relevant Fabric artifact you have access to, inspects its schema, runs queries, and returns a cited answer alongside your broader Microsoft 365 context.
When to build a dedicated agent
The discovery step works well and can often identify the right items on the first try, but it's not without tradeoffs. If you rely on a curated set of reports and semantic models and want fast, repeatable answers with less guesswork, we can do better. A dedicated agent lets you:
- Skip the discovery lag and ambiguity. In general chat, M365 Copilot may fan out searches across emails, Teams chats, OneDrive decks, and all your workspaces before settling on a Power BI item, adding several seconds of latency. If you have a dozen reports about "Sales" or "Revenue", it may pick the wrong one or return inconsistent answers from one day to the next. Agents let Copilot bypass tenant-wide search by routing queries to the correct report or model immediately.
- Create repeatable, controlled experiences without interference from Office content. Because general chat blends all your Microsoft 365 content, an answer might pull numbers from an outdated email thread or Word document instead of your authoritative Power BI report. Scoping the agent to your trusted Power BI reports and semantic models, and only the M365 sources you explicitly enable, ensures every user gets consistent, governed answers.
- Show native zero-prompt starters and improve follow-ups. Guide users with tailored conversation starters from the moment they open the agent. Provide them with smarter, context-aware follow-up suggestions after each answer.
- Control presentation and charting logic. You decide how metrics are defined and presented to users, how tables are formatted, and influence how charts are styled and labeled.
- Package and share easily. A declarative agent is easy to distribute across your organization in a few clicks.
In this blog post, I'll walk you through how you can create your own agent for Microsoft 365 Copilot Chat. We'll build it as a declarative agent and use GitHub Copilot to assist with the development.
How the Microsoft 365 Copilot declarative agent uses routing instructions and Fabric IQ MCP to select among sales, finance, and inventory reports or semantic models.
What we're building
Here is our AdventureWorks Insights declarative agent in action, greeting users with tailored zero-prompt conversation starters, and then answering directly from our curated Power BI semantic model:
AdventureWorks Insights declarative agent zero-prompt home screen showing tailored conversation starters.
AdventureWorks Insights declarative agent ranking five sales territories, with sales, share of all sales and a source citation.
How declarative agents work
Under the hood, a declarative agent runs on the same orchestrator and foundation models as M365 Copilot Chat. It is configured through a lightweight set of files that define: identity and behavior (name, instructions, constraints, and conversation starters), knowledge (approved grounding sources), capabilities and actions (built-in tools like Code Interpreter or MCP-based plugins), and host metadata (manifest.json and icons for packaging and distribution).
A declarative agent project is packaged from a single appPackage/ folder alongside your Agents Toolkit project configuration:
my-fabric-iq-agent/
├── m365agents.yml # Build & validate workflow
├── env/.env.dev # Environment variables
└── appPackage/
├── manifest.json # App identity & icons
├── declarativeAgent.json # Starters, capabilities & actions
├── agent_instructions.md # Routing & chart rules (max 8,000 chars)
├── ai-plugin.json # Fabric IQ MCP plugin manifest
└── color.png / outline.png # 192x192 & 32x32 iconsCopy-paste prompt to get started
You don't need to write these JSON files by hand. Unzip the starter template (.zip) (or use an empty folder), then copy the instructions below and paste them as-is into GitHub Copilot App, CLI, Claude Code, or your favorite harness. The coding agent will interview you for your target reports and preferences, inspect your schemas, and generate the entire project for you. Before you start, think about what you want your agent to do:
- Capabilities: turn on CodeInterpreter so the agent can write Python to render custom charts. If your users want to blend Power BI numbers with strategy decks or team discussions, enable OneDriveAndSharePoint, GraphConnectors, or TeamsMessages.
- Instructions, conversation starters & follow-ups: clickable starter cards that launch your most common analyses without typing, paired with instructions that guide smart follow-up suggestions and routing. See section below for how to write effective instructions.
- Connectors: during authoring, your coding agent inspects your items via the Fabric IQ MCP server (https://fabriciq.svc.cloud.microsoft/v1/mcp/fabriciq), and wires the finished agent's ai-plugin.json to the M365 Fabric IQ integration (known as AskPowerBI). You can also attach additional MCP servers or API plugins if your workflow spans other systems.
- Branding & packaging: Your agent's short name (max 30 chars), descriptions (short max 80 chars, full max 4,000 chars), two icons (color.png at 192x192 and outline.png at 32x32), and an accent color bundled into an installable M365 app package.
Instructions to copy and paste
Build a Microsoft 365 Copilot declarative agent backed by the Fabric IQ MCP server (m365agents.yml, env/.env.dev, and appPackage/: declarativeAgent.json, agent_instructions.md, ai-plugin.json, manifest.json, color.png, outline.png).
Template: Fetch https://community.fabric.microsoft.com/blog/community_blog/build-a-fabric-iq-declarative-agent-for-microsoft-365-copilot-chat/5377379 (or unzip my-fabric-iq-agent-template.zip) and reuse its JSON templates; skip external doc fetches unless troubleshooting.
Workflow:
1. Gather inputs: Ask which Power BI reports/models to include (names, URLs, or discover via Fabric IQ MCP), agent name, and optional capabilities beyond `CodeInterpreter` (`OneDriveAndSharePoint`, `TeamsMessages`, `GraphConnectors`). Wait for my reply.
2. Inspect in parallel: Call `GetReportMetadata` and `GetSemanticModelSchema` in parallel (both accept a Report GUID; use `DiscoverArtifacts` only to resolve names). Run one batched `ExecuteQuery` only if sample values or date ranges are missing.
3. Scaffold strict JSON (no `//` comments): Create `declarativeAgent.json` (v1.8, `"instructions": "$[file('agent_instructions.md')]"`, 4-6 starters), copy `ai-plugin.json` (v2.4, `AskPowerBI`) verbatim, create `manifest.json` (v1.25) + `m365agents.yml`, and generate 192x192 `color.png` & 32x32 `outline.png` (`agent_instructions.md` max 8,000 chars; `name.short` max 30; `description.short` max 80).
4. Write `appPackage/agent_instructions.md` (max 8,000 chars): (1) Artifact Routing Table with GUIDs & rules to skip `DiscoverArtifacts`, (2) 4-6 Example Questions with follow-up context, (3) Producing Answers rules, (4) Charting Guidelines (lollipop/dumbbell/line, light background, business axis titles).
5. Package & validate (min 90s timeout): Run `npx --yes @microsoft/m365agentstoolkit-cli package --env dev && npx --yes @microsoft/m365agentstoolkit-cli validate --env dev`, then help run `provision --env dev` or sideload `appPackage/build/appPackage.dev.zip`.Testing and distributing your agent
Once your files are ready, run these commands from your project root using the Microsoft 365 Agents Toolkit CLI, or ask Copilot to run them for you:
# 1. Build appPackage/build/appPackage.dev.zip (inlines agent_instructions.md)
npx --yes @microsoft/m365agentstoolkit-cli package --env dev
# 2. Validate schemas, limits & icons
npx --yes @microsoft/m365agentstoolkit-cli validate --env dev
# 3. Provision & sideload to M365
npx --yes @microsoft/m365agentstoolkit-cli provision --env dev- Test in Copilot Chat. Open m365.cloud.microsoft/chat, select your agent from the right-hand rail, and click your zero-prompt conversation starters to verify routing, citations, and chart rendering.
- Share with your team or organization. Run npx --yes Microsoft/m365agentstoolkit-cli share --scope shared to grant access to specific security groups, or submit appPackage/build/appPackage.dev.zip to the Microsoft 365 Admin Center (Settings > Integrated apps) for tenant-wide catalog deployment. Every user's queries continue to respect their individual Power BI permissions and row-level security (RLS).
Under the hood: configuring a declarative agent
This section walks you through the various files that make up a declarative agent. You don't have to understand every detail, but it's helpful to understand how the pieces fit together.
declarativeAgent.json
This is the core manifest, it defines your agent's identity and capabilities:
{
"$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.8/schema.json",
"version": "v1.8",
"name": "AdventureWorks Insights",
"description": "Answers sales, finance, and inventory questions using curated Power BI reports and semantic models.",
"instructions": "$[file('agent_instructions.md')]",
"conversation_starters": [
{"title": "Top markets by sales", "text": "Which markets bring in the most sales? Show the top five and their share of total sales."},
{"title": "Category breakdown", "text": "What product categories drive our leading market?"},
{"title": "Margin vs. stock check", "text": "Compare gross margin and current stock levels for our top product category."}
],
"capabilities": [{"name": "CodeInterpreter"}],
"behavior_overrides": {"default_response_mode": "Think deeper"},
"actions": [{"id": "fabric-iq-action", "file": "ai-plugin.json"}]
}Note: Keep JSON strict (no // comments); package inlines agent_instructions.md (max 8,000 chars).
Adding Fabric IQ connection via ai-plugin.json
The "actions" entry above points to ai-plugin.json in the same appPackage/ folder. This file connects your declarative agent to the Fabric IQ M365 MCP integration (AskPowerBI) and maps Power BI source metadata into native M365 Copilot citations and sensitivity labels. You can drop this ready-made version straight into your project:
{
"$schema": "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.4/schema.json",
"schema_version": "v2.4",
"namespace": "fabriciq",
"name_for_human": "Fabric IQ",
"description_for_human": "Answers questions grounded in curated Power BI reports and semantic models.",
"description_for_model": "Ask data questions about the Power BI artifacts in instructions. Pass artifactId from the routing table.",
"functions": [{
"name": "AskPowerBI",
"description": "Answers a Power BI report or model question via DAX. Prefer Report GUIDs; include prior context on follow-ups.",
"parameters": {"type": "object", "properties": {"artifactId": {"type": "string"}, "query": {"type": "string"}, "context": {"type": "string"}}, "required": ["artifactId", "query"]},
"capabilities": {"response_semantics": {"data_path": "$.content[*]._meta.artifact_citation", "properties": {"title": "$.Name", "subtitle": "$.Description", "url": "$.Url", "information_protection_label": "$.SensitivityLabelId", "thumbnail_url": "$.IconUrl"}}}
}],
"runtimes": [{
"type": "RemoteMCPServer",
"auth": {"type": "None"},
"spec": {
"url": "https://api.fabric.microsoft.com/v1/mcp/fabricaihub/integrations/m365",
"mcp_tool_description": {"tools": [{
"name": "AskPowerBI",
"description": "Answers a Power BI report or model question via DAX.",
"inputSchema": {"type": "object", "properties": {"artifactId": {"type": "string"}, "query": {"type": "string"}, "context": {"type": "string"}}, "required": ["artifactId", "query"]},
"annotations": {"destructiveHint": false, "openWorldHint": false, "readOnlyHint": true},
"_meta": {"variants": "Fabric.Routing.M365.V1", "microsoft/response_semantics": {"data_path": "$.content[*]._meta.artifact_citation", "properties": {"title": "$.Name", "subtitle": "$.Description", "url": "$.Url", "information_protection_label": "$.SensitivityLabelId", "thumbnail_url": "$.IconUrl", "x-ms_unique_id": "$.ArtifactId"}}}
}]}
},
"run_for_functions": ["AskPowerBI"]
}]
}How to write efficient instructions
Tip: Usually, it is best to put model-specific instructions and examples as close to the data source as possible. If your instructions are model-specific, like covering how to write DAX queries or which parts of your schema are relevant, consider adding them to the semantic model's custom instructions through Power BI's Prep data for AI experience. Keep them in your declarative agent's instructions only when you can't edit the underlying semantic model, or when you want rules that apply exclusively to this agent without changing how the model behaves elsewhere.
When you need to define behavior at the agent level, write instructions to agent_instructions.md. We will structure it around four focused blocks.
1. Build an artifact routing table
When you include exact artifact GUIDs and contents in a markdown table, the agent skips the discovery search call and routes straight to the right report or semantic model.
## Artifact Routing Table
Match the question to the right source and pass Artifact ID directly to AskPowerBI:
| Artifact Name | Type | Artifact ID | Key Content |
| :--- | :--- | :--- | :--- |
| **AdventureWorks Sales** | Report | `60763385-b565-411a-b266-05c22543d6e4` | `[Total Sales]`, `[Orders]`; `Sales Territory`, `Category`, `Fiscal Year` |
| **Global Margin Model** | Model | `14c445e9-24b5-4ded-86b4-f2e1db5b0f34` | `[Gross Margin %]`, `[COGS]`, `[Net Revenue]`; `Cost Center`, `Category` |
| **Supply Chain Tracker** | Report | `9b2184a1-4c90-4e12-8a15-7f8e9102bc31` | `[Units on Hand]`, `[Backorder Rate %]`; `Warehouse`, `Supplier` |
Routing rules:
- Sales, volume, and territory rankings to **AdventureWorks Sales**.
- Cost, profitability, and gross margin to **Global Margin Model**.
- Stock and warehouse availability to **Supply Chain Tracker**.
- Cross-domain questions to query each artifact separately and align by `Category`.2. Include example questions
Give the model a few concrete examples so it learns how to disambiguate similar metrics and carry context across turns:
## Example Questions & Routing
- "Which markets lead in sales?" to Query **AdventureWorks Sales** (`[Total Sales]` by `Sales Territory[Region]`).
- "What drives the leading market?" to Keep prior territory and period; break down `[Total Sales]` by `Product[Category]`.
- "How is gross margin trending for Bikes?" to Switch to **Global Margin Model**, keep `Category = "Bikes"`, query `[Gross Margin %]` by `Fiscal Year`.
- "What is our revenue?" to Clarify gross `[Total Sales]` (Sales report) vs. `[Net Revenue]` (Finance model).3. Define how to produce answers
Tip: Only add custom answer-formatting rules if the out-of-the-box experience does not suit your needs. Fabric IQ's built-in instructions are already tuned to provide strong defaults for grounding, charts, citations, and formatting.
If your audience requires a specific executive style, such as always leading with a one-sentence headline or suggesting cross-model follow-ups, you can layer those preferences in:
## Producing Answers
- **Lead with the headline.** Start with a one-sentence finding naming the leader, exact figure, and share of total.
- **State denominator and period.** Specify the date range and whether percentages are share of all sales or top N.
- **Suggest follow-ups.** End with 2-3 next questions grounded in your routed artifacts.4. Standardize charting logic
Because CodeInterpreter is enabled, you can instruct the agent to render clean, publication-grade visuals automatically, without the user asking for a chart:
## Charting Guidelines
- Include a chart for any comparison of 3+ items.
- **Visual forms:** Sorted horizontal lollipop for rankings, dumbbell for 2-period comparisons, line for trends.
- **Axis labels:** Use business titles (`Market`, `Sales ($M)`); never `X` or `Y`.
- **Styling:** Light background, direct data labels, quiet gridlines, and `#b11f4b` accent for the leader.(Tip: In M365 Copilot Chat, users can also open the chart menu and select Display as interactive chart for native inline hover tooltips.)