Edit

Enable your app and custom tools in Microsoft 365 Copilot

[This topic is pre-release documentation and is subject to change.]

Power Apps in Microsoft 365 Copilot lets users interact with your model-driven app directly from Copilot. When a user talks to the agent, it can surface your app's data as interactive UI, a grid for browsing records or a form for viewing, editing, or creating them, all without leaving the Copilot experience. Additionally, you can add custom MCP tools and interactive UI to the app’s declarative agent. This functionality is achieved via MCP apps which is an extension to MCP that enables MCP servers to deliver interactive user interfaces to hosts. The feature works by generating an MCP server and declarative agent from your app.

Important

  • This is a preview feature.
  • Preview features aren’t meant for production use and may have restricted functionality. These features are available before an official release so that customers can get early access and provide feedback.

Prerequisites

  • A model-driven app. Currently, this feature is only available with model-driven apps.
  • Microsoft 365 Copilot license. Required for both the maker deploying the agent and end users interacting with it.
  • Permission to upload custom apps in Microsoft Teams. Your Microsoft 365 admin might need to enable this. Check your Teams admin settings if the upload option is not visible.

Set up Power Apps in Copilot

  1. Go to Power Apps, select the environment you want, and then open the desired model-driven app.

  2. Select the App MCP icon on the left navigation bar, and then select Set up MCP. This action sets up the MCP server for the app, which provides MCP tools for Copilot conversations. This is a one-time step and may take a few seconds to complete.

    Setup app MCP for model-driven app

  3. Save and Publish the app.

  4. Select Download app package to download declarative agent generated by your app’s MCP. This package contains the agent definition, built-in tools for record and data along with the configuration needed to deploy your app’s experience to Microsoft 365 copilot.

    Download app package button from the model-driven app designer

  5. Upload the compressed file that is named similar to declarative-agent-app name.zip to Microsoft Teams or Microsoft 365 Agents:

    • Teams: Upload for personal use as a custom app in Teams. More information Upload your app in Teams
    • Microsoft 365 Agents: Publish the package for a team or group from the Microsoft 365 admin center. More information: Publish agents

You can now ask questions about the tables in the app from this declarative agent. Built-in tools can show an interactive grid for the dataset queries.

Example of viewing flights returned from the declaritive agent

Additionally, intelligent forms can be used to create, view, and edit records within the Microsoft 365 Copilot context.

Example of creating a new record from email via declaritive agent

Note

You can customize the declarative agent included in the app package at you own discretion. To reduce the possibility of unexpected behavior when using AI agents, use caution when you customize the declarative agent code. More information: Declarative Agents for Microsoft 365 Copilot.

Create custom tools

In addition to the built-in tools available within the app’s declarative agent, its functionality can be extended by incorporating custom tools and widgets. A prompt builder–based designer can be used to integrate custom MCP tools and interactive UI components into the app’s declarative agent. For example, in the Zava Airlines app, a custom tool can be added to display the flight map alongside the flight timeline as a Gantt chart in a side-by-side view.

Important

  1. Select Create custom tool under the Tools section of the App MCP tab.

  2. Provide a clear, descriptive name and description for the tool, as Microsoft 365 Copilot uses this information to determine when to invoke it.

  3. Add the instructions to output data for the tool that defaults to JSON format. You can change it to text if the tool doesn't have UX associated with it. Instructions can include queries for specific records of the table in the app or it could be an input parameter to the tool to be used in tool-chaining. Make sure to experiment and choose the right prompt AI model.

    Create a custom tool to view flight data

  4. Select Test to check and validate tool's output and then select Next. You can now create and paste optional custom HTML specific to this tool. This HTML can be created using the /generate-mcp-apps-ui skill or your own development tool. Select Save.

    Custom tool example output JSON

  5. Download the updated app package zip and upload the latest version to Microsoft Teams or Microsoft 365 agents.

  6. Invoke the tool by issuing the relevant query in the app agent to see the custom UI in action.

    Custom UI created depicting flight times

Note

