Copilot Studio + Power BI
See it in action / Real M365 Copilot screenshots

Ask about your model. Get an answer.

A Copilot Studio agent with the Microsoft 365 Copilot channel configured, running inside M365 Copilot - not an Agent Builder agent. It uses model metadata to generate DAX, query Power BI as you, and explain results.

Actual user prompt: Review the Agents semantic model and provide me the top 20 used agents and their creators.
1. Ask a questionActual prompt from the published M365 test. The tested Power BI semantic model contains agents, creators and usage data.
Actual agent response excerpt showing the first eight of twenty ranked agents, creators and interaction counts; people's names masked.
2. Get a model-grounded responseActual output, cropped to the first 8 of 20 rows. People's names are masked; agent names, values and dates are unchanged. View the complete response and test notes.

Observed response, not an independent numerical audit. Experimental starter: configure your own connection, model metadata and business definitions before publishing. This website is documentation, not a live agent.

Published M365 conversations tested. A generic top-20 request returned agents and creators; a top-five follow-up matched the prior first five; advice returned explicitly unexecuted DAX. Complete redacted captures appear below. This is scoped response and consistency evidence, not universal query correctness. The earlier repeated-value concern is deferred and the combined single-turn request remains unresolved.
Built in Copilot StudioPublished through the M365 Copilot channel; not built in Agent Builder.
Existing Power BI modelQuery the semantic layer, not exported spreadsheets.
Your execution identityExplicit end-user connection, no maker fallback.
A custom example, not Microsoft Agent 365. The demonstration model/report happens to be named Agent365. It is not the Microsoft product or an official product schema. Use this pattern with other compatible Power BI models by adapting the model context, queries, configuration, and permissions.
01 / How it works

A small set of capabilities.
Many different questions.

Download simple editable diagram
Message flows through Copilot Studio and topics to the Power BI tool, Run a query against a dataset, then an explained answer. The connector executes generated DAX as the user.
Message -> Copilot Studio / topics -> Power BI tool -> answerTopics control the workflow; the embedded Run a query against a dataset connector action executes the DAX. The separate tool box makes its role visible, not a separate deployment. Detailed diagram · Editable detailed source.

A governed metadata snapshot supplies structure. The orchestrator is expected to author a new DAX table expression. Native runtime controls form a bounded execution envelope. Deployment of those pieces is not proof of successful orchestration.

Governed metadata, checked as the callerOwner-run definition preparation retains structural context. A zero-row Invoker probe gates runtime disclosure. Refresh and republish after schema changes.
Advice does not execute the business queryCompile proposed DAX and label it unexecuted. Metadata authorization may still probe Power BI. Exact existing-measure implementations are not in the snapshot.
PRESERVE

The top-100 experience

Keep the successful ranking presentation as a regression scenario, including ordering, metric definition, and all requested rows up to the limit.

GENERALIZE

Expressions, not metric templates

Generate new combinations of actual fields, measures, filters, and calculations. The input is a table expression, not every possible full DAX script.

EXPLAIN

DAX with context

Use real model names, explain filter context and time scope, and distinguish a query from a measure. Suggested code is not verified code.

Current contract: one onboarded primary model; generated table expressions, aliases/order, and scalar date bounds; up to 100 rows, 16 columns, and 256 characters per text cell with explicit truncation. No five-metric or owner-field enumeration. The local Python modules prepare metadata and native source; they are not a hosted runtime service.
02 / Example conversations

Ask for an answer. Or ask how.

Public-safe examples

Tested against a Power BI semantic model containing agents. The demonstration model includes agent inventory, creator/ownership and usage data, which is why the test questions ask about agents, creators and interactions. Copilot Studio queries that semantic model with DAX, not the report visuals. Other compatible models require their own metadata and business definitions.

User-provided Power BI Copilot interactions report showing agent usage, sessions, interaction trends and client surfaces for the semantic model used in testing.
The report behind the agent-focused exampleUser-provided view of the custom report connected to the tested semantic model. This is a Power BI report, not an agent response or a synthetic illustration. Its displayed date window differs from the conversation tests, so the totals are not a like-for-like comparison. The report and semantic model are not included in the solution ZIP.

These examples document the intended experience and evaluation criteria. Synthetic values are clearly marked; supported combinations and test status live in the source documentation.

Question -> ranked result

Keep the useful answer format

Give me the top 100 agents by usage.

Illustrative output: Agents ranked by audited Interactions for the selected period. Return every available requested row up to 100 and state the date scope.

RankAgentInteractions
1Service Desk Demo1,284
2Policy Finder Demo976
3Onboarding Demo811

