Build a Microsoft 365 Copilot Agent with Power Automate HTTP Trigger Using Agents Toolkit
Introduction
Refer to blog post Triggering a Power Automate HTTP Trigger from External Applications - testing with Postman for the initial Power Automate flow set up and testing with Postman. In this post, I’ll show you how to build a Microsoft 365 Copilot declarative agent that invokes a Power Automate flow with an HTTP trigger using Microsoft 365 Agents Toolkit. This approach enables you to extend Copilot’s capabilities by orchestrating complex workflows without writing custom code.
The Power Automate HTTP trigger is particularly useful for triggering business process automation from Declarative Agent providing easy integration with other applications.
Architecture Overview
The solution consists of:
- Power Automate Flow - A cloud flow with a
When an HTTP request is receivedtrigger - Entra ID App Registration - OAuth2 authentication for secure API access
- Oauth Client registration with Teams Developer - OAuth2 authentication for secure API access within Teams Developer portal
- Microsoft 365 Agents Toolkit - TypeSpec-based agent configuration
Refer to blog post Triggering a Power Automate HTTP Trigger from External Applications - testing with Postman for the initial Power Automate flow set up and testing with Postman for steps 1 and 2.
Step 3: Oauth Client registration in Teams Developer Portal
In the Teams Developer Portal, add a new OAuth client registration with the following details:
- Registration Name: InvokePAFlow
- Base URL: https://
.09.environment.api.powerplatform.com - Restrict Usage by Org: My organization only
OAuth Settings:
- Client ID:
<Entra ID Application ID> - Client Secret:
<Entra ID Application Secret> - Authorization Endpoint: https://login.microsoftonline.com/tenantid/oauth2/v2.0/authorize
- Token Endpoint: https://login.microsoftonline.com/tenantid/oauth2/v2.0/token
- Scope: https://service.flow.microsoft.com//.default (note the double slash before “default”) otherwise you will encounter a forbidden error with a single quote.
- Client ID:
Replace tenantid with your tenantid which is a GUID.
Entra ID details:

Other details:

Step 4: Create the Agent Using Microsoft 365 Agents Toolkit
Use Visual Code with M365 Agents Toolkit extension to create a new declarative project using TypeSpec

Project Structure
src/
├── main.tsp
├── prompts/
│ └── instructions.tsp
├── actions/
│ └── invokePAFlow.tsp
├── env.tsp
└── .env.dev