You can issue '-developer on' command to Microsoft 365 Copilot to see agent debug info and tools invoked. For troubleshooting common issues, see Troubleshoot MCP apps in Microsoft 365 Copilot

Dynamic tool chaining

Tool chaining in Power Apps declarative agents uses the Microsoft 365 Copilot orchestrator to reason over user intent and dynamically invoke multiple MCP-powered actions (tools) in sequence to complete a task. The orchestrator selects, parameterizes, and executes the right combination of MCP app actions based on context and function descriptions, enabling end‑to‑end workflows across Power Apps and enterprise systems. Here’s how to create a tool with parameterized input.

  1. Select Create custom tool under the Tools section of the App MCP tab.

  2. Provide a clear, descriptive name and description for the tool, as Microsoft 365 Copilot uses this information to determine when to invoke it.

  3. In this example, we use a Sankey chart visualizer. First, define the JSON input schema required to generate a Sankey chart. Next, create a prompt for the Sankey chart visualizer tool. The tool exposes an input parameter named SankeyDiagramVisualizationInputData. This parameter is interpreted by the tool and transformed into the JSON structure expected by the visualizer. Choose a clear and descriptive input parameter name so the LLM can correctly identify and invoke the tool.

    Custom tool with tool chaining

  4. You can now create and paste custom HTML specific to this tool. This HTML can be created using the /generate-mcp-apps-ui skill or your own development tool. Select Save.

  5. Download the updated app package zip and upload the latest version to Microsoft Teams or Microsoft 365 Agents.

  6. Copilot can now use natural language queries to fetch the data and pass it to the tool for visualization. For example you can use a complex query to dynamically get inputs from the 'issues' table data and visualize them using Sankey Chart Visualizer tool.

    Sankey chart visualizer displaying issues table data.

  7. You can further refine the Sankey chart by continuing the conversation.

    Sankey chart visualizer displaying additional information from conversation.

Full screen example

In this example, an expand button is rendered only if the host supports fullscreen mode.

function renderExpandButton(app) {
  const ctx = app.getHostContext();

  // Don't render the button if the host doesn't support fullscreen
  if (!ctx?.availableDisplayModes?.includes('fullscreen')) {
    return null;
  }

  const btn = document.createElement('button');
  btn.addEventListener('click', async () => {
    const result = await app.requestDisplayMode({ mode: 'fullscreen' });
    // Always use result.mode — the host may grant a different mode than requested
    console.log('Granted mode:', result.mode);
  });
  return btn;
}

The same guard applies to any host capability. Check getHostContext() before use:

const ctx = app.getHostContext();

// Theme
if (ctx?.theme) applyTheme(ctx.theme);

// Current display mode
if (ctx?.displayMode === 'fullscreen') { /* adjust layout */ }

// Available modes
if (ctx?.availableDisplayModes?.includes('inline')) { /* show collapse option */ }

React to capability changes at runtime via onhostcontextchanged — the host context can update after connect():

app.onhostcontextchanged = (ctx) => {
  if (ctx.theme) applyTheme(ctx.theme);
  if (ctx.displayMode) updateLayout(ctx.displayMode);
};

Using fullscreen mode with tool results

A common pattern is to switch to fullscreen automatically when the widget receives data, giving the content more space to render.

app.ontoolresult = async (result) => {
  const data = result.structuredContent;
  if (!data) return;

  // Expand to fullscreen when data arrives, if the host supports it
  const ctx = app.getHostContext();
  if (ctx?.availableDisplayModes?.includes('fullscreen') && currentMode !== 'fullscreen') {
    const granted = await app.requestDisplayMode({ mode: 'fullscreen' });
    currentMode = granted.mode;
    document.body.classList.toggle('mode-fullscreen', currentMode === 'fullscreen');
  }

  renderData(data);
};

You can also let the user decide — render into the current mode first, then offer the expand button:

app.ontoolresult = (result) => {
  const data = result.structuredContent;
  if (!data) return;

  renderData(data);        // render in whatever mode is active
  updateExpandBtn();       // show the expand button now that there is content
};

Generate MCP app widgets with AI code generation tools

FAQ for Power Apps in agents