Synthetic three-row excerpt only. Agent names and values are invented; this table is not test evidence.

03 / Published M365 Copilot

Real responses. Clear provenance.

Exact prompts and test observations

Actual published-channel prompts and responses. With the owner's approval, only people's names are covered in the result captures; agent names, usage figures and dates are unchanged. Composites are labeled and no replacement values are invented. Checks establish visible shape and consistency, not independently audited numerical accuracy.

Review the Agents semantic model and provide me the top 20 used agents and their creators.

Real generic top-20 request and response; people's names redacted, actual agent names, usage and dates visible.
One generic request, 20 ranked rowsCreators included, displayed usage descending and distinct. The agent declared its own 30-day default. Values were not independently audited; an extra per-row date lacked a label.
Real same-period top-five follow-up; people's names redacted, actual agent names and usage visible.
Context retained across turnsThe five agent, creator and usage triples matched the preceding first five. The agent retained the period but rendered a list rather than the requested table.
Real prompt and DAX advice explicitly labeled unexecuted.
Model-grounded DAX adviceSame-period platform comparison and filter-context explanation. Prose instead of a code block; neither semantic correctness nor business-query nonexecution was independently instrumented.
Actual current four active and three inactive topics; editor identity redacted.
Current generic capabilitiesMetadata, generated execution, advice and error handling live under Topics. Three older bounded topics remain inactive.
Actual M365 Copilot prompt and Power BI Allow or Cancel consent card.
Power BI access as the requesting userThe current published-channel consent step, not a historical tool-registration screen. Connection consent does not grant missing model permissions.
Actual GPT-5 Reasoning Preview model picker.
Rendered model selection observedGPT-5 Reasoning (Preview). Current warnings concern preview-model suitability and no formal Studio evaluation; inference telemetry is not verified.
Configuration / Native capabilities

Tools and topics, in detail.

Complete contracts and YAML

Yes, these capabilities call Power BI. They live under Topics, with embedded connector actions. There is no dedicated top-100 tool and no new tool per question. Copilot Studio selects reusable topics and fills their technical inputs from the question and verified metadata.

Get model metadata

Trigger: generative selection.

Validates the model alias, probes schema visibility as the requester, then returns the governed catalog or selected tables.

Inputs: modelAlias (String, blank defaults to primary), view (String: catalog/tables), tableNames (String: at most four verified names).

Output: metadata JSON in result, plus the shared status/visibility fields below.

Full synthetic metadata topic

Run generated DAX

Trigger: generative selection.

Requires the current-turn/user metadata gate, validates newly authored DAX and forms a bounded query. The embedded Power BI action executes it as the requesting user.

Inputs: the seven query parameters below.

Output: bounded row-envelope JSON in result, the final generatedDax and execution status.

Full synthetic execution topic

Compile DAX advice

Trigger: generative selection.

Uses the same expression contract, but compiles the proposed business query without executing it. The answer must label it unexecuted; metadata authorization may still probe Power BI.

Inputs: the same seven query parameters.

Output: proposed generatedDax and advice/status envelope, not business result rows.

Full synthetic advice topic
Generated query error · Trigger: OnError. Reports the actual error and stops rather than fabricating an answer. No declared task inputs or outputs. Full synthetic error topic.

The actual tool: Power BI > Run a query against a dataset

Connector: Power BI (shared_powerbi). Action: Run a query against a dataset. Operation ID: ExecuteDatasetQuery. These are the names to look for in Studio, not the custom topic names above. The connector executes DAX; Copilot Studio generates it.

TopicActual connector action
Get model metadataRun a query against a dataset: execute a schema-visibility probe, then return the prepared metadata snapshot. This is not a built-in metadata-discovery action.
Run generated DAXRun a query against a dataset: execute the compiled business query.
Compile DAX adviceNo connector action in this topic. Native Power Fx compiles the proposed query; the separate metadata topic may still probe Power BI.
Generated query errorNo connector action. Native error handling reports and stops.

Add the tool yourself

  1. Open your agent's Topics page and the query topic. Select + Add node > Add a tool > Connector, search for Power BI, and choose Run a query against a dataset.
  2. Create or select a Power BI connection and retain user credentials / Invoker. The requesting user needs the appropriate Read/Build permissions and connection consent.
  3. Set the fixed workspace/model and bind the query/output as shown below. Do not let the agent invent resource IDs or an impersonated user.
  4. Add the same action in the metadata topic for its generated visibility probe. Keep advice and error handling as native topic logic, not extra Power BI actions.