The Instructions File: instructions.tsp
Define your agent’s behavior and capabilities:
namespace Prompts {
const INSTRUCTIONS = """
You are a Power Automate Flow Invocation Agent, designed to help users trigger and execute Power Automate flows efficiently.
## Core Capabilities
You can invoke the Power Automate flow by calling the invokePA action with the required parameters.
""";
}
The Main Agent Configuration : main.tsp
Configure your agent using TypeSpec:
import "@typespec/http";
import "@typespec/openapi3";
import "@microsoft/typespec-m365-copilot";
import "./actions/invokePAFlow.tsp";
import "./prompts/instructions.tsp";
import "./env.tsp";
using TypeSpec.M365.Copilot.Agents;
@agent(
"InvokePowerAutomate",
"A Microsoft 365 Copilot agent that invokes Power Automate flows with HTTP triggers."
)
@instructions(Prompts.INSTRUCTIONS)
@conversationStarter(#{
title: "Trigger a workflow",
text: "Help me trigger a Power Automate flow"
})
namespace InvokePowerAutomate {
// Expose the Power Automate flow invocation action
op invokePA is MsGraphAPI.invokePA;
}
The Action Definition : invokePAFlow.tsp
Define how to invoke the Power Automate HTTP trigger:
Replace the ${{TENANT_ID}} with Tenant ID.
Note that scopes: ["https://service.flow.microsoft.com//.default"] has double slash.
import "@typespec/http";
import "@microsoft/typespec-m365-copilot";
using TypeSpec.Http;
using TypeSpec.M365.Copilot.Actions;
@service
@server(Environment.PA_APP_SERVER_URL)
@actions(MsGraphAPI.ACTIONS_METADATA)
@useAuth(MsGraphAPI.PAAgentAuth)
namespace MsGraphAPI {
const ACTIONS_METADATA = #{
nameForHuman: "Invoke PA Flow",
descriptionForHuman: "Invoke a Power Automate flow.",
descriptionForModel: "Invoke a Power Automate flow with the specified parameters.",
};
const SERVER_URL = Environment.PA_APP_SERVER_URL;
const FLOW_URL = Environment.PA_APP_INVOKE_PATH;
/**
* Invoke a Power Automate flow
* @param body The flow parameters as JSON string
*/
@route(FLOW_URL)
@post op invokePA(
@body body: string,
@query("api-version") apiVersion: string = "1",
): {
@statusCode statusCode: 200;
@body response: string;
} | {
@statusCode statusCode: 400;
@body error: string;
} | {
@statusCode statusCode: 500;
@body error: string;
};
model PAAgentAuth is OAuth2Auth<[{
type: OAuth2FlowType.authorizationCode;
authorizationUrl: "https://login.microsoftonline.com/${{TENANT_ID}}/oauth2/v2.0/authorize";
tokenUrl: "https://login.microsoftonline.com/${{TENANT_ID}}/oauth2/v2.0/token";
refreshUrl: "https://login.microsoftonline.com/${{TENANT_ID}}/oauth2/v2.0/refresh";
scopes: ["https://service.flow.microsoft.com//.default"];
}]> { }
}
Environment Configuration File : env.dev
Update the environment file .env.dev file with the necessary configuration:
- PAAGENTAUTH_REGISTRATION_ID refers to the ID of the Oauth registration within Teams Developer Portal.
- EnvironmentID is the power platform environment id
- PA_APP_SERVER_URL and PA_APP_INVOKE_PATH refers to the base Url of the power automate flow and rest of the url respectively
The format of the Power automate flow URL copied from the trigger is
https://<environmentid>.09.environment.api.powerplatform.com:443/powerautomate/automations/direct/workflows/<workflowid>/triggers/manual/paths/invoke?api-version=1

I found the hard way while debugging with my dear friend Lee Ford that keeping the port number 443 causes the base Url mismatch and need to be omitted from the base Url.
# Built-in environment variables
TEAMSFX_ENV=dev
APP_NAME_SUFFIX=dev
# Power Automate Configuration
PA_APP_SERVER_URL=https://<EnvironmentID>.09.environment.api.powerplatform.com #note that I have omitted the :443 otherwise you may face base url incompatibility.
PA_APP_INVOKE_PATH=/powerautomate/automations/direct/workflows/<WorkflowID>/triggers/manual/paths/invoke
PAAGENTAUTH_REGISTRATION_ID=<YOUR_AUTH_REGISTRATION_ID>
# Generated during provision
TEAMS_APP_ID=<YOUR_TEAMS_APP_ID>
TEAMS_APP_TENANT_ID=<YOUR_TENANT_ID>
M365_TITLE_ID=<YOUR_TITLE_ID>
M365_APP_ID=<YOUR_APP_ID>
Deploy and Test Your Agent
Deploy the solution and test triggering the Power Automate flow.

Next Steps
- Explore Power Automate documentation
- Learn more about Microsoft 365 Agents Toolkit
Conclusion
With Microsoft 365 Agents Toolkit and Power Automate HTTP triggers, you can build powerful Copilot extensions that automate complex business processes deterministically. This approach provides flexibility, scalability, and security while leveraging your existing Power Automate investments.
By following this guide, you’ve learned how to:
- Set up a Power Automate HTTP trigger
- Configure Entra ID authentication
- Create a TypeSpec-based declarative agent
- Deploy and test your solution
- Copilot
- Microsoft 365 Agents Toolkit
- Power Automate
- HTTP Trigger
- M365 Copilot Extensibility
- TypeSpec
- Declarative Agent