Action fieldQuery-topic setting
Workspace (groupid)Your authorized workspace, fixed configuration.
Dataset (datasetid)Your semantic model, fixed configuration.
Query text (query)Power Fx formula Topic.generatedDax (=Topic.generatedDax in native YAML). This is the complete compiled DAX query, not the raw tableExpression input.
Impersonate user (impersonatedUserName)Leave blank (=Blank() in YAML); execution uses the requesting user's connection.
Output (firstTableRows)Bind to Topic.RawRows. Preserve Any in the native output schema for arbitrary generated columns.

In the native action source, retain serializerSettings: ={includeNulls:false} and requestTimeoutInMilliseconds: 30000. The metadata action instead uses its prepared probe query, Topic.ProbeRows and the numeric AccessProbe output schema.

Adding the connector alone does not recreate this agent. You also need the model-specific metadata, agent instructions, topic inputs, DAX compilation/validation and result handling. Follow the complete manual wiring guide and the linked native topic source. Microsoft's topic-tool steps · Power BI action reference.

Query and advice inputs

The orchestrator fills these arguments; the user asks an ordinary business question. Workspace/model IDs and execution identity are trusted configuration, not model-authored inputs.

InputTypeContract
modelAliasStringBlank defaults to primary; only the onboarded primary alias is supported.
tableExpressionStringNew DAX table expression, not a full EVALUATE/DEFINE/ORDER BY script; maximum 12,000 characters.
columnsString1-16 distinct output aliases, comma-separated.
sortByStringDeclared aliases and asc/desc; remaining aliases break ties.
limitNumberInteger 1-100; default 20.
startDateExpressionStringOptional scalar DAX date bound, paired with end.
endDateExpressionStringOptional scalar DAX date bound, paired with start. Dates use UTC_TODAY, QUERY_START and QUERY_END.

Shared outputs

status, stage, probeResultStatus, resolvedModelAlias, error, result and generatedDax are Strings. connectorAttempted, connectorReturned and visibilityVerified are Booleans. Completion or a generated query alone does not prove execution, valid rows or semantic correctness.

Actual Studio configuration

Actual Run generated DAX topic details: model-facing execution description, status On and ask-before-running Off.
Callable execution topicThe model-facing description distinguishes execution from advice. Ask-before-running is off here; this does not bypass Power BI connection consent.
Actual tableExpression String input, dynamically filled, with a metadata-grounded DAX description and the visible display-name warning.
AI-filled DAX, not a fixed queryThe actual tableExpression input is dynamically filled. Studio's display-name warning is retained in this capture; no runtime settings were changed for documentation. The full input description and contract are in the source.
Actual Studio code editor: query bound to Topic.generatedDax, Invoker mode, ExecuteDatasetQuery, firstTableRows Any and a 30000 millisecond timeout; resource IDs masked.
Embedded Power BI action: Run a query against a datasetExecuteDatasetQuery receives Topic.generatedDax, uses Invoker mode and returns dynamic rows as Any. Null omission is explicit; rows are serialized directly. The workspace and semantic-model IDs are redacted, not replaced with fake settings.
Working demo versus downloadable starter: these are genuine captures of the configured demo. The ZIP deliberately has no live metadata or connection binding and stops before queries until customized. Follow the full import guide. Read the full agent instructions.
Scope / Discovery / Scale

Reusable execution is not
automatic model understanding.

Capability and limits guide

The primary snapshot contains 21 tables, 244 columns, 166 measure names, and 13 relationships. It is prepared metadata, not live per-turn definition discovery, complete business semantics, or verified conversational reasoning.

Importable solution available. The unmanaged starter ZIP was successfully imported as a separate unpublished agent. It intentionally contains no demo schema or connection binding and stops before queries until configured. Download, import and customize for your report/model.
DEPLOYED / SCOPED SUCCESS

Generic expression capabilities

Metadata, dated ranking and creator follow-up are user-observed working. Other question shapes still need evaluation; structural controls are not a complete DAX parser, semantic proof or cost estimator.

REQUIRES ONBOARDING

Another model's meaning

Prepare current metadata and validate permissions and semantics. No new five-metric template is intended, but changing only a dataset ID is still not a verified onboarding process.

NOT YET DEMONSTRATED

Automatic multi-model discovery

A model catalog, focused metadata retrieval, routing, schema refresh, and cross-model interpretation remain separate work. No model-count or concurrency ceiling has been measured.

Not exposed does not mean nonexistent. The generic contract no longer bans owner/creator fields. Actual schema visibility, permissions, missing metadata, and genuine absence remain distinct. The all-column metadata probe may fail closed for narrower OLS users, who can require a role-appropriate snapshot.

Second-model probe: structure discovery succeeded

A genuinely different model accepted three constant DAX queries. Its definition was retrieved automatically using the documented Fabric API: 78 tables, 694 columns, 17 measures, and 79 relationships, including hidden/generated objects.

This used existing read/write model permissions. No nonempty object descriptions were found; authored-instruction discovery remains unproven. The schema has not been wired into the agent, and this is not evidence of automatic business understanding or read-only-user metadata access.

Observed constant-query request times: 823 / 461 / 538 ms. Three sequential samples, not a benchmark, concurrency test, or complete-chat latency.

04 / What is proven

Evidence without overclaiming.

Read the verification notes

Observed and separately verified

DIRECT TESTA constant-only DAX query executed successfully against the model.
DIRECT TESTCounts and a 100-row ranking executed using the audited Interactions metric.
USER REPORTThe user confirmed they liked the top-100 output.
SCREENSHOTActive topics, AI-filled DAX input, Invoker connector configuration and published-channel consent are visible.
OFFLINEThe generic source has 54 Python tests, 5 client-harness tests, and 55 synthetic native Power Fx checks; the native null-serialization caveat is documented.
DIRECT TESTEight varied expression cases passed, including new combinations and the original ranking membership/order.
M365 UITop-20 ranking, consistent top-five follow-up and explicitly unexecuted DAX advice completed. Real redacted captures are included.

Offline/direct checks are authored fixtures. Actual caller traces established generated-query execution; later Studio and M365 responses succeeded. All displayed values are not independently audited; the earlier combined request and deferred repeated-value case remain unresolved. Missing declared fields mean DAX blank/null under the explicit null-omission policy. The rendered picker shows GPT-5 Reasoning (Preview); inference telemetry remains unverified. Current warnings concern preview-model suitability and absence of formal Studio evaluation.

Production questions still matter

Does RLS automatically make this safe?

RLS follows the actual execution identity and workspace role. Verify restricted users, Build permission, and the model's sensitive fields. Agent instructions do not enforce authorization.

Can it answer any question?

No guarantee. The generic contract removes the five-metric mapping but still requires valid metadata, permissions, supported table-expression syntax and correct reasoning. Dated ranking and creator follow-up are user-observed working; the combined request and broader question coverage remain unverified. Exact measure implementations and automatic multi-model routing are not provided.

Is Fabric capacity or MCP required?

A Fabric data agent is not required for the connector/REST route. Power BI licensing still applies. Hosted Power BI MCP is a separate optional integration; its query-generation tool has Copilot entitlement requirements.

Are these real business results?

The M365 result screenshots are real, with owner-approved agent names, usage figures and dates unchanged. People's names are masked. Separately labeled illustrative tables use invented names and numbers; they are not test evidence. Original captures and tenant configuration remain private.

05 / Import and configure

A deployable starter.
Your model's configuration.

Complete import guide
1 / IMPORT

Import into development

Download the unmanaged ZIP and import it through Power Apps or Copilot Studio Solutions. It creates a separate unpublished agent with no configured channels or bound Power BI connection.

2 / CONFIGURE

Ground it in your model

Bind an end-user connection, prepare authorized model metadata and review your metric definitions, relationships, dates and permissions. Demo report instructions and private model data are not included.

3 / VERIFY AND PUBLISH

Generate, test, then share

Generate and deploy the configured topics using the supplied source. Validate important answers independently, then publish and configure your M365 Copilot channel. The ZIP stops before queries until configured.

Reusable does not mean unlimited. One model alias is configured at a time. Missing business definitions, unsupported expressions and incorrect DAX filter context can still prevent a correct answer. Successful execution alone is not an accuracy guarantee.

Full synthetic topic YAML · Complete agent instructions · Package checksums

05 / Build on it

Source, setup, and the fine print.

Adapt the agent

Start with the sanitized source, your own provisioned agent, and an approved model contract. Bind your own connection.

Setup guide

Inspect the connector

The connector runs DAX. Model discovery, interpretation, validation, and answer quality are separate responsibilities.

Microsoft connector reference

Reviewed documentation. Clear publication boundaries.

People's names are masked in real result screenshots; agent names, usage figures and dates remain visible with owner approval. Configuration captures redact private resource IDs and identities. Illustrations are labeled synthetic. The reviewed ZIP excludes credentials, tenant bindings and the demo model. No open-source license has been selected; public visibility does not grant additional reuse rights.

Release review and limitations