Tag: Power Platform

  • Copilot Studio Hooks: Build Five Practical Customer Ops Automations

    Copilot Studio Hooks: Build Five Practical Customer Ops Automations

    Booking a service visit is only part of the job. Someone still has to confirm access, check the equipment and review the customer’s service history.

    I wanted my agent to handle that follow-up automatically. I also wanted it to route support cases using customer defaults and offer compatible parts when the requested stock wasn’t available.

    So I built a small customer operations agent in Copilot Studio, connected it to Dataverse, and added hooks around its tools. The tools save the booking, create the case and check stock. The hooks handle the shared preparation, routing and context.

    The result is five useful automations from four hook bindings. Below, I’ll walk through the setup, the logic and what happened in Preview. The solution export is linked at the end; you can follow the examples here without importing it.

    This uses the GitHub Copilot harness in Copilot Studio. It’s the agent authoring and runtime experience used for this build. Check that you have access in your environment before starting. Microsoft describes hooks as workflows called automatically when their selected event occurs. Microsoft’s hooks documentation.

    All customer and inventory data in this demo is fictional. The booking tool saves a demonstration record, so it doesn’t reserve a technician or create a calendar appointment. The support case is also a demonstration Dataverse record. I tested the published workflows through a draft agent’s Preview.

    Table of contents

    What are Copilot Studio hooks?

    A hook runs a workflow automatically at a point you choose in an agent’s conversation: when a session starts, before a tool runs, or after it finishes.

    You set two things: the event that triggers it and the workflow to run. Copilot Studio passes details about that event to the workflow and reads its response before the agent continues.

    The difference from a normal tool is what starts it. The agent chooses a tool to perform an action. A hook is triggered by its configured event, so the agent doesn’t have to choose a second tool for the follow-up.

    In this build, the agent chooses BookServiceVisit to save a booking. A Post tool use hook then checks the booking result and creates the preparation checklist for a confirmed booking. It skips rejected requests. The booking tool still owns the booking; the hook handles the follow-up.

    A Pre tool use hook does its work before the tool runs. My case-routing hook looks up the customer’s defaults and replaces the routing inputs passed to CreateSupportCase. A Start (pre-loop) hook loads the signed-in user’s work briefing before their first message.

    There are six events available in this preview:

    EventWhen it runs
    Start (pre-loop)A new conversation begins
    User prompt submittedBefore a user’s message is processed
    Pre tool useBefore a tool call
    Post tool useAfter a tool returns successfully
    After tool failureA tool returns an error
    ErrorAn error occurs outside a tool call

    You can scope tool events to selected tools. Here, the stock hook only needs stock results, and the routing hook only needs case calls. Microsoft’s hooks documentation.

    A hook can fail while the agent continues. Keep mandatory validation inside the business tool too. If a booking must be rejected, enforce that decision inside the booking tool.

    What we’ll build

    ExampleEventWhat the hook does
    Prepare a booked visitPost tool useSaves a checklist linked to the booking
    Route a support casePre tool useApplies the customer’s configured team, region and service tier
    Offer compatible stockPost tool useEnriches the shortage result with suitable alternatives
    Load a work briefingStart (pre-loop)Gives the first response relevant user context
    Build a customer timelinePost tool useRecords completed bookings and cases in one view

    The checklist and timeline use the same Post tool use workflow. That’s why there are five outcomes but four bindings. Both branches work from the original business result; they don’t depend on one hook running before another.

    One hook, from request to result

    Here’s the case-routing example before we get into the build:

    1. The agent proposes a case. It has the customer ID CUST-100, the issue “Replacement pump needs an inspection” and a request ID. It proposes a call to CreateSupportCase.
    2. The Pre tool use hook runs before that call. Its workflow looks up CUSTOMER-CUST-100 in Dataverse and finds the customer’s routing defaults.
    3. The hook returns modifiedParameters. It keeps the customer ID, issue and request ID, then adds the assigned team West Service, region West and service tier Premium.
    4. The case tool runs with those inputs. It saves the case with the supplied routing and returns the outcome.

    The hook supplies the routing. The tool creates the case. The customer just describes the problem.

    Set up the agent and data

    Create an agent in the right experience

    Sign in to Copilot Studio and select your development environment. Choose the Agent card on Home, or Agents > New agent. The current Home cards use the GitHub Copilot harness experience; Other ways to build takes you to the standard experience. Start building an agent.

    Enter the agent’s name and instructions in Build, then Save. Choose the language, solution and schema name before the first save if you need to control those settings. The schema name becomes read-only afterward. Building and testing can consume Copilot Credits. Create an agent.

    Give the agent a clear job. These are the instructions that matter for this walkthrough:

    Use BookServiceVisit for service visit requests.
    Use CreateSupportCase for support cases.
    Use CheckStock for stock availability.
    Use ReadOpsRecords to retrieve saved records and follow-up work.
    Collect the required business inputs before calling a tool.
    Hooks run automatically; do not call them as separate tools.
    Report outcomes returned by tools or saved-record lookups.
    Do not invent bookings, stock, routing values or task completion.

    Create one Dataverse table

    I used a single table called Ops Lab Records to keep the demo easy to inspect. Customer defaults, stock, bookings, cases and follow-up work all live there. In a real application, those would usually be separate business tables.

    The logical table name is fadh_opslabrecord, with entity set fadh_opslabrecords. If you use a different publisher prefix, replace fadh in the expressions below.

    ColumnTypeWhat it holds
    fadh_nameText, 850, required primary nameReadable record name
    fadh_recordkeyText, 200Stable business key
    fadh_kindText, 100stock, customerProfile, userProfile, booking, Case, checklist or timeline
    fadh_parentkeyText, 100Customer or booking this record belongs to
    fadh_customeridText, 100Customer ID
    fadh_assignedteamText, 100Assigned team
    fadh_regionText, 100Region
    fadh_servicetierText, 100Service tier
    fadh_statusText, 100Custom record status
    fadh_payloadPlain multiline text, 20,000JSON stored as text

    Create an alternate key on fadh_recordkey and wait for it to become Active. Every record shares that key space, so use prefixes: CUSTOMER-, STOCK-, BOOKING-, CASE-, CHECKLIST- and TIMELINE-. The custom status field above is separate from Dataverse’s built-in status columns. Dataverse alternate keys.

    Add a customer record with these values:

    FieldValue
    NameContoso West customer defaults
    Record KeyCUSTOMER-CUST-100
    KindcustomerProfile
    Customer IDCUST-100
    Assigned TeamWest Service
    RegionWest
    Service TierPremium

    Set Kind to stock on all four stock rows.

    Then create four stock records. Set Name and Record Key to STOCK- followed by the SKU. Paste each stock object’s JSON into Payload using this shape:

    {"sku":"KIT-A","availableQty":0,"source":"Synthetic Ops Lab","compatibleGroup":"service-kit"}
    SKUAvailable quantityCompatibility group
    KIT-A0service-kit
    KIT-B4service-kit
    KIT-C8incompatible-kit
    KIT-D1service-kit

    These quantities make the stock example useful: a part can be plentiful but incompatible, or compatible but insufficient.

    Create the business tools

    In Build, open Tools > Add > Workflow. A normal workflow starts with When an agent calls the flow and ends with Respond to the agent. Create and publish the tools before attaching their hooks. Add a workflow tool.

    ToolRequired inputsResult
    BookServiceVisitCustomer ID, date, request IDSaves a booking and returns its ID and status
    CreateSupportCaseCustomer ID, issue, request IDSaves a case; team, region and tier are optional inputs
    CheckStockSKU, quantityReturns availability and the requested quantity
    ReadOpsRecordsOptional exact key or parent keyRetrieves saved records for verification

    The saved-record lookup is used to check the results in these examples. Build ReadOpsRecords using the readback instructions below.

    For booking and case writes, use the request ID to form the stable key, check for an existing record, validate the request, save only a new valid request, then return the saved outcome. An exact repeat should return the original outcome. A changed customer, date or issue under the same request ID should be rejected as a conflict.

    Build details: Demo booking and case tool mappings

    For BookServiceVisit, the workflow is: Request → List_prior_booking → Prior → Cached → Code → Outcome → Store_new_booking → Respond. The write branch saves the new booking; the repeat and rejection branches return without another write. Set Name and Record Key to the returned bookingId, Kind to booking, Record Status to Confirmed, Customer ID to the returned customer ID and Payload to @string(outputs('Outcome')). The Text response also returns that serialized Outcome, after the write succeeds.

    For CreateSupportCase, use Request → List_case → New_case. The new-record branch builds Case_outcome, saves it through Create_case, then returns @string(outputs('Case_outcome')). The other branch returns the stored outcome for an exact repeat, or a conflict/invalid-request result. Its created response includes status: created, code: case_created, caseId, customerId, issue, requestId, assignedTeam, region, serviceTier and createdAt.

    Save the case with these mappings:

    FieldValue
    Name and Record Key@outputs('Case_outcome')?['caseId']
    Kind and Record StatusCase and Open
    Customer ID and Parent Key@outputs('Request')?['text']
    Assigned Team@coalesce(outputs('Request')?['text_3'],'')
    Region@coalesce(outputs('Request')?['text_4'],'')
    Service Tier@coalesce(outputs('Request')?['text_5'],'')
    Payload@string(outputs('Case_outcome'))

    These are the base tools the hooks expect. You can also use your existing booking and case tools, adapting the hook’s input mapping and result decoder to their contracts. The solution export includes the full demonstration tools, including their validation and replay logic.

    I tested those replay and conflict paths in the booking and case workflows. The booking’s date validation is basic; a real scheduling tool needs calendar and capacity checks inside that tool.

    Use Dataverse’s selected environment actions and choose your environment and table explicitly. The names used below are action names: rename the nodes before entering expressions that refer to them. Enter expressions through Switch to expression mode.

    Also check Code view. A friendly input label can differ from its actual property name. In this build, customerId is text, date or issue is text_1, and requestId is text_2. A Text output labelled result is internally text. Those internal names are what triggerBody() reads.

    Add the hooks

    Open More options (…) > Hooks > Create. Select the event, choose the tool scope where applicable, and create the workflow from that dialog. For tool events, leaving the Tools selection empty applies the hook to All tools. Add a hook.

    Keep the generated trigger and response fields. This caught me during the build. I added a fresh Text output labelled additionalContext, but its internal property was text. The workflow looked right and still wasn’t compatible with the hook.

    The event starter gives you the correct contract. Use its existing additionalContext, modifiedParameters or modifiedResult field. The last two are objects in the starters used here. Changing a display label won’t fix the wrong property name or type.

    These fields are the handoff between Copilot Studio and the hook workflow. The event determines which inputs and response fields are available. Here are the ones used in this build:

    FieldDirectionWhat it does here
    parametersInto the workflowThe proposed tool inputs, such as customer ID and issue.
    resultInto the workflowThe returned tool result for a Post tool use hook.
    metadataInto the workflowSession details, including the user identity used by the briefing lookup. Values can be empty.
    additionalContextBack to the agentInformation the agent can use, such as a work briefing or saved checklist reference.
    modifiedParametersBack to Copilot StudioReplaces the proposed tool inputs. Keep the existing business inputs when adding routing.
    modifiedResultBack to Copilot StudioReplaces the result the agent receives. The stock hook keeps the original result and adds alternatives.

    Returning context does not save a record by itself. The workflow’s Dataverse actions do the writes; its response tells the agent what happened.

    Configure these bindings:

    NameEventScope
    Load my work briefingStart (pre-loop)Session
    Route support cases from customer defaultsPre tool useCreateSupportCase
    Prepare bookings and log successful actionsPost tool useBookServiceVisit, CreateSupportCase
    Offer compatible stock alternativesPost tool useCheckStock

    Publish each workflow, choose Done in the hook dialog, and Save the agent. Workflow publication and agent publication are separate. I used the draft agent’s Preview for these tests. A saved but unpublished hook workflow doesn’t run. Hook publication and runtime behaviour.

    1. Book the visit and prepare the work

    The first request is simple: book a visit for CUST-100 and prepare the work that needs to happen before it.

    BookServiceVisit saves the booking. Its returned JSON includes status, bookingId, requestId, customerId and date:

    {
    "status": "confirmed",
    "code": "confirmed",
    "bookingId": "BOOKING-FAD-BOOK-20261004-01",
    "requestId": "FAD-BOOK-20261004-01",
    "customerId": "CUST-100",
    "date": "2026-10-10",
    "source": "Synthetic Ops Lab",
    "createdAt": "2026-10-04T09:18:38.9943774Z"
    }

    Now the Post tool use workflow has something concrete to act on. It checks the tool name and business status before writing follow-up work. A workflow can complete successfully while returning a rejected request, so technical success alone isn’t enough.

    • Input: The booking tool’s returned outcome.
    • Event: Post tool use.
    • Outcome: For a confirmed booking, the workflow saves a linked checklist and returns its reference through additionalContext. Rejected requests skip that work.

    Decode the result, then check it

    The real agent sends a wrapper around the tool’s JSON Text output:

    {
    "textResultForLlm": "{\"text\":\"{...business JSON...}\"}",
    "resultType": "success",
    "toolTelemetry": {}
    }
    Build details: Decode the outcome and check business success

    Add a Compose action called Outcome and decode the known booking and case results with this tested expression. It handles that runtime wrapper and the direct Text envelopes used in manual workflow tests:

    @if(or(equals(triggerBody()?['toolName'],'BookServiceVisit'),equals(triggerBody()?['toolName'],'CreateSupportCase')),json(string(coalesce(if(empty(triggerBody()?['result']?['textResultForLlm']),null,coalesce(json(triggerBody()?['result']?['textResultForLlm'])?['text'],json(triggerBody()?['result']?['textResultForLlm'])?['result'],json(triggerBody()?['result']?['textResultForLlm']))),triggerBody()?['result']?['result'],triggerBody()?['result']?['text'],triggerBody()?['result'],json('{}')))),json('{}'))

    Add an If/Else action called Successful_action. Use the following expression as the Property, Equals, and @true as the Value:

    @and(equals(triggerBody()?['event'],'PostTool'),or(empty(triggerBody()?['result']?['resultType']),equals(triggerBody()?['result']?['resultType'],'success')),not(empty(outputs('Outcome')?['requestId'])),not(empty(outputs('Outcome')?['customerId'])),or(and(equals(triggerBody()?['toolName'],'BookServiceVisit'),equals(outputs('Outcome')?['status'],'confirmed')),and(equals(triggerBody()?['toolName'],'CreateSupportCase'),equals(outputs('Outcome')?['status'],'created'))))

    Only confirmed bookings and created cases with customer and request IDs reach the write branches. If resultType is present, it must also be success.

    Save the checklist

    For BookServiceVisit, look up CHECKLIST-{requestId}. If it’s absent, create a row with Kind checklist, Status Pending, Customer ID from Outcome and Parent Key from bookingId. Set Name and Record Key using:

    @concat('CHECKLIST-',outputs('Outcome')?['requestId'])

    The checklist contains three tasks: Confirm access, Check equipment and Review service history. It’s one Dataverse row with three task objects in Payload. These aren’t three Planner tasks.

    Build details: Find or create the checklist

    Use the exact record-key filter below in List_checklist, selecting fadh_recordkey,fadh_kind,fadh_payload with a row count of 2:

    @concat('fadh_recordkey eq ',decodeUriComponent('%27'),replace(concat('CHECKLIST-',outputs('Outcome')?['requestId']),decodeUriComponent('%27'),decodeUriComponent('%27%27')),decodeUriComponent('%27'))

    Create only when length(body('List_checklist')?['value']) is zero. For the new row’s Payload, this tested expression builds the checklist and safely encodes the IDs as JSON strings:

    @concat('{"kind":"checklist","synthetic":true,"recordKey":',substring(string(createArray(string(coalesce(concat('CHECKLIST-',outputs('Outcome')?['requestId']),'')))),1,sub(length(string(createArray(string(coalesce(concat('CHECKLIST-',outputs('Outcome')?['requestId']),''))))),2)),',"bookingId":',substring(string(createArray(string(coalesce(outputs('Outcome')?['bookingId'],'')))),1,sub(length(string(createArray(string(coalesce(outputs('Outcome')?['bookingId'],''))))),2)),',"customerId":',substring(string(createArray(string(coalesce(outputs('Outcome')?['customerId'],'')))),1,sub(length(string(createArray(string(coalesce(outputs('Outcome')?['customerId'],''))))),2)),',"createdAt":',substring(string(createArray(string(coalesce(triggerBody()?['timestamp'],'')))),1,sub(length(string(createArray(string(coalesce(triggerBody()?['timestamp'],''))))),2)),',"tasks":[{"id":',substring(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-01'),'')))),1,sub(length(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-01'),''))))),2)),',"title":"Confirm access","status":"Pending"},{"id":',substring(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-02'),'')))),1,sub(length(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-02'),''))))),2)),',"title":"Check equipment","status":"Pending"},{"id":',substring(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-03'),'')))),1,sub(length(string(createArray(string(coalesce(concat(outputs('Outcome')?['requestId'],'-03'),''))))),2)),',"title":"Review service history","status":"Pending"}]}')

    Return the saved checklist key through the hook’s existing additionalContext field after the write. Keep modifiedResult empty. The agent can then use ReadOpsRecords to retrieve the checklist and report its current status.

    In Preview, the visit was confirmed, the hook returned its follow-up keys, and a record lookup found the checklist with all three tasks Pending. A repeated request in the workflow test skipped creation and preserved the existing payload.

    That last part matters. Retrying a booking should not create a second checklist or reset work somebody has already started. This demo checks for an existing key; it doesn’t reconcile that row’s contents. The unique key helps prevent duplicate rows, but the sequential replay tests don’t prove concurrent retry handling.

    A failed checklist hook also doesn’t undo the booking. If the checklist is a mandatory condition of a valid booking, put it inside the booking tool or its backend transaction.

    2. Route the case from customer defaults

    The customer knows their pump needs an inspection. They shouldn’t need to know which internal team handles Premium customers in the West region.

    The Pre tool use hook looks up CUSTOMER-CUST-100 and supplies that configuration before CreateSupportCase runs. The case tool needs only the customer’s ID, issue and request ID from the conversation.

    • Input: The proposed case call’s customer ID, issue and request ID.
    • Event: Pre tool use.
    • Outcome: modifiedParameters keeps those inputs and adds the customer’s configured routing before the case tool runs.

    Create a Dataverse List rows action called List_customer_defaults. Set row count to 1 and use:

    @concat('fadh_recordkey eq ''CUSTOMER-',replace(coalesce(triggerBody()?['parameters']?['text'],''),'''',''''''),''' and fadh_kind eq ''customerProfile''')

    The case tool’s input mapping is:

    MeaningInternal property
    Customer IDtext
    Issuetext_1
    Request IDtext_2
    Assigned teamtext_3
    Regiontext_4
    Service tiertext_5
    Build details: Merge routing into the tool inputs

    In Respond to the agent, map the existing modifiedParameters object to:

    @if(and(equals(triggerBody()?['toolName'],'CreateSupportCase'),not(empty(body('List_customer_defaults')?['value']))),union(coalesce(triggerBody()?['parameters'],json('{}')),json(concat('{"text_3":',substring(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_assignedteam'])),1,sub(length(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_assignedteam']))),2)),',"text_4":',substring(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_region'])),1,sub(length(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_region']))),2)),',"text_5":',substring(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_servicetier'])),1,sub(length(string(createArray(first(body('List_customer_defaults')?['value'])?['fadh_servicetier']))),2)),'}'))),triggerBody()?['parameters'])

    It’s a long expression because it safely quotes the configuration values. The important part is union(originalParameters, routingObject).

    modifiedParameters replaces the parameter object. Preserve the customer, issue and request ID, then add the routing values. Returning only the three new fields would lose the business inputs.

    The second object in union wins for duplicate properties. This implementation applies the configured routing even if the proposed call already contains routing values. If you want approved user overrides, implement that policy explicitly.

    For a missing profile, the workflow’s permissionDecision mapping is:

    @if(and(equals(triggerBody()?['toolName'],'CreateSupportCase'),empty(body('List_customer_defaults')?['value'])),'deny','')

    Return a helpful reason through permissionDecisionReason. The case tool in this demo allows blank routing fields. If the routing hook fails, it can therefore create an unrouted case. If routing is mandatory in your process, validate the route inside the case tool as well.

    I tested a request with just CUST-100, “Replacement pump needs an inspection” and a request ID. The Pre tool trace preserved those inputs and added West Service, West and Premium. The case tool then returned the created case.

    The useful part is that the team controls the configuration in Dataverse. The customer describes the issue. The agent doesn’t need to guess the service organisation.

    3. Give a stock shortage a useful next step

    For two units of KIT-A, the original lookup returns unavailable: zero in stock, two requested.

    The Post tool use hook checks the other maintained stock records. KIT-B is compatible and has four units. KIT-C has eight but is incompatible. KIT-D is compatible but has only one.

    • Input: The stock tool’s returned availability and requested quantity.
    • Event: Post tool use.
    • Outcome: modifiedResult adds suitable alternatives to the result the agent receives, while keeping the original availability and quantity.

    Build CheckStock

    Build details: Stock tool inputs, lookup and response

    Create required Text input sku and Number input quantity. In this build they’re text and number internally. Add Find_stock with row count 1, select fadh_recordkey,fadh_payload, and use:

    @concat('fadh_kind eq ''stock'' and fadh_recordkey eq ''STOCK-',replace(toUpper(trim(triggerBody()?['text'])),'''',''''''),'''')

    Add Stock_data Compose:

    @if(empty(body('Find_stock')?['value']),json('{"availableQty":0,"source":"Synthetic Ops Lab","compatibleGroup":"","sku":""}'),json(first(body('Find_stock')?['value'])?['fadh_payload']))

    Return this through the tool’s Text result:

    @string(union(outputs('Stock_data'),json(concat('{"status":"',if(less(triggerBody()?['number'],1),'invalidQuantity',if(empty(body('Find_stock')?['value']),'unknownSku',if(greaterOrEquals(outputs('Stock_data')?['availableQty'],triggerBody()?['number']),'available','unavailable'))),'","requestedQty":',string(triggerBody()?['number']),'}'))))

    Build the alternatives hook

    Use this node order:

    Original_stock → Approved_stock → Compatible_stock → Alternative_summary → Enriched_stock → Enriched_json_literal → Respond to the agent.

    Build details: Decode the returned stock result

    In Original_stock, decode the runtime result:

    @if(not(empty(triggerBody()?['result']?['textResultForLlm'])),json(string(coalesce(json(triggerBody()?['result']?['textResultForLlm'])?['result'],json(triggerBody()?['result']?['textResultForLlm'])?['text'],json(triggerBody()?['result']?['textResultForLlm'])))),json(string(coalesce(triggerBody()?['result']?['result'],triggerBody()?['result']?['text'],triggerBody()?['result'],json('{}')))))

    That wrapper deserves attention. My first manual hook test passed, but the first agent Preview didn’t offer alternatives. The manual input and runtime input had different envelopes. Parsing textResultForLlm and then its inner text fixed it.

    Build details: Filter alternatives and return the enriched result

    In Approved_stock, list rows with Kind stock, select fadh_recordkey,fadh_payload, and use a row count of 50 for this small demo.

    Add Filter array called Compatible_stock, From @body('Approved_stock')?['value']. Its condition is:

    @and(equals(outputs('Original_stock')?['status'],'unavailable'),not(empty(outputs('Original_stock')?['compatibleGroup'])),equals(json(item()?['fadh_payload'])?['compatibleGroup'],outputs('Original_stock')?['compatibleGroup']),greaterOrEquals(json(item()?['fadh_payload'])?['availableQty'],outputs('Original_stock')?['requestedQty']),not(equals(json(item()?['fadh_payload'])?['sku'],outputs('Original_stock')?['sku'])))

    In the native condition editor, put that expression in Property, choose Equals, and set Value to @equals(1,1).

    Add Select called Alternative_summary, From @body('Compatible_stock'), with these mappings:

    OutputExpression
    sku@json(item()?['fadh_payload'])?['sku']
    availableQty@json(item()?['fadh_payload'])?['availableQty']
    source@json(item()?['fadh_payload'])?['source']

    In Enriched_stock, preserve the original result and add alternatives, their source and checked time:

    @union(outputs('Original_stock'),json(concat('{"alternatives":',string(body('Alternative_summary')),',"alternativesCheckedAt":"',utcNow(),'","alternativesSource":"Ops Lab Records (synthetic Dataverse)"}')))

    In Enriched_json_literal, encode that result as a JSON string:

    @substring(string(createArray(string(outputs('Enriched_stock')))),1,sub(length(string(createArray(string(outputs('Enriched_stock'))))),2))

    Finally, map the hook’s existing modifiedResult object using:

    @if(not(empty(triggerBody()?['result']?['textResultForLlm'])),union(triggerBody()?['result'],json(concat('{"textResultForLlm":',substring(string(createArray(string(union(json(triggerBody()?['result']?['textResultForLlm']),json(concat('{"text":',outputs('Enriched_json_literal'),'}')))))),1,sub(length(string(createArray(string(union(json(triggerBody()?['result']?['textResultForLlm']),json(concat('{"text":',outputs('Enriched_json_literal'),'}'))))))),2)),'}'))),if(contains(coalesce(triggerBody()?['result'],json('{}')),'result'),union(triggerBody()?['result'],json(concat('{"result":',outputs('Enriched_json_literal'),'}'))),if(contains(coalesce(triggerBody()?['result'],json('{}')),'text'),union(triggerBody()?['result'],json(concat('{"text":',outputs('Enriched_json_literal'),'}'))),outputs('Enriched_stock'))))

    This puts the enriched business JSON back inside its envelope and preserves the other runtime properties, including resultType and toolTelemetry.

    Set additionalContext to: “The alternatives list is an optional recommendation from synthetic Dataverse stock records. Preserve the original stock status and quantity. No reservation has been made.” Leave output visible.

    Preview returned only KIT-B for the two-unit KIT-A request. KIT-A stayed unavailable. I also tested KIT-B for two units, which was available, and KIT-A for five units, where no alternative had enough stock. Both returned empty alternatives arrays.

    The hook makes the answer more useful without changing what the original lookup found. It doesn’t reserve stock or create an order. For a real inventory, add paging and validate whole-number quantities; this demo reads at most 50 rows and rejects quantities below one, but doesn’t reject every fraction.

    4. Start with the user’s work briefing

    An agent that already knows the user’s assigned work can get to the useful part of the conversation faster.

    • Input: The new session’s user identity metadata.
    • Event: Start (pre-loop).
    • Outcome: additionalContext gives the agent the matching work profile, its source and refresh time before the first user message is processed.

    The Start hook reads a userProfile row using the platform-supplied metadata.userAadObjectId. Inspect that field in a new Preview session’s Start event to find the identity used by your test. Create a record with Kind userProfile, Name Synthetic startup profile and Record Key USER: followed by that object ID. Use this Payload, changing the display name for your user:

    {
    "ownerDisplayName": "Josh Cook",
    "region": "West",
    "assignedTeam": "West Service",
    "serviceTier": "Premium",
    "workList": [
    {"id":"CASE-DEMO-OPEN-1","summary":"Review pump inspection","priority":"High"},
    {"id":"VISIT-DEMO-TODAY-1","summary":"Prepare service visit checklist","priority":"Normal"}
    ],
    "source": "Synthetic lab configuration"
    }

    Create List_my_briefing, row count 1, with this filter:

    @concat('fadh_recordkey eq ''USER:',coalesce(triggerBody()?['metadata']?['userAadObjectId'],'MISSING'),''' and fadh_kind eq ''userProfile''')

    In the starter’s existing additionalContext output, use:

    @if(empty(body('List_my_briefing')?['value']),concat('No trusted user work briefing found for this session. Do not invent tasks. Checked at ',utcNow()),concat('Trusted synthetic customer operations work briefing. Use only for the current session. Refreshed at ',utcNow(),'. Profile source: ',string(first(body('List_my_briefing')?['value'])?['fadh_name']),'. Work profile: ',string(first(body('List_my_briefing')?['value'])?['fadh_payload'])))

    The response includes the profile source and a refresh time. If the lookup is empty, it says no trusted briefing was found and tells the agent not to invent tasks.

    I started a new Preview chat and asked: “What is on my work list today? Show priorities, source and refresh time.” It returned the two seeded items with their priorities, source and timestamp.

    This is session context from a lookup. The two work items are seeded demonstration data, so this isn’t a live case queue or persistent conversation memory. A production version could retrieve the user’s actual work from an authorised source, with its own freshness rules.

    Also, Start has no customer prompt to inspect yet. Load user or team context here. Resolve the customer when the agent proposes a business tool. Identity metadata can be empty, particularly for unsigned-in users, so keep the empty-lookup path. Hook metadata.

    5. Keep completed actions on a customer timeline

    The case and booking belong to the same customer. Put their completed business outcomes together and the next person can see what happened without piecing together a chat.

    • Input: A confirmed booking or created case returned by its tool.
    • Event: Post tool use.
    • Outcome: The workflow saves a customer timeline entry and returns its reference through additionalContext. This shares the booking-preparation workflow from example one.
    Build details: Timeline key, lookup and record payload

    Use the Successful_action branch from example one. Before the booking-only checklist branch, look up the timeline key:

    @concat('TIMELINE-',triggerBody()?['toolName'],'-',outputs('Outcome')?['requestId'])

    Create List_timeline, select fadh_recordkey,fadh_kind,fadh_payload, row count 2. Its filter is:

    @concat('fadh_recordkey eq ',decodeUriComponent('%27'),replace(concat('TIMELINE-',triggerBody()?['toolName'],'-',outputs('Outcome')?['requestId']),decodeUriComponent('%27'),decodeUriComponent('%27%27')),decodeUriComponent('%27'))

    If no row exists, create the timeline record:

    FieldValue
    Name and Record KeyThe timeline key above
    Kindtimeline
    Customer ID and Parent Key@outputs('Outcome')?['customerId']
    Record StatusRecorded
    PayloadExpression below
    @concat('{"kind":"timeline","synthetic":true,"recordKey":',substring(string(createArray(string(coalesce(concat('TIMELINE-',triggerBody()?['toolName'],'-',outputs('Outcome')?['requestId']),'')))),1,sub(length(string(createArray(string(coalesce(concat('TIMELINE-',triggerBody()?['toolName'],'-',outputs('Outcome')?['requestId']),''))))),2)),',"toolName":',substring(string(createArray(string(coalesce(triggerBody()?['toolName'],'')))),1,sub(length(string(createArray(string(coalesce(triggerBody()?['toolName'],''))))),2)),',"occurredAt":',substring(string(createArray(string(coalesce(triggerBody()?['timestamp'],'')))),1,sub(length(string(createArray(string(coalesce(triggerBody()?['timestamp'],''))))),2)),',"actor":',substring(string(createArray(string(coalesce(coalesce(triggerBody()?['metadata']?['userAadObjectId'],'unknown'),'')))),1,sub(length(string(createArray(string(coalesce(coalesce(triggerBody()?['metadata']?['userAadObjectId'],'unknown'),''))))),2)),',"parentKey":',substring(string(createArray(string(coalesce(outputs('Outcome')?['customerId'],'')))),1,sub(length(string(createArray(string(coalesce(outputs('Outcome')?['customerId'],''))))),2)),',"outcome":',string(outputs('Outcome')),'}')

    The payload keeps the original outcome, tool name, event timestamp, customer and actor metadata. The stable key lets a sequential repeat find the same entry and skip another write.

    After the timeline branch, check whether toolName is BookServiceVisit. Only bookings reach the checklist branch. Connect every selected path to Respond after its writes, including existing-record paths; a direct shortcut to Respond can bypass the work.

    Build details: Return the completed record references

    In the shared hook’s additionalContext, return the completed record references:

    @if(and(equals(triggerBody()?['event'],'PostTool'),or(empty(triggerBody()?['result']?['resultType']),equals(triggerBody()?['result']?['resultType'],'success')),not(empty(outputs('Outcome')?['requestId'])),not(empty(outputs('Outcome')?['customerId'])),or(and(equals(triggerBody()?['toolName'],'BookServiceVisit'),equals(outputs('Outcome')?['status'],'confirmed')),and(equals(triggerBody()?['toolName'],'CreateSupportCase'),equals(outputs('Outcome')?['status'],'created')))),concat('Customer activity recorded in Ops Lab Records: TIMELINE-',triggerBody()?['toolName'],'-',outputs('Outcome')?['requestId'],if(equals(triggerBody()?['toolName'],'BookServiceVisit'),concat('. Preparation checklist: CHECKLIST-',outputs('Outcome')?['requestId'],'. Tasks: Confirm access; Check equipment; Review service history. Read the checklist row for current task statuses.'),''),'. Synthetic demonstration records.'),'')

    In Preview, I created a booking and a case for CUST-100, then retrieved records with that customer as Parent Key. Both timeline entries were there. Stock and read-only lookups aren’t in this hook’s scope, and rejected business requests skip the write branches.

    Call this a business activity timeline. It’s useful history, but it isn’t an authoritative audit trail. A hook can fail, and the timeline and checklist are separate writes. The booking and case records remain the source of truth for their business actions.

    Test the answer against the saved work

    A good-looking agent response isn’t enough to verify an automation.

    First run the whole workflow in the native designer with synthetic inputs. Check the selected branch, node inputs and outputs. Connector actions still write real rows in your selected environment. Native workflow testing.

    Then test in the agent’s Preview and inspect its activity trace: the tool selected, its parameters, the automatic hook and its returned output. That second test is what caught the stock wrapper mismatch. Test through the agent.

    Build ReadOpsRecords

    Build details: Read back the saved records

    For readback, ReadOpsRecords uses optional Text inputs parentKey and recordKey, internally text and text_1. Add Read_records, select the columns you need, order by createdon asc, row count 50, and use:

    @if(not(empty(trim(coalesce(triggerBody()?['text_1'],'')))),concat('fadh_recordkey eq ''',replace(trim(triggerBody()?['text_1']),'''',''''''),''''),if(not(empty(trim(coalesce(triggerBody()?['text'],'')))),concat('fadh_parentkey eq ''',replace(trim(triggerBody()?['text']),'''',''''''),''''),'fadh_recordkey eq ''__NO_LOOKUP__'' and fadh_recordkey ne ''__NO_LOOKUP__'''))

    Return @string(body('Read_records')?['value']) through a Text output. Exact key takes precedence; both inputs blank return []. For bookings and cases, query the returned BOOKING- or CASE- ID, rather than the unprefixed request ID.

    These are the checks I’d keep for this build:

    TestExpected result
    New booking, then exact repeatOne booking and one checklist; original outcome preserved
    Same request ID, changed date or issueConflict rejected without another business write
    Case with only the three required inputsMaintained routing supplied before tool execution
    KIT-A, quantity 2Unavailable, with KIT-B as the only alternative
    KIT-A, quantity 5Unavailable, no sufficiently stocked alternative
    KIT-B, quantity 2Available, no alternatives needed
    New chat with a matching work profileTwo seeded work items, source and refresh time
    Rejected bookingNo checklist or completed-action timeline entry

    Those paths were exercised in workflow tests or Preview as described above. Concurrent requests, write-timeout recovery and failures between the two follow-up writes need additional testing before a production deployment.

    Keep mandatory rules inside the tool

    This is the part I wouldn’t skip.

    Microsoft documents that a failed, timed-out or unreadable hook lets the agent continue as though the hook returned nothing. All response fields are optional; an empty response leaves the default behaviour. Documented failure behaviour.

    Use hooks for useful shared work, but put required validation and required business commitments inside the tool or data layer. suppressOutput controls presentation where supported. Blocking a proposed tool call uses Pre tool use and permissionDecision: "deny"; a reason alone doesn’t block it.

    I tested that distinction in a separate refund example. Its demonstration policy allows positive CAD amounts up to CAD 100. A CAD 125 request was denied by the Pre tool use hook:

    Then I deliberately failed the hook. The refund tool still rejected the request because it independently checked the policy before writing:

    The CAD 100 threshold is that demo’s policy. The lesson is where the rule lives: the required validation survives the hook’s failure. If you see isContinue in a trace, that’s runtime information, not an extra field to add to the hook response.

    Where I’d start

    Pick the next piece of work people already do by hand after an agent’s action.

    For a service team, I’d start with the booking checklist. For a support team, customer-based routing. For a parts team, compatible stock alternatives. Each gives you a result you can see and test before expanding the agent.

    Build the business tool, create the correct event starter, keep its contract, then check the actual Preview trace and saved records. Use a fresh request ID for a new action and the same ID for an intentional repeat.

    The value of hooks is that the shared process happens at the right event. A confirmed visit gets preparation work. A case reaches its configured team. A stock shortage comes back with a useful option.

    Download the solution

    This is the unmanaged Power Platform solution exported from the Customer Ops demo. It includes the agent, all four tools, four hook workflows, hook bindings, Dataverse table definitions and the connection reference.

    Download the Customer Ops solution (.zip) — version 1.0.0.1, 118 KB.

    Import the ZIP as it is; you don’t need to extract it first. Use a development environment with access to the GitHub Copilot harness preview.

    1. In Power Apps, select your development environment, open Solutions > Import solution, and upload the ZIP.
    2. Connect the Dataverse connection reference to your own connection. The workflows also keep the demo’s original environment selection: open all eight workflows and change all 13 Dataverse actions to your environment. Save and publish the workflows after those changes.
    3. Add the customer defaults and four stock records from Set up the agent and data. Add the work profile using your own session identity, as shown in example four. The solution includes the table schema, but no sample rows or saved bookings.
    4. Open the agent, check its four hook bindings against the table above, and run the Preview tests with fresh request IDs.
    After import: Dataverse actions to update
    WorkflowActions
    BookServiceVisitList_prior_booking, Save_booking
    CreateSupportCaseList_case, Create_case
    CheckStockFind_stock
    ReadOpsRecordsRead_records
    FAD Ops Route CaseList_customer_defaults
    FAD Ops After Business ActionList_timeline, Create_timeline, List_checklist, Create_checklist
    FAD Ops Load Work BriefingList_my_briefing
    FAD Ops Stock AlternativesApproved_stock

    The ZIP also contains the Refund Lab Request table schema. The separate refund agent and its workflows aren’t included.

    I checked the exported package for the components above. Importing and running it in a second environment hasn’t been verified yet.

  • AI Weekly: Copilot Studio Hooks, Lovable, and Desktop Automation

    AI Weekly: Copilot Studio Hooks, Lovable, and Desktop Automation

    Week of September 28–October 2, 2026 · Sources checked October 2

    The announcements kept coming after last week’s roundup. I’m pulling the useful changes together, with the settings, costs and limits that are easy to miss in separate launch posts.

    This week, Copilot Studio documents hooks before tool calls. Lovable adds a path for publishing internal apps to Microsoft’s runtime. SharePoint adds PDF edits, version comparisons and Teams notifications. Microsoft starts rolling out a plugin registry. GitHub Copilot can work through desktop apps and run a process you define in code.

    My bar stays the same: show me the finished task, the permissions behind it, and the bill. That is how I’d judge the new models too.

    This week in 60 seconds

    • New models: Sonnet 5.5 and GPT-6.1 Sol reach GitHub Copilot. Wednesday’s Microsoft update starts their Cowork and Copilot Studio rollout.
    • Copilot Studio hooks: Run a workflow at a lifecycle event. Check the failure behavior before relying on it to stop an action.
    • Lovable: a Microsoft-tenant publishing path. Check the plan and admin setup before building.
    • SharePoint: PDF work, file-version comparisons and Teams notifications. Some advanced features consume Copilot Credits.
    • Plugins: Admins get a registry for managing capabilities. Copilot Studio support for that registry is still future.
    • GitHub Copilot: Desktop computer use and reusable agent workflows enter public preview.
    • Admin checks: Review Copilot retention coverage, inherited code-review settings and Purview’s classic DSPM retirement window.

    Table of contents

    1. New models: separate the product, rollout and bill
    2. Copilot Studio hooks: check the call before it runs
    3. Lovable apps: who hosts them after the build?
    4. SharePoint: PDF edits and Teams notifications
    5. Plugin registry: who can use what?
    6. GitHub Copilot: desktop apps and repeatable workflows
    7. Work IQ: ask a business question, then check the records
    8. Admin dates and settings worth checking
    9. OpenAI in Teams: check the execution identity
    10. What I’d check first

    New models: separate the product, rollout and bill

    September 28–30 · Different products, different rollout stages. Claude Sonnet 5.5 and GPT-6.1 Sol are generally available in GitHub Copilot with gradual rollouts. Your plan determines which you can try.

    ModelEligible GitHub Copilot plans
    Claude Sonnet 5.5Pro, Pro+, Max, Business, Enterprise
    GPT-6.1 SolPro+, Max, Business, Enterprise
    GitHub’s published model-picker example showing Claude Sonnet 5.5.
    GitHub’s model-picker example. It illustrates the selection screen, not a performance result or availability in my account. Source. Select the image for the full-size view.

    The announcements cover the app, CLI, coding agent and supported IDEs, plus GitHub.com and mobile. Business and Enterprise admins should check their model policy: new models can become enabled under the global default.

    Wednesday’s update brings them to Cowork and Copilot Studio

    Microsoft’s September 30 announcement says both models begin rolling out in Copilot Cowork and Copilot Studio with usage-based billing. Word, Excel, PowerPoint and Chat begin a phased rollout in the coming week under the user subscription license, with limits. Access varies by license and region.

    Sonnet 5.5 also became available in Microsoft Foundry on September 28. Check Foundry availability and pricing separately from the Copilot rollout.

    GitHub reports fewer tokens and steps in its own tests. Compare the completed change. Give both models the same bug or PCF task, check the result, and compare elapsed time, retries and total credits. An answer that needs fixing still costs you time.

    HydraFusion adds another way to compare the work

    September 30 · Research preview. HydraFusion expands from CLI into VS Code and the Copilot app. It can select one model, escalate a draft, or have another model family critique it. GitHub lists Pro, Pro+, Business and Enterprise. Business and Enterprise admins must enable preview features. VS Code needs version 1.140 or later, or Insiders.

    ↑ Back to this week’s contents

    Copilot Studio hooks: check the call before it runs

    Preview documentation checked October 2 · Agents using the GitHub Copilot harness. Hooks trigger a workflow at a lifecycle event. The agent does not have to decide to call that workflow as a tool.

    Copilot Studio’s documented agent menu showing Hooks with a Preview badge.
    Microsoft’s documented agent menu shows Hooks with a Preview label. Source. Select the image for the full-size view.

    There are six events: session start, a submitted prompt, an agent error, before a tool runs, successful tool completion, and tool failure. Before a tool runs, a hook can inspect or change arguments and deny the call. Afterward, a hook can adjust the returned result or log it.

    If the hook workflow fails, times out or returns an unreadable response, the agent continues. Keep rules that must block unauthorized updates enforced in the underlying service.

    Microsoft Learn’s documented behavior when a hook workflow fails or times out.
    Official documentation captured October 1. A failed hook and a hook that explicitly denies a tool call have different outcomes. Source. Select the image for the full-size view.

    For a Dataverse pilot, log an update tool and reject a request that breaks a business rule. Then deliberately break the hook workflow and check the service’s authorization.

    ↑ Back to this week’s contents

    Lovable apps: who hosts them after the build?

    September 28 · Lovable integration; Managed Runtime is in public preview. Lovable’s announcement describes packaging an app with Microsoft’s runtime SDK and deploying it into the company’s Microsoft tenant. Microsoft introduced Copilot Managed Runtime on September 25. The runtime also powers apps built in Cowork, Code and Copilot Studio.

    Microsoft provides hosting. Entra handles sign-in, and organizational policies govern connectors, data access and endpoints. The SDK and CLI support development, deployment and versioning.

    Microsoft’s published Apps overview in the Microsoft 365 admin center for Copilot Managed Runtime.
    Microsoft’s published Apps overview. Source capture from September 25; reused for this follow-up. Source. Select the image for the full-size view.

    Hosted apps appear in Microsoft 365 admin center → Apps, where admins can review access, usage, health and policy, and enable or disable apps. The host and SDK remain in public preview.

    The Lovable setup has specific limits

    Lovable’s current setup guide spells out who can build, publish and use these apps:

    Lovable’s published walkthrough of an internal app being published to Microsoft Copilot Managed Runtime.
    Lovable’s published Runtime demonstration, September 28. Source. Select the image for the full-size view.
    • Plan and rollout: Lovable Business or Enterprise, with gradual availability. A Microsoft work account and one-time IT tenant setup are required.
    • Audience: internal organizational users with Microsoft work sign-in. Public or anonymous access is unavailable.
    • Backend: these apps use Microsoft connectors. Lovable Cloud databases, secrets and backend functions are outside this deployment path.
    • Identity: building and publishing use the Microsoft account that owns the project’s connection. Published app data access uses each end user’s sign-in.
    • Cost: the Lovable plan covers building. Running the app uses your organization’s Microsoft licensing.

    IT setup is required. The tenant admin consents to Lovable managed apps and enables Allow external artifact deployment in the target environment group. A Lovable workspace admin controls connector availability; Enterprise defaults to disabled. The setup guide distinguishes published runtime activity, which stays in Microsoft, from project source code and chat history, which stay in Lovable under its workspace settings.

    Building the screen is only the start. I’d use a small status app with test data, check access as two different users, deploy a second version and inspect consumption before handing it to a team.

    ↑ Back to this week’s contents

    SharePoint: PDF edits and Teams notifications

    October 1 update · General availability rollout started September 30. Copilot in SharePoint’s latest update covers splitting, merging and reordering PDFs, comparing file versions, restoring an earlier version, and building Teams notifications from changes in a library.

    Copilot shows the workflow plan before creation. Review the trigger, condition, card fields and Teams destination before selecting Create.

    Microsoft’s SharePoint Contracts library example with a proposed Teams notification workflow.
    Microsoft’s example shows the trigger, Active-status condition, card fields and Teams destination before creation. Source. Select the image for the full-size view.

    The result is a Teams card with contract fields and a file link. This is a notification workflow. The example does not demonstrate a completed business approval.

    Microsoft’s example Teams card showing an active contract and an Open contract button.
    The paired Teams result shows the contract’s status and an Open contract link. Source. Select the image for the full-size view.

    Teams workflows require a Microsoft 365 Copilot license and Power Automate access. Advanced Autofill, image generation/editing and site analytics also need Copilot Credits and are rolling out during October. Check that distinction before applying AI processing across a whole library.

    My first check would be the generated trigger and condition, followed by the card produced after a file changes.

    ↑ Back to this week’s contents

    Plugin registry: who can use what?

    September 30 · Rollout underway. Microsoft’s plugin registry announcement brings skills, connections and agents into a managed catalog. Admins control access under Microsoft 365 admin center → Agents → Tools.

    Microsoft’s example admin center Tools registry with Plugins, Skills, MCP servers and Connectors.
    Microsoft’s example registry. The counts and availability statuses belong to its illustrated tenant. Source. Select the image for the full-size view.

    For builders, Work IQ Developer Tools can import supported skills and MCP configurations and package them for Microsoft Copilot. The wiqd plugin commands are in public preview. Each Copilot experience supports its own capabilities; one package does not guarantee identical behavior in every app.

    Microsoft’s Work IQ MCP server policy pane showing access categories and controls.
    The announcement also shows policy controls for Work IQ MCP tools. Source. Select the image for the full-size view.

    Copilot Studio, GitHub Copilot and Microsoft Foundry support for this registry is still future in the announcement.

    Before approving a package, I’d check its instructions, connected systems and allowed users.

    ↑ Back to this week’s contents

    GitHub Copilot can now work through desktop apps

    October 1 · Public preview on Windows and macOS. Computer use is available in GitHub Copilot CLI and the Copilot app. It can inspect app content, click, type, scroll and move through a task across applications.

    The practical target is a business process stuck in software without an API, command-line interface or MCP tool. GitHub’s demonstration uses an expense-report workflow in Safari.

    Still from GitHub’s desktop computer-use demo showing Safari tool actions and its expense-report result.
    A still from GitHub’s published demo, captured October 1, showing tool actions and the reported expense result. Source. Select the image for the full-size view.

    The feature starts disabled. Turn it on in the app’s Computer Use settings or with /computer on in CLI. App permissions and enterprise policies still apply. GitHub’s documentation describes the risks of fragile interfaces, including wrong or repeated actions.

    Check the result in the destination app. The agent saying “done” is not the same as the right record being updated.

    Put recurring release checks in a workflow

    October 1 · Public preview. Dynamic workflows let you define stages in code and use agents where judgment is needed. They can run checks, work in parallel, pass structured results forward and pause for review.

    For a Power Platform pilot, I’d run a PCF build and tests, ask an agent to investigate failures, then pause for a developer to inspect the findings. Save that process and rerun it on the next change.

    The preview covers CLI, the app and SDK on all Copilot plans. CLI needs experimental features enabled. Agent, time and credit limits are documented, but the credit limit is approximate. Work already running can exceed it.

    ↑ Back to this week’s contents

    Work IQ: ask a business question, then check the records

    Preview follow-through from last Friday. Microsoft scheduled Business Applications in Work IQ to begin rolling out September 30 and continue through October. Last week’s edition covers the announcement; the current documentation explains the supported applications and agent entry points.

    For a pilot, ask which customers have an upcoming renewal and an unresolved service issue. Check the answer against the records and the asking user’s permissions. Follow the admin quickstart and review consumption alongside answer quality. Confirm that the preview is available in your environment.

    ↑ Back to this week’s contents

    Admin dates and settings worth checking

    Copilot retention: check the policy coverage

    Archived notice dated September 28 · Change scheduled for late October through mid-November. The independent reproduction of MC1481313 says some legacy Teams policies that also cover Copilot interactions will become Teams-only.

    If you depend on that implicit coverage to retain or delete prompts and responses, inspect the policy and configure the Copilot workload explicitly where required.

    Confirm the dates in your Message Center. Microsoft Learn explains policy separation; the independent archive supplies the new change schedule.

    Two follow-ups for the admin list

    • GitHub code review · Effective September 28. Inherited Default moves from Lite to Balanced for organizations and repositories. Explicit Lite stays. This was announced earlier; inspect the effective setting and consumption on a representative pull request.
    • Purview DSPM classic · November 30–December 31. Archived MC1481315 gives the retirement window for DSPM classic and DSPM for AI classic. Confirm it in your Message Center, identify affected workflows and update internal guidance using Microsoft’s task mapping.

    ↑ Back to this week’s contents

    OpenAI in Teams: check the execution identity

    September 29 · Enterprise updates. OpenAI’s release notes cover shared recurring team tasks, participation in approved Teams conversations and reusable Codex Cloud environments.

    Recurring work runs under a team service account and configured connections. The connected provider account determines access. Check that identity before attaching a task to business data.

    Shared cloud environments give coding tasks a prepared workspace. The cloud-environment documentation says browser and computer use are currently unsupported there.

    ↑ Back to this week’s contents

    What I’d check first

    • Admin: inspect Copilot retention coverage and inherited GitHub review settings. Neither depends on trying a new model.
    • Maker: pick one tool call for a hooks pilot. Test a denied call and a broken hook workflow.
    • Builder: run one recurring release check with an explicit review point. Compare a complete task, not a promising transcript.

    I want evidence that the work is right, the permissions are right, and the cost is understood. That is what I’ll check before putting any of these features into a business process.

    ↑ Back to this week’s contents

  • AI Weekly: Copilot’s Super App, Work IQ, and New Models

    AI Weekly: Copilot’s Super App, Work IQ, and New Models

    Week of September 21–25, 2026 · Updated Friday, September 25

    Microsoft’s Friday announcement takes the lead this week. The new Copilot brings Home, Code and Autopilot together. For Power Platform builders, Work IQ’s business-data preview and Copilot Managed Runtime deserve just as much attention.

    Here’s what changed this week, plus the earlier notices with rollout dates and deadlines worth keeping on your list.

    This week in 60 seconds

    • Copilot’s new app: Home(Chat+Cowork) and Code are heading into Frontier. Autopilots remains a private preview.
    • Business context: Work IQ’s Dynamics 365 and Power Platform preview starts September 30. Fabric IQ is generally available in Chat and Cowork.
    • Apps and spending: Managed Runtime enters public preview, with new controls for AI costs and model access.
    • Models: GPT-6 Sol, Luna and Claude Opus 5.5 arrived Tuesday. The prices and availability details are below.
    • Admin dates: Review advanced-package upload permissions before October 25 and GitHub’s new default feature policy before October 22.

    In this post

    Copilot’s Super App gets Home, Code and Autopilot

    September 25 · Announced, with staged previews. Microsoft’s new Copilot app makes the “Super App” idea much more concrete:

    • Home brings Chat and Cowork together, with Word, Excel and PowerPoint built into the experience.
    • Code builds apps and workflows from natural-language requests using the technology behind GitHub Copilot.
    • Autopilot, previously Scout, is a persistent cloud agent with its own identity, memory and workspace.
    Microsoft’s published Copilot Home preview showing Home, Code and Autopilot navigation and the Chat and Cowork selector.
    Microsoft’s published Home preview, not a screenshot from my tenant. Captured in Chrome, September 25, 2026. Source. Tap to enlarge.

    Home and Code start entering Frontier over the coming weeks; the Code section specifies the end of September. Autopilot expands into private preview at month-end.

    Also announced: a unified plugin registry rolling out now, Today entering private preview in October, and @Copilot in Teams entering private preview by the end of September.

    The part I want to try is moving from a conversation into an editable file or a useful app without rebuilding the context. The announcement sets that expectation; a real customer task will be the test.

    Work IQ, Fabric IQ, and a place to run the apps

    Work IQ starts using your business definitions

    September 25 · Public preview starts September 30. Business applications in Work IQ connects Dynamics 365 and Power Platform data to Copilot and agents. Rollout continues through October; Finance and Operations support is listed for late October.

    Its semantic models use selected tables and columns, relationships, views, forms and business terminology to explain what the data means. Makers can refine that context and reuse business skills across connected agents, including Copilot Studio.

    Dataverse stores the models and skills. Microsoft also introduces the Dataverse Ask API and business context through the Work IQ MCP server, CLI and coding-agent plugin. Admins still decide which environments and data participate.

    This is the preview I want to spend time with. In a custom Dataverse solution, understanding which records belong together is often the hard part. I want to see how much of that understanding carries across agents without maintaining the same explanation in every prompt.

    Fabric IQ is available in Chat and Cowork

    September 25 · Generally available. The Copilot announcement says Fabric IQ now grounds Chat and Cowork in Fabric and Power BI semantic models. Code integration follows through Frontier. This is separate from the Power BI report references coming to Notebooks below.

    Copilot Managed Runtime handles app hosting

    September 25 · Public preview. Copilot Managed Runtime provides Microsoft-operated hosting within the Microsoft 365 tenant boundary for apps built in Cowork, Code and Copilot Studio. The SDK and CLI also open that path to professional developers and compatible third-party tools.

    Microsoft’s published Apps overview screen in the Microsoft 365 admin center for Copilot Managed Runtime.
    Microsoft’s published Apps overview preview. Captured in Chrome, September 25, 2026. Source. Tap to enlarge.

    The shared runtime includes Entra identity, governed data connections, Git-backed source and version control, deployment, and an app inventory with usage and health information in the Microsoft 365 admin center.

    That gives the app-building story a useful next step: somewhere to host the result, manage access and update it after people start using it.

    Back to contents ↑

    AI spending controls and admin dates

    September 25 · New capabilities and staged rollout. Agent 365 cost management now covers Code and Managed Runtime alongside Cowork and Work IQ APIs. Copilot Studio support is planned for October.

    • Model access: controls for which model families a group can use are rolling out for Cowork, including what Auto can select.
    • Spending policies: Microsoft Graph API management and credit-request redirects can connect to existing approval workflows.
    • User visibility: Cowork users can see consumed and remaining credits and usage history inside Copilot.
    • Value reporting: new Cowork consumption views connect spending with the work produced.

    Microsoft’s pricing explanation separates the user subscription for everyday work from Copilot Credits for advanced work such as Cowork, Code and Autopilot. A user subscription is required for those capabilities. Enterprise usage-based services remain off until an admin creates a spending policy.

    Three dates for the admin list

    • September 25 / October 25 — advanced-package uploads: Microsoft’s MC1472007 notice, reproduced in a public archive, updated September 15, schedules the control from September 25. Choose all, no, or selected users/groups before October 25; otherwise advanced uploads remain allowed by default. Basic uploads are unaffected. This is a rollout reminder, not a new announcement today.
    • September 25 notice — connected A2A agents: the archived MC1478975 notice describes Agent 365 agents using Agent2Agent as connections in declarative agents. Admins install and approve them; users cannot self-install. The notice’s GA window is late August through late September, so the publication date is not the rollout start.
    • October 22 — GitHub’s default feature policy: the September 24 announcement gives Business and Enterprise admins a default for eligible generally available features. Explicit decisions stay intact and previews remain opt-in. Configure it before enforcement starts October 22.

    The two Message Center archives reproduce Microsoft’s notices but are independently operated. These dates describe Microsoft’s schedule; I haven’t confirmed the new controls in my tenant.

    Back to contents ↑

    New models, API prices and caching

    September 22 · Rolling out. Microsoft’s announcement brings GPT-6 Sol and Claude Opus 5.5 to Word, Excel, PowerPoint, Chat, Cowork, and Copilot Studio. Availability depends on licence, access, and region, so a rollout announcement doesn’t mean every tenant has both models yet.

    Microsoft’s September 22 announcement naming GPT-6 Sol and Claude Opus 5.5 and the Copilot products receiving them.
    Microsoft’s announcement of the two models rolling out across Copilot. Screenshot captured September 24, 2026. Source. Tap to enlarge.

    Give both models the same account briefing or spreadsheet task, with the same source files, and compare how much correction each result needs.

    The new models and their API prices

    September 22 · Released. GPT-6 Sol and Luna add lower-cost options to the GPT-6 family. Sol is the one I’d try on everyday coding and document work; Luna’s price makes it interesting for repeated extraction or classification tasks.

    ModelInputCache readOutput
    GPT-6 Sol$2.00$0.20$10.00
    GPT-6 Luna$0.10$0.01$0.50
    Claude Opus 5.5$4.00$0.20$20.00

    Prices are USD per million tokens. OpenAI’s figures are Standard pricing for prompts with up to 272K input tokens; Anthropic’s are its standard Opus 5.5 rates. Cache writes, longer prompts, other processing tiers, and tool charges need to be checked separately. Sources: OpenAI’s September 22 API changelog and Anthropic’s launch pricing.

    OpenAI also launched both models in ChatGPT Work and Codex for Plus, Pro, Business, Enterprise, and Edu. Its launch notice says Free and Go users get Luna in the desktop app, and that the models were not yet available in Chat.

    Claude Opus 5.5 is also in Microsoft Foundry

    Microsoft lists Opus 5.5 as generally available in Foundry, hosted on Azure, with Global Standard and US Data Zone deployment offers. The published input and output rates match the $4 and $20 figures above.

    Microsoft Foundry table showing Claude Opus 5.5 pricing, cache rates, deployment offers, and general availability on Azure.
    Microsoft’s Foundry pricing and availability table for Opus 5.5. Screenshot captured September 24, 2026. Source. Tap to enlarge.

    Anthropic reports that Opus 5.5 costs about 40% less than Opus 5 on its typical test workloads at default settings. The input and output token prices fell 20%; the larger workload saving also depends on efficiency. I wouldn’t put a flat 40% saving into a project estimate.

    GPT-6 caching and repeated input costs

    September 22 · API update. OpenAI’s prompt-caching post explains improvements to how GPT-6 reuses repeated context. Eligible shared prompt prefixes reused within 30 minutes can receive cache discounts, with savings of up to 90% on cached input tokens.

    That percentage applies to cached input, not the whole bill. Output tokens and other charges still count.

    The post also covers a caching dashboard, diagnostics for missed cache reuse, and explicit breakpoints for choosing which part of a prompt to cache. It describes ways to change reasoning effort and tool availability while keeping earlier context reusable.

    For an agent that carries the same instructions and tool definitions through dozens of calls, I’d look at cache hit rates before cutting useful context just to save tokens.

    Back to contents ↑

    Cowork browser controls

    Microsoft’s MC1474461, published September 19, schedules controls for specific users or groups in mid-to-late September. Browser use is off by default.

    Cowork uses a hidden tab in your local Edge browser and your existing signed-in session. Cookies, credentials and session tokens stay on the device. Microsoft documents browser automation for Cowork on the web in Edge; desktop and mobile do not support this capability.

    Microsoft Learn table showing Cowork browser support in Edge on the web and the requirements for browser use.
    Microsoft Learn’s browser support table and requirements for Cowork. Documentation screenshot captured September 22, 2026. Source. Tap to enlarge.

    The browser documentation explains handbacks for sign-in, MFA and CAPTCHA. Admin guidance covers Conditional Access, DLP, auditing and usage-based consumption.

    Start with a small group and an approved test system. Exercise the approval step, interrupt a run, then inspect the audit and consumption records. Browser permission and general Cowork access through spending policies are separate controls; a pilot needs both.

    Check your old Dataverse discovery calls

    MC1474128 sets September 21, 2026 as the end-of-support date for the legacy Global Discovery Service REST API and says the affected endpoints will no longer be available.

    Search custom environment selectors, admin utilities and older integration or ALM scripts for globaldisco.crm.dynamics.com.

    For Git-tracked files, run git grep -n -F 'globaldisco.crm.dynamics.com'. Also review deployed configuration and scripts stored outside the repository.

    Microsoft points custom integrations to the Power Platform List Environments API, with token scope:

    https://api.powerplatform.com/.default

    Check Entra permissions, authentication and response mapping, then test the migration.

    The notice excludes Dataverse Developer Tools such as the CRM SDK and connectors. Focus on custom REST calls to the affected endpoints.

    MC1474128 retirement notice showing affected Global Discovery REST endpoints, the developer-tool exclusion, and migration steps.
    Public reproduction of MC1474128 on MS Message Center, an independent archive. The notice identifies the affected endpoints and migration steps. Source. Tap to enlarge.

    The independent archive reproduces the dated notice. Microsoft’s older discovery documentation still shows the retired endpoints; I haven’t tested whether they remain reachable.

    Back to contents ↑

    Copilot Studio costs need to be visible while we build

    Agents using the GitHub Copilot harness can consume credits during building, testing, evaluations, and runtime, according to Microsoft’s current guidance. A Microsoft 365 Copilot licence doesn’t cover that usage.

    Microsoft Learn table explaining when Copilot Studio features consume Copilot Credits and whether a Microsoft 365 Copilot licence covers usage.
    Microsoft’s current Copilot Credits billing table. This is documentation; the new cost views discussed below are still roadmap items. Source. Tap to enlarge.

    The useful distinction is how much went on production, testing or evaluations.

    These roadmap items were added earlier in September and remain on my watchlist. Microsoft plans to show costs in three places:

    Roadmap itemWhat it is intended to show
    571194: Preview Chat and HistoryConsumption associated with preview/testing and historical runs.
    571195: Agent EvaluationsCosts for evaluation generation, test execution, and model grading.
    571196: MonitorPer-agent costs and an estimated split across authoring, testing, evaluations, and production.

    The archived entries are marked In development, with a September 2026 target. I couldn’t confirm the individual records on the live roadmap, so I’m treating them as planned features.

    You can check the Microsoft roadmap using those IDs. Archived copies of Microsoft’s text are linked in the sources below.

    Until the cost views arrive

    Keep track of what you change between test runs. When the cost views become available, that record should help explain why one run cost more than another.

    Microsoft already documents monthly agent limits with Stop usage and environment capacity settings. Disabling access to unallocated prepaid capacity won’t stop consumption through a linked pay-as-you-go plan.

    I covered the Cowork reporting side in my first-month admin guide. For Copilot Studio, I’d include development and testing when working out what an agent costs.

    Power BI reports are coming to Copilot Notebooks

    The September 19 notice MC1474458 says users will be able to add Power BI reports as references alongside files for summaries, presentations and briefs.

    • Public preview: late September through mid-October 2026.
    • General availability: late October through mid-November 2026.

    The notice says no extra setup is needed beyond users already having Power BI and Copilot. These are planned windows, separate from Friday’s Fabric IQ availability in Chat and Cowork.

    Public archive of MC1474458 announcing Power BI report references in Copilot Notebooks, with planned preview and general availability timing.
    MC1474458 in the independent Microsoft 365 Message Center Archive. Announcement screenshot showing planned rollout timing, captured September 22, 2026. Source. Tap to enlarge.

    For an account review, try a sales report, account plan and meeting notes in one Notebook. Ask for performance changes, outstanding commitments and source citations. Compare the output with the report and repeat with users who have different permissions. Adding a reference should not be treated as unrestricted access to its underlying datasets.

    More for builders: Foundry, WebMCP and reusable context

    DeepSeek-V4.1-Flash: check the deployment path

    September 23. Microsoft’s Foundry announcement describes DeepSeek-V4.1-Flash with text and image input, up to one million tokens of context, and adjustable reasoning effort. The availability labels differ: Direct from Azure is in public preview; Fireworks on Foundry is generally available.

    The same post announces a Global deployment option for GLM-5.3-Flash through Fireworks and adds Global deployment for Kimi K3 alongside its existing Data Zone option. Those choices can affect where and how a model is deployed, so I’d check the model card before comparing prices.

    Edge’s WebMCP implementation is ready for testing

    September 21 · Early testing. Microsoft’s Edge developer update says developers can try its WebMCP implementation. It lets a website expose structured tools that a browsing agent can call using the site’s existing front-end code. Microsoft has samples and an extension for testing and debugging those tools.

    This caught my attention for business portals. A site could describe an action explicitly instead of relying on the agent to work out every step from the page. It’s something to experiment with; the announcement isn’t a claim of built-in Power Pages support.

    Microsoft’s governance guidance looks beyond the agent inventory

    September 22 · Guidance. In a Copilot Studio post ahead of October’s Power Platform Conference, Microsoft argues for monitoring changes in agent ownership, access, usage, cost, and behaviour, then responding according to risk. It discusses Agent 365 and automating decisions that already have a defined policy.

    How V7 gives agents reusable context

    OpenAI’s September 21 V7 case study looks at a problem that comes up in agent design: how to reuse information from company files across tasks.

    V7 uses GPT-5.6 Luna to extract information from files into a Context Graph connecting entities, relationships, and cited evidence. Agents can query that context through MCP, with stronger models used for harder reasoning.

    V7 reports Astra reaching 89% accuracy versus Sol’s 78% on its hardest graph-query tests. Those are customer-reported results in an OpenAI case study, not a general accuracy guarantee.

    OpenAI’s September 21, 2026 case study, How V7 gives AI agents institutional memory, with the V7 logo and customer-reported 89 percent result.
    OpenAI’s September 21 V7 case study. The performance figures are customer-reported results from that case study. Source. Tap to enlarge.

    For a Dataverse project, I’d take that as a design prompt: how should an agent connect a record to its supporting documents and show the evidence behind an answer?

    Back to contents ↑

    My take on the week

    The new Copilot app is the headline. Work IQ is where I want to dig deeper: a custom Dataverse solution has business meaning in its relationships, forms and views, and I want to see how well agents can reuse it.

    Managed Runtime also makes the app story more interesting. Once someone builds a useful tool, hosting, access and updates become ongoing work. Having those pieces connected to Microsoft 365 could make a real difference.

    The model releases still deserve testing, and the Dataverse retirement still needs attention. But Friday changed the focus of this edition. Next week, I’m watching what actually arrives in Frontier and the September 30 Work IQ preview.

    Sources

    Message Center links require an authorized Microsoft 365 admin account. Public archives below reproduce the original notices or roadmap entries but are not Microsoft-operated sites.

  • Copilot Cowork /goal Prompt Vault:

    Copilot Cowork /goal Prompt Vault:

    I’ve been using Copilot Cowork since March, and the biggest lesson is simple: stop treating it like a chat box.

    Give it a real goal.

    The /goal skill is where Cowork gets serious. When you point it at the right files, context, assets, and instructions, it can move from “give me ideas” to “go figure this out, build the plan, show me the sources, and wait for approval.”

    Each prompt will include the use case, the exact prompt, the expected result, and the follow-up prompts you can use to push Cowork further.

    1. Prompt #1 — Create an Organization Branding Kit
    2. Prompt #2: Find Copilot-Only Automation Use Cases from Work IQ

    Prompt #1 — Create an Organization Branding Kit

    Use case

    Use this when you want Copilot Cowork to pull together a practical branding kit for an organization using available internal context, public website branding, existing files, logos, icons, and PowerPoint decks.

    This is useful when the organization already has branding scattered across folders, decks, documents, images, and websites, but there is no clean source of truth.

    The goal is simple: get Cowork to discover what already exists first, then build the branding kit from real assets instead of guessing.

    The /goal prompt

    /goal Create a complete branding kit for [Organization Name].
    Use all available context you can access, including internal files, shared documents, PowerPoint decks, Word documents, PDFs, images, logos, icons, and the organization’s public domain: [Website URL].
    Your first job is discovery.
    Look for:
    - Existing logos and icon files
    - PNG and JPEG image files containing official logos, icons, or brand graphics
    - PowerPoint decks that appear to be templates or close to templates
    - Sales decks, pitch decks, marketing decks, one-pagers, proposals, product sheets, and internal documents
    - Existing colors, fonts, layouts, screenshots, visual patterns, and repeated design styles
    - Website branding, tone, product language, and positioning from the public domain
    Asset handling guardrails:
    - Do not recreate, redraw, regenerate, restyle, or reimagine any existing logo or icon.
    - Use the actual existing image assets when they are available.
    - Prefer the original PNG or JPEG files for logos, icons, and other brand images.
    - If multiple versions exist, identify the best available source file and note the others.
    - Preserve the original appearance of logos and icons, including proportions, colors, spacing, and transparency.
    - Do not generate substitute logos or substitute icons.
    - If an official asset cannot be found, clearly mark it as missing and recommend that it be provided.
    - If an asset is unclear, low quality, duplicated, or inconsistent, flag it instead of attempting to remake it.
    Do not invent brand rules. If something is not clearly available, mark it as “recommended” instead of “confirmed.”
    Create a practical branding kit that includes:
    1. Brand overview
    Summarize the organization’s visual identity, positioning, tone, and audience.
    2. Logo guidance
    Identify the available logo and icon assets, especially the PNG and JPEG files, and recommend how they should be used across slides, documents, social posts, and web assets.
    3. Color palette
    Extract or infer the main brand colors from existing assets. Include hex codes when possible. Separate confirmed colors from recommended supporting colors.
    4. Typography guidance
    Identify any fonts used in existing materials if possible. If the fonts are unclear, recommend a clean Microsoft-friendly font stack that matches the brand.
    5. Presentation style
    Review existing PowerPoint decks and identify the best deck or slides to use as the closest template. Explain what makes it the best starting point.
    6. Slide design rules
    Create clear rules for title slides, section dividers, content slides, screenshots, diagrams, callout slides, and closing slides.
    7. Icon and image style
    Define the icon style, image style, screenshot style, and visual treatment the organization should use consistently, based only on existing assets and patterns you find.
    8. Voice and tone
    Define how the organization should sound in external content, internal content, sales material, and social posts.
    9. Reusable asset recommendations
    List the assets that should be created next, including PowerPoint template, Word template, social post template, proposal template, one-page product sheet, and icon set.
    10. Gaps and questions
    List anything missing, unclear, inconsistent, or worth confirming before the branding kit becomes official.
    Before creating the final branding kit, show me:
    - The files and sources you found
    - Which logo and icon image files you found, especially PNG and JPEG assets
    - Which PowerPoint deck is the best starting point
    - Any assumptions you are making
    - Any missing or questionable assets
    - The proposed structure for the final branding kit
    Wait for my approval before creating the final output.

    Expected result

    Cowork should search the available context, identify the real brand assets, review existing decks and documents, and build a branding kit grounded in what already exists.

    The important part is that it should separate confirmed brand rules from recommended brand rules.

    • Confirmed means Cowork found evidence in the files, website, images, decks, or documents.
    • Recommended means Cowork is filling a gap based on the closest available context.

    That distinction matters because branding work can go sideways fast when the AI starts inventing things. The prompt forces Cowork to find the source material first, flag gaps, and wait for approval before creating the final output.

    The guardrails around logos and icons are also important. Cowork should use the actual image files where possible. It should not recreate or redesign official assets.

    How to extend / prompt more

    Once Cowork creates the first version of the branding kit, keep driving it with follow-up prompts like these:

    Add this <logo.png> as the main logo for the branding kit. Use the actual image file. Do not recreate, redraw, or modify the logo.
    Use this <icon.png> as the primary app or product icon. Keep the original proportions, colors, and transparency.
    Using this brand kit, generate a new Word template I can use for general letter headings.
    Using this brand kit, create a Word proposal template with a cover page, section headings, body styles, callout sections, and a closing page.
    Using this brand kit, create a PowerPoint template structure with a title slide, section divider, agenda slide, content slide, screenshot slide, quote or callout slide, and closing slide.
    Use this existing <presentation.pptx> as the closest visual reference and create a cleaner template based on its style.
    Create a one-page brand cheat sheet for employees that shows the logo usage, colors, fonts, tone, and common do and don’t rules.
    Create a social post template guide using this branding kit for LinkedIn and X.
    Create a reusable prompt I can paste into Cowork any time I want it to generate on-brand content for this organization.
    Create a list of missing brand assets I should upload next, including logo formats, icons, PowerPoint templates, Word templates, screenshots, and product images.
    Create a lightweight version of this branding kit for sales, delivery, and support teams.
    Review this generated template against the branding kit and tell me what is off-brand before I use it.

    Final note

    This is where Copilot Cowork starts to become more than a chat experience.

    You are giving it a goal, pointing it at real organizational context, adding guardrails, and forcing it to work from actual assets.

    That is how you get better output.


    Prompt #2: Find Copilot-Only Automation Use Cases from Work IQ

    This prompt is designed for Copilot Cowork when you want to look across your Microsoft 365 work patterns and find practical automation opportunities that can be handled with Copilot first.

    The key constraint is important:

    The first three use cases must be possible using only Copilot.

    No Power Automate. No Azure. No custom code. No developer work.

    Then the prompt asks for one bonus use case where Power Automate is allowed, but only if the workflow truly needs a trigger, system action, approval, notification, or reliable automation beyond what a prompt can do.

    This is a strong Frontier grace period test because it helps you answer a very practical question:

    What recurring work can we improve with Copilot alone before we start building anything heavier?

    What this /goal does

    • Looks for recurring work patterns across Microsoft 365
    • Identifies repeated meeting prep, follow-ups, updates, summaries, and content work
    • Shortlists possible Copilot-only automation use cases
    • Selects the top 3 practical use cases
    • Builds setup blueprints for each one
    • Drafts scheduled prompts, Cowork skill drafts, /goal workflows, or Copilot Chat prompts
    • Adds one bonus Power Automate use case where automation is actually justified

    The /goal prompt

    /goal
    Analyze my Work IQ and Microsoft 365 work patterns to identify the top Copilot-only automation use cases.
    Purpose:
    I want you to look deeply at my available Microsoft 365 work context and Work IQ signals to find the best recurring work patterns that can be improved using only Microsoft 365 Copilot and Copilot Cowork.
    This should not be a generic brainstorm.
    I want practical use cases that can be implemented with Copilot capabilities only, such as:
    - Microsoft 365 Copilot scheduled prompts
    - Copilot Cowork skills
    - Copilot Cowork /goal workflows
    - Microsoft 365 Copilot Chat prompts
    - Copilot agents where available
    For the first 3 use cases, do not require Power Automate, Azure, custom code, external connectors, or developer work.
    After the top 3 Copilot-only use cases, include a 4th bonus use case where Power Automate is allowed.
    Primary goal:
    Find the top 3 recurring work patterns that can be improved using only Copilot, then create a practical setup plan for each one.
    Then identify one additional use case where Power Automate would be the better option.
    Important guardrails:
    - Do not force Power Automate into the first 3 use cases
    - Do not recommend custom code
    - Do not recommend Azure Functions
    - Do not recommend complex integrations
    - Do not recommend external tools
    - Do not create anything unless I approve
    - Do not schedule anything unless I approve
    - Do not send emails
    - Do not post in Teams
    - Do not modify files
    - Do not create automations
    - Clearly separate Copilot-only use cases from the Power Automate use case
    - Base recommendations on real work patterns where possible
    - If Work IQ signals are limited, use available Microsoft 365 context such as meetings, emails, chats, files, recurring collaboration patterns, and repeated tasks
    - Be practical
    - Recommend the lightest approach that solves the problem
    Step 1: Create a work plan
    Before starting, create a short work plan.
    Explain:
    - What Microsoft 365 work context you will analyze
    - What Work IQ signals you will look for
    - How you will identify repeated work patterns
    - How you will decide whether something can be handled with Copilot only
    - How you will decide whether something needs Power Automate
    - What outputs you will create
    Then proceed.
    Step 2: Analyze Work IQ and Microsoft 365 work patterns
    Review available work signals and look for recurring patterns such as:
    - Repeated meeting prep
    - Repeated meeting follow-up
    - Weekly status updates
    - Recurring stakeholder updates
    - Repeated executive summaries
    - Repeated project updates
    - Repeated customer updates
    - Repeated inbox triage
    - Repeated action item tracking
    - Repeated document drafting
    - Repeated research tasks
    - Repeated content creation
    - Repeated review workflows
    - Recurring decisions that need summaries
    - Recurring risks that need monitoring
    - Work that happens before meetings
    - Work that happens after meetings
    - Work that requires pulling context from multiple Microsoft 365 sources
    - Work that could run on a schedule
    - Work that could be standardized with a skill
    - Work that could be delegated to Cowork
    - Work that should stay lightweight in Copilot Chat
    Create a short summary of the main patterns you found.
    Step 3: Create a shortlist of Copilot-only candidates
    Create a shortlist of at least 10 possible Copilot-only use cases.
    For each candidate, include:
    - Use case name
    - Work pattern it is based on
    - Why it matters
    - Who benefits
    - Frequency
    - Business value
    - Time savings potential
    - Complexity
    - Data sensitivity
    - Best Copilot capability
    - Why this can be done with Copilot only
    - Why it does not need Power Automate
    The best Copilot capability should be one of:
    - Microsoft 365 Copilot scheduled prompt
    - Copilot Cowork skill
    - Copilot Cowork /goal workflow
    - Microsoft 365 Copilot Chat prompt
    - Copilot agent, where available
    - Combination of Copilot capabilities only
    Step 4: Select the top 3 Copilot-only use cases
    Rank the candidates and select the top 3 use cases that can be implemented with Copilot only.
    Score each candidate from 1 to 5 for:
    - Business value
    - Frequency
    - Time savings
    - Ease of setup
    - User adoption likelihood
    - Scheduled prompt fit
    - Cowork skill fit
    - Cowork /goal fit
    - Governance risk
    - Data sensitivity
    - Repeatability
    For each top 3 use case, explain:
    - Why it made the top 3
    - Why it is more valuable than the other candidates
    - Why it can be handled with Copilot only
    - Why Power Automate is not required
    - Whether the best approach is a scheduled prompt, Cowork skill, /goal workflow, Copilot Chat prompt, or combination
    Step 5: Build the setup blueprint for each Copilot-only use case
    For each of the top 3 Copilot-only use cases, create a complete setup blueprint.
    Include:
    - Use case name
    - Business problem
    - Work pattern evidence
    - Main users
    - Trigger or schedule
    - Required context
    - Microsoft 365 sources needed
    - Recommended Copilot capability
    - Setup steps
    - Prompt text
    - Expected output
    - Human review points
    - Governance notes
    - What success looks like
    - What could go wrong
    - What should not be automated
    - How to test it
    - How to improve it after testing
    Step 6: Draft the actual Copilot assets
    For each top 3 use case, draft the actual Copilot setup assets.
    If it should be a scheduled prompt, include:
    - Scheduled prompt name
    - Recommended schedule
    - Why that schedule makes sense
    - Full scheduled prompt text
    - Expected output
    - Who should review it
    - What the user should do with the output
    - Guardrails
    - What the scheduled prompt should not do
    If it should be a Copilot Cowork skill, include:
    - Skill name
    - Skill purpose
    - When users should use it
    - What the skill should ask the user
    - What context it needs
    - What steps it should follow
    - What outputs it should create
    - What it should never do
    - How it should handle uncertainty
    - Approval points
    - Validation checklist
    If it should be a Copilot Cowork /goal workflow, include:
    - Goal name
    - Goal purpose
    - Full /goal prompt
    - Expected outputs
    - Why Cowork is the right fit
    - Approval points
    - How to avoid unnecessary credit usage
    If it should stay in Microsoft 365 Copilot Chat, include:
    - Prompt name
    - Full prompt text
    - When to use it
    - When not to use it
    - Expected output
    - How to reuse it
    Step 7: Add one Power Automate bonus use case
    After the top 3 Copilot-only use cases, identify one additional use case where Power Automate is actually justified.
    This should be a workflow where:
    - A real trigger is needed
    - A system action needs to happen automatically
    - A record needs to be created or updated
    - An approval needs to be routed
    - A notification needs to be sent
    - A process needs reliability beyond a prompt
    - Copilot alone is not enough
    For the Power Automate use case, include:
    - Use case name
    - Why Copilot alone is not enough
    - Why Power Automate is justified
    - Trigger
    - Core flow steps
    - Inputs
    - Outputs
    - Approvals
    - Error handling
    - Where Copilot fits
    - Where Cowork fits
    - Governance notes
    - What should stay manual
    - What should be tested first
    Step 8: Compare the top 4
    Create a comparison table with:
    - Use case
    - Copilot-only or Power Automate
    - Best tool
    - Why this tool fits
    - Setup effort
    - Business value
    - Risk
    - Data sensitivity
    - User adoption likelihood
    - First test to run
    Step 9: Final output
    At the end, give me:
    - Executive summary
    - Work IQ pattern summary
    - Top 10 Copilot-only candidate list
    - Top 3 Copilot-only use cases
    - Why those 3 won
    - Full setup blueprint for each top 3 use case
    - Scheduled prompt drafts
    - Cowork skill drafts
    - Cowork /goal drafts
    - Copilot Chat prompt drafts
    - One Power Automate bonus use case
    - Comparison table
    - Rollout recommendations
    - Governance concerns
    - What should be tested first
    - What should not be automated yet
    - Assumptions
    - Data gaps
    - Confidence level
    Final instruction:
    Be strict.
    The first 3 use cases must be possible with Copilot only.
    Do not sneak Power Automate into the first 3.
    Only the 4th bonus use case can use Power Automate.
    I want the strongest practical Copilot-only use cases, not flashy demos.

    Why this prompt works?

    This prompt forces Cowork to stay practical.

    The first three use cases must be possible with Copilot only, so the output should focus on things like scheduled prompts, Cowork skills, /goal workflows, Copilot Chat prompts, and agents where available.

    Then the fourth use case gives you a clean escalation path for Power Automate when the process actually needs a trigger, approval, notification, record update, or reliable system action.

    That is the real value: start with Copilot, then only move to automation when the work pattern justifies it.

  • Copilot Cowork Prompt of the Day: Real Microsoft 365 Workflows That Actually Save Time

    Copilot Cowork Prompt of the Day: Real Microsoft 365 Workflows That Actually Save Time

    Copilot Cowork Prompt of the Day: Real Microsoft 365 Workflows That Actually Save Time

    I have been testing Copilot Cowork across real work patterns inside Microsoft 365: meetings, calendar cleanup, files, time entries, customer feedback, follow-ups, and workspace history.

    The pattern is becoming clear.

    The strongest Copilot Cowork prompts do not just ask for an answer. They assign a business outcome. They define the source of truth. They set guardrails. They tell Cowork what finished work should look like.

    That is where this gets serious.

    Below is a practical prompt library based on my Copilot Cowork Prompt of the Day posts across X and LinkedIn. I grouped them by scenario so the examples are easier to scan, reuse, and adapt.

    Note: Some examples use demo companies, files, customers, and project names. Replace those with your own Microsoft 365 content, folders, meetings, and business context.

    Table of Contents

    Calendar and Focus Management

    Calendar work looks simple until it eats your day. Declining meetings, cancelling organizer-owned events, protecting focus time, and finding clean openings are perfect examples of work that should be delegated.

    These prompts show Cowork acting like a real calendar operator, not a passive chatbot.

    Decline and Cancel Holiday Meetings

    The situation

    Friday is a holiday. Your calendar still has meetings. Some meetings were created by other people. Some meetings may be yours. You need everything cleaned up properly.

    The important part is the distinction between declining and cancelling. If you are only an attendee, Cowork should decline the meeting. If you are the organizer, Cowork should cancel it and send a note so attendees know why it disappeared.

    Copilot Cowork using calendar management to decline meetings and cancel organizer-owned meetings for a holiday.

    The prompt

    [Day] is a holiday. Check [Date].
    - Decline every meeting.
    - If I’m the organizer, cancel it and send a note.
    Use /calendar-management

    What Cowork should do

    • Check the target date.
    • Find every meeting on that day.
    • Decline meetings where you are an attendee.
    • Cancel meetings where you are the organizer.
    • Send a professional cancellation note where needed.
    • Summarize what changed.

    This is the kind of task that burns attention. The value is not only the minutes saved. The real value is that Cowork understands the difference between attendee action and organizer responsibility.

    Cancelling a meeting you own sends a different signal than declining a meeting someone else owns.

    How I would tighten the prompt

    For a production-style version, I would add the wording for the cancellation note directly into the prompt.

    Friday is a company holiday. Check April 3rd in my calendar.
    For every meeting that day:
    - If I am only an attendee, decline the meeting.
    - If I am the organizer, cancel the meeting.
    - For cancelled meetings, send this note:
    “April 3rd is a holiday, so I’m cancelling this meeting.
    Please reschedule for the following week if still needed.”
    After you finish, send me a summary grouped by declined meetings
    and cancelled meetings.
    Use /calendar-management

    Create Focus Time from Your Phone

    The situation

    This one is simple. That is why it matters.

    I used the iOS app from bed and told Cowork to find two separate one-hour focus blocks for Monday morning. Cowork checked my calendar, found the openings, and created both events.

    No desktop. No calendar hunting. No dragging blocks around half asleep.

    The prompt

    Set some focus time for me up for Monday morning.
    Find 2 separate 1 hour blocks so I can focus on:
    1) <Task>
    2) <Task>

    What Cowork should do

    • Review your Monday morning calendar.
    • Find two separate one-hour openings.
    • Create calendar events for each focus block.
    • Name each block clearly based on the task.
    • Add useful context where available.

    Focus time only helps if it actually lands on the calendar. A lot of people know what they need to work on, then lose the day to meetings, messages, and context switching.

    This turns focus protection into a command.

    That is the kind of small task agents should crush first. Scheduling. Calendar juggling. Protecting time. Removing the coordination mess.

    How I would tighten the prompt

    I would add preferred working hours, meeting buffer rules, and event details.

    Set up 2 separate 1-hour focus blocks for Monday morning.
    Focus areas:
    1) <Task 1>
    2) <Task 2>
    Rules:
    - Only schedule between 8:00 AM and 12:00 PM.
    - Do not overlap existing meetings.
    - Leave at least 15 minutes between meetings and focus blocks where possible.
    - Use clear calendar titles: “Focus: <Task>”.
    - Add a short note to each event with the goal for that focus block.
    After scheduling, tell me the times you picked.

    ↑ Back to top


    Time Entry and Work Reporting

    Time entry is one of the best Cowork use cases because the evidence already exists across Microsoft 365. Meetings, chats, emails, files, edits, and shared work all tell the story of the day.

    The hard part is turning that messy activity trail into believable time-entry comments that a human can review.

    Build a Daily Time Entry Summary from Microsoft 365 Activity

    The situation

    This prompt asks Cowork to review the day’s Microsoft 365 activity and produce a structured time-entry draft. The goal is not perfect accounting. The goal is a practical, honest draft that can be reviewed and corrected quickly.

    The real power is that Cowork is not only looking at meetings. It is asked to look across calendar activity, Teams chats, email, files, transcripts, meeting notes, and other signals.

    Daily time entry draft created from Microsoft 365 work activity.

    The prompt

    Review ALL of MY Microsoft 365 work activity from TODAY in
    [your timezone] and build a realistic, structured daily time entry
    summary.
    Then send it as a [direct Teams message / Email].
    Use every available signal from today:
    - calendar meetings
    - transcripts and recaps
    - meeting chats
    - Teams chats and channel messages
    - emails
    - files opened, edited, or shared
    - any other work activity signals
    Rules:
    1. Only use today in my local timezone.
    2. Look across all evidence, not just meetings.
    3. Infer the best-fit project, client, internal initiative, or business
    development category.
    4. Map work to a project whenever possible.
    5. If unclear, use: Business Development, Internal Operations,
    Practice Development, Admin, or Learning / Enablement.
    6. Consolidate fragmented activity into meaningful work blocks.
    7. Target a full day close to 8.0 hours.
    8. Acceptable total range: 6.0-8.0 hours.
    9. Accuracy first, then use reasonable consolidation to close gaps.
    10. Do not invent fake meetings, deliverables, or project names.
    11. If evidence is weak, make the best possible mapping, but keep
    descriptions honest.
    12. Avoid over-fragmenting. Prefer fewer, stronger entries.
    13. Write descriptions like real time-entry comments, not AI summaries.
    14. Keep descriptions concise but useful.
    15. Group short related activities under the same project.
    16. If there is clear prep or follow-up around meetings, emails,
    chats, or docs, include that under the relevant project when evidence
    supports it.
    17. Capture business development work where relevant:
    sales support, proposal work, internal planning, networking,
    demos, enablement, certifications, or content creation.
    Format the Teams message as HTML:
    - Bold heading: Daily Time Entry Draft – [YYYY-MM-DD]
    - Bold "Summary:" plus a 1-2 line plain-text summary
    - HTML table: # | Project Name | Description | Duration | Date
    - One row per entry, ordered largest to smallest
    - Duration in decimal hours, e.g. 3.0 hrs or 0.5 hrs
    - Bold "Total: X.X hours" at the bottom
    Quality bar: practical, believable, timesheet-ready.
    Use real work patterns. Balance to 6-8 hours.
    If today has limited evidence, still produce the best possible draft.

    What Cowork should do

    • Build a workday view from Microsoft 365 evidence.
    • Classify activity into projects, clients, or internal categories.
    • Consolidate short fragments into stronger time-entry rows.
    • Keep the wording practical and timesheet-ready.
    • Send the finished draft as a Teams message.

    This is a serious consulting and professional services scenario.

    Timesheets fail when people are forced to reconstruct their day from memory. Cowork can inspect the activity trail and give you a draft while the day is still fresh.

    You still review it. You still own it. Cowork reduces the blank-page problem.

    Important guardrails

    The guardrails are the real prompt design lesson here.

    • Do not invent fake meetings, deliverables, or project names.
    • Keep weak evidence honest.
    • Prefer fewer, stronger entries.
    • Write like a real time-entry comment.

    That is how you keep this useful without letting the agent drift into fantasy work logs.

    ↑ Back to top


    Meeting Intelligence and Follow-Up

    Meetings create a lot of residue: transcripts, AI notes, chats, files, agendas, decisions, action items, and follow-up messages.

    The problem is that the value disappears when nobody turns that residue into something clean.

    Create a Meeting Recap and Send It to Attendees

    The situation

    This prompt gives Cowork one target meeting and asks it to pull all available meeting content. The output is a structured recap and a concise email to attendees.

    The prompt also changes the recap style based on the meeting type. A requirements session should not be summarized the same way as a standup or UAT meeting.

    Meeting recap generated from meeting content, notes, transcript, chat, and related files.

    The prompt

    Use the meeting provided in context: <Meeting>.
    Meeting type: [Requirements | Standup | Training | UAT | Other]
    Treat this as the only target meeting. Pull all available meeting content
    including AI notes, transcript, meeting chat, shared files, agenda,
    description, and attached notes.
    Create a recap with:
    - purpose
    - key discussion points
    - decisions
    - action items
    - owners
    - due dates
    - follow-ups
    Adapt the recap based on the meeting type:
    - Requirements: needs, requested features, pain points, constraints,
    open requirements
    - Standup: progress, blockers, next steps
    - Training: what was taught, guidance shared, takeaways, resources
    - UAT: what was tested, issues found, defects, next steps for fixes or
    retesting
    - Other: use the most appropriate structure
    If anything is unclear or missing, state that clearly instead of guessing.
    Then draft and send a concise, professional recap email to all attendees.

    What Cowork should do

    • Use only the meeting provided in context.
    • Pull available transcript, recap, chat, files, agenda, and notes.
    • Build a recap that matches the meeting type.
    • Call out missing or unclear details.
    • Send a concise recap email to attendees.

    The most useful meeting recap is not a generic summary. It captures the operating details that move work forward: decisions, owners, due dates, and follow-ups.

    This prompt also handles one of the biggest issues with AI meeting summaries: context control. It tells Cowork to treat the provided meeting as the only target meeting.

    How I would tighten the prompt

    For client-facing work, I would add a review step before sending.

    Use the meeting provided in context: <Meeting>.
    Meeting type: [Requirements | Standup | Training | UAT | Other]
    Treat this as the only target meeting. Pull all available meeting conten
    including AI notes, transcript, meeting chat, shared files, agenda,
    description, and attached notes.
    Create a recap with:
    - Purpose
    - Key discussion points
    - Decisions
    - Action items
    - Owners
    - Due dates
    - Follow-ups
    Adapt the recap based on the meeting type.
    If anything is unclear or missing, state that clearly instead of guessing.
    Draft a concise, professional recap email to all attendees,
    but do not send it until I review and approve it.

    ↑ Back to top


    Customer Feedback and Leadership Deliverables

    This is the most advanced scenario in the set.

    The assignment is not just “summarize feedback.” The assignment is to turn scattered customer signals into a leadership-ready action package.

    That means Cowork has to analyze, prioritize, create deliverables, flag weak evidence, and prepare different outputs for different audiences.

    Turn Customer Feedback into a Product Action Plan

    The situation

    Kavora’s marketing department has customer feedback scattered across interviews, surveys, comments, web signals, and meeting notes.

    Leadership needs the real story:

    • What customers are saying.
    • What matters most.
    • What needs action.
    • What needs human judgment before the team moves.

    For the demo, the input files were:

    • Customer interview notes
    • Product feedback survey and web signal export
    • Source customer comments
    • Marketing leadership request and context email

    The Cowork assignment was to review the feedback, find the strongest themes, rank them by impact and urgency, flag gaps or contradictions, then build the deliverables a marketing team would actually need.

    Copilot Cowork turning scattered customer feedback into a brief, deck, emails, Teams update, and decision tracker.

    The expected outputs

    • Executive feedback brief
    • Stakeholder-ready presentation deck
    • Customer follow-up email pack
    • Launch squad Teams update
    • Leadership decision tracker

    The prompt

    Act as my marketing operations lead.
    Goal:
    I’m working on turning messy customer product feedback into a clear
    action plan for product, marketing, and leadership teams.
    Sources:
    Use the attached files and project folder as the source of truth.
    These may include customer interview notes, survey results,
    web/funnel data, Teams meeting summaries, support themes,
    website feedback, campaign comments, and leadership request emails.
    Task:
    1. Review the materials and identify the strongest customer feedback
    themes.
    2. Prioritize the themes by customer impact, urgency, revenue risk, and
    brand risk.
    3. Pull proof points from the source material, including customer
    quotes, survey signals, and web/funnel trends.
    4. Identify gaps, contradictions, sampling bias, or anything that needs
    validation before decisions are made.
    5. Recommend the next best actions for product, marketing,
    customer success, and leadership.
    Produce:
    • A polished executive feedback brief
    • A stakeholder-ready presentation deck
    • A customer follow-up email pack
    • A Teams update for the launch squad
    • A leadership decision tracker with priorities, owners, and dates
    Guardrails:
    • Separate facts from recommendations
    • Do not invent evidence
    • Call out assumptions clearly
    • Flag anything that needs human review
    • Make the outputs ready for me to review, edit, and share

    What Cowork should do

    • Review all supplied source material.
    • Find repeated customer themes.
    • Rank themes by impact, urgency, revenue risk, and brand risk.
    • Pull quotes and proof points from the evidence.
    • Flag contradictions, bias, gaps, and validation needs.
    • Create separate deliverables for leadership, product, launch teams, and customer follow-up.

    The best part of this prompt is the deliverable design. It does not stop at analysis. It asks for the assets the business actually needs:

    • A brief for executives.
    • A deck for stakeholders.
    • Email drafts for customers.
    • A Teams update for the launch squad.
    • A decision tracker for leadership.

    That is the difference between “tell me what the files say” and “help me move the business forward.”

    The human review layer

    This prompt gets the review model right. It tells Cowork to separate facts from recommendations and flag assumptions.

    That matters because customer feedback can be messy. You can have contradictory signals, loud power users, small samples, weak survey patterns, or feedback that sounds urgent but needs validation.

    The agent can organize the evidence. The human still owns the judgment.

    How I would tighten the prompt

    I would add a scoring model so the ranking is easier to audit.

    When ranking feedback themes, score each theme from 1-5 across:
    - Customer impact
    - Urgency
    - Revenue risk
    - Brand risk
    - Evidence strength
    Then calculate a priority recommendation of P0, P1, or P2.
    For every theme, include:
    - Evidence used
    - Customer quote or signal
    - Recommended owner
    - Recommended next action
    - What needs human validation before action

    ↑ Back to top


    File and Workspace Operations

    Some of the best agent use cases are boring. That is the point.

    Moving files, finding folders, reviewing previous sessions, and organizing workspace context are small tasks by themselves. Across a week, they become attention tax.

    Move a File in OneDrive

    The situation

    I downloaded a zip file on my phone, uploaded it to OneDrive, and told Cowork to move it into the right demo folder.

    No laptop. No desk. No clicking through folders.

    Cowork found the file, found the destination folder, and moved it.

    Copilot Cowork finding a recently uploaded zip file and moving it to the right OneDrive folder.

    The prompt

    I just uploaded a <file or folder> to OneDrive.
    Can you move it to the Copilot Cowork Demos folder

    What Cowork should do

    • Search OneDrive for the uploaded file or folder.
    • Search OneDrive for the destination folder.
    • Move the item.
    • Confirm the exact file or folder that was moved.

    This is the kind of work nobody wants to do. It is small enough to feel annoying and common enough to keep stealing attention.

    Agents should handle the annoying little tasks first.

    Find the file. Find the folder. Move it. Confirm it.


    Review Past Cowork Sessions

    The situation

    This is a fun one for understanding the workspace Cowork builds around your work.

    The prompt asks Cowork to look across previous sessions and tell you what you have built together, then pick its favorite session.

    Your Cowork sessions are stored in:

    Documents > Coworker > sessions
    Copilot Cowork reviewing previous sessions and summarizing what has been built.

    The prompt

    based on all our sessions, can you tell me the things we have built
    together, and your most favorite session?

    What Cowork should do

    • Enumerate previous session folders.
    • Identify deliverables created in each session.
    • Summarize patterns across the work.
    • Pick a favorite session and explain why.

    This shows Cowork as more than a one-off task runner. It can review the body of work created across sessions and help you understand what has been built.

    That becomes useful when you are building demos, content, project assets, templates, or repeatable internal workflows.

    How I would tighten the prompt

    I would ask for the output in a reusable inventory format.

    Review all our Cowork sessions stored in
    Documents > Coworker > sessions.
    Create a structured inventory with:
    - Session name
    - Date if available
    - Business scenario
    - Deliverables created
    - Files produced
    - Skills or tools used
    - Reusable assets I should keep
    - Your favorite session and why
    Group the results by scenario type.

    ↑ Back to top


    The Prompt Design Pattern

    After testing these scenarios, the pattern is obvious.

    A strong Copilot Cowork prompt usually needs these parts:

    1. Assign the role

    Example

    Act as my marketing operations lead.

    This gives Cowork a working frame. A calendar assistant, marketing operations lead, project coordinator, meeting analyst, or time-entry assistant will make different choices.

    2. Define the business goal

    Example

    I’m working on turning messy customer product feedback into a clear
    action plan for product, marketing, and leadership teams.

    The goal keeps Cowork focused on the outcome instead of wandering through the source material.

    3. Name the source of truth

    Example

    Use the attached files and project folder as the source of truth.

    This matters because Cowork may have access to a lot of context. You need to tell it what evidence matters.

    4. Add rules and guardrails

    Example

    Do not invent evidence.
    Call out assumptions clearly.
    Flag anything that needs human review.

    Guardrails keep the work usable. They also make the output safer to review, edit, and share.

    5. Specify the finished output

    Example

    Produce:
    - A polished executive feedback brief
    - A stakeholder-ready presentation deck
    - A customer follow-up email pack
    - A Teams update for the launch squad
    - A leadership decision tracker with priorities, owners, and dates

    Do not make Cowork guess what “done” means. Define the deliverables.

    6. Keep human review in the loop

    Example

    Make the outputs ready for me to review, edit, and share.

    This is the right operating model. Cowork can create the draft, organize the work, and prepare the package. You still make the judgment call.

    ↑ Back to top

    Final Thought

    Copilot Cowork gets interesting when you stop treating it like a chat box and start treating it like a worker with an assignment.

    The best prompts are direct. They give Cowork the goal, the evidence, the rules, and the expected output.

    That is how you move from “write me a summary” to:

    • Clean up my calendar.
    • Protect my focus time.
    • Draft my time entries.
    • Summarize the meeting and follow up.
    • Turn customer feedback into an action plan.
    • Move the file where it belongs.
    • Review the work we have already built.

    Small tasks. Big tasks. Same lesson.

    Give the agent clear work. Keep the guardrails tight. Review the output like a professional.

    That is where Copilot Cowork starts to feel like real capacity.

    ↑ Back to top

  • How I Keep Copilot Cowork Sessions Alive with a requirements.md File

    How I Keep Copilot Cowork Sessions Alive with a requirements.md File

    Copilot Cowork is strong at creating files. Documents, markdown files, HTML files, specs, plans, summaries, all of it.

    So I started using that strength against one of the biggest pain points in agent work: losing context.

    1. The Problem
    2. The Workaround
    3. The Prompt I Use
    4. What I Want Cowork To Track
    5. The Recovery Flow
      1. Step 1: Open the Output Folder
      2. Step 2: Copy the OneDrive Link
      3. Step 3: Start a New Cowork Session
    6. Why This Works
    7. My Recommendation
    8. Final Take

    The Problem

    Sometimes a session can glitch, freeze, or reach a point where starting fresh is easier.

    The painful part is not starting a new session.

    The painful part is rebuilding the context.

    You have to explain the goal again. Rebuild the requirements. Re-upload or reconnect files. Remind it what decisions were already made. Recreate the mental map of the work.

    That burns time.

    So I started giving Copilot Cowork a job before it does any other job:

    Keep the context alive.

    The Workaround

    At the start of the session, tell Cowork to create a requirements.md file and keep it updated while you work.

    That file becomes the session brain.

    It gives you a portable record of the work that can move from one Cowork session to another.

    Think of it like a handoff file.

    Not a final deliverable. Not a pretty summary. A working memory file.

    The Prompt I Use

    Create a requirements.md file and keep it updated throughout this session.
    Use it to track the full context of our work, including:
    - requirements
    - decisions made
    - open items
    - files created
    - key conversation details
    - risks
    - assumptions
    - and next steps
    I want to be able to pass this file to another Copilot Cowork session
    so it can continue with full context.

    You can change the file name if you want.

    For some sessions, I might use project-context.md, demo-notes.md, or handoff.md.

    But I like requirements.md because it forces the session to stay grounded in what is actually being built.

    Note

    This works best when the requirements.md file is updated throughout the session, not only at the end. When decisions change, files are created, or blockers appear, tell Cowork to update the file.

    What I Want Cowork To Track

    The file should not be a fluffy recap.

    I want it tracking the stuff that matters:

    • Session goal
    • Current objective
    • Requirements
    • Decisions made
    • Files created
    • Important assumptions
    • Open questions
    • Risks or blockers
    • Next actions
    • Anything another session would need to continue the work

    That last one is the key.

    Do not just ask Cowork to summarize.

    Ask it to prepare the next session to continue the work.

    The Recovery Flow

    If the session glitches, breaks, or you want to continue in a fresh session, here is the flow I use.

    Step 1: Open the Output Folder

    In Copilot Cowork, open the details pane and look for the Output folder.

    Click the folder icon to open the generated files in OneDrive.

    Once the folder opens in OneDrive, click Copy link.

    This gives you a link to the folder that contains the files from the previous Cowork session.

    Step 3: Start a New Cowork Session

    Open a new Copilot Cowork session.

    Paste the OneDrive folder link into the new session and tell Cowork:

    Im continuing the <Project or task name>.
    Use the files from our previous session. ( <Paste OneDrive Link> )
    Start by reading the requirements.md file.
    Then continue the work from there.

    Now Cowork has a fighting chance at picking up where the previous session left off.

    Why This Works

    Agent workflows are only as strong as the context behind them.

    If the context is trapped inside one chat session, you are exposed.

    If the context is written into a file, you can move it.

    That changes the way you work with Cowork.

    You are no longer relying only on the chat thread.

    You are creating a portable project trail that can survive a new session.

    My Recommendation

    Make this part of your normal Copilot Cowork workflow.

    Before you ask it to build the document, analyze the data, write the plan, or generate the assets, tell it to create the context file first.

    Then keep pushing Cowork to update that file as the session evolves.

    When a decision is made, tell it to update the file.

    When a requirement changes, tell it to update the file.

    When a file is created, tell it to update the file.

    Small habit.

    Big protection.

    Final Take

    Copilot Cowork can generate the work.

    But you should also make it generate the trail.

    The requirements file keeps the important context outside the chat window, inside the actual working folder, where another session can use it.

    That is the move.

    Use Cowork to build the output.

    Use Cowork to protect the context.

    This is currently a limitation on the product, which I assume the Team will fix in the future. But for now, this is how I manage long running tasks and work with Copilot Cowork.

  • Build Your Agent Factory: 10 Moves That Ship Fast (and Scale)

    Build Your Agent Factory: 10 Moves That Ship Fast (and Scale)

    Build Your Agent Factory: 10 Moves That Ship Fast (and Scale)

    Agents at scale. Not POCs.

    Here’s the playbook I’d hand any exec or builder who wants working agents in production—without turning the org into a science fair.

    1) Stand up an AI Agents Workforce

    What it is: A small cross-functional crew with authority to hunt repetitive work and ship agents.

    Who’s in:

    • 1 product owner
    • 1 engineer (Copilot Studio/Power Automate)
    • 1 data person
    • 1 security/governance lead
    • 1 domain SME.

    Ship this week: Write a one-page charter with scope, decision rights, and a 30-day roadmap (first 5 agents + metrics).

    2) Win with horizontals first, then go vertical

    Horizontals (1-hour wins): drafting, summarizing, policy Q&A, meeting notes to actions, form-fill helpers.

    Verticals (outsized ROI): pick 1–2 per business unit where there’s money, risk, or SLA pain.

    Guardrail: don’t start with the hardest workflow; start where you can close the loop and measure value inside two weeks.

    3) Make an Agents Directory the front door

    Why: Ideas die in email. A directory turns “we should build X” into spec and governance.

    Minimum intake fields:

    • use case name
    • goal
    • users
    • decision rights
    • data sources + who owns it
    • tools
    • PII/sensitivity
    • KPIs
    • business owner
    • risk level
    • rollout plan.

    Outcome: Every request auto-generates a lightweight PRD (goal, inputs, outputs, metrics, guardrails) and a yes/no gate.

    4) Create the 1-Hour Agent template

    Template anatomy:

    Goal + success criteria Input schema (what the user provides) Tools (actions/connectors) and permissions Knowledge sources (files, sites, indexes) Safety rules (allowed/blocked actions, escalation) Evaluation set (10–20 test prompts with expected outcomes) Deploy script (Dev → Test → Prod)

    Rule: If a use case can’t fit this page, it’s not a 1-hour agent—park it for later.

    5) Tie every agent to a visible scorecard

    Metrics to publish: time saved, cost avoided, error rate, CO₂/efficiency (where relevant), user satisfaction.

    Simple formula: monthly users × average minutes saved × loaded cost = value.

    Make it public internally: green/red status, owner, last review, next improvement.

    6) Run on a secure, managed agent runtime

    Non-negotiables: identity passthrough, content safety, audit logs, tool call restrictions, data boundary controls, environment isolation.

    Practical tip: standardize a “sensitive sources” policy and block tools by default; allow case-by-case.

    7) Split the stack to move fast without breaking things

    Experience layer: Copilot Studio for UX, channels, and connectors.

    Agent runtime/orchestration: managed agent service for threads, tool calls, safety, and evaluations.

    Why it works: builders ship quickly at the edge; platform team keeps shared guardrails, monitoring, and upgrades stable.

    8) Mix knowledge + action (or you’ll stall)

    Knowledge: structured grounding (SharePoint/Fabric/Search), doc versioning, citations-on by default.

    Action: flows/Logic Apps, Graph, line-of-business APIs; always ship with a dry-run mode first.

    Design pattern: Answer → show sources → propose actions → execute on approval. When confidence is high and stakes are low, allow auto-execute.

    9) Keep humans in the loop—by design

    HITL patterns that work:

    Shadow mode (observe only) → suggest mode → execute with approval → auto-execute.

    Confidence thresholds where low confidence routes to a human. Escalation logic when guardrails trip or data is missing.

    UX rule: one click to approve, one click to undo.

    10) Plan to scale on day one

    Pipelines: Dev → Test → Prod with approvals and rollback.

    Evals: pre-ship test set per agent; weekly drift checks; quarterly red-team.

    Ops: central logging, cost dashboards, incident playbook.

    Program ritual: a quarterly “Agent Backlog Day” to harvest new ideas and retire underperformers.

    Starter Architecture (fast and boring)

    Experience: Copilot Studio (web, Teams, M365, chat, plugins)

    Actions: Power Automate/Logic Apps + custom APIs

    Knowledge: SharePoint/Fabric/AI Search with retrieval policies

    Runtime: managed agent service for tool orchestration, identity, safety

    Observability: evaluations, telemetry, and a simple agent scorecard per app

    Security: Entra ID RBAC, private endpoints, DLP, approval gates

    Prompts and policies that save you pain

    Prompt contract (keep it in the repo): role, goals, inputs, allowed tools, forbidden actions, decision rights, escalation, output format, citation rules.

    Data contract: what sources are permitted, freshness expectations, sensitivity tags.

    Failure modes: what the agent must do when unsure (ask for clarification, route to human, or stop).

    Anti-patterns I keep seeing

    • Starting with an “AI strategy deck” instead of shipping 3 agents.
    • Agents that answer but can’t act—users stop coming back.
    • No owner, no scorecard, no sunset date.
    • Canary-testing in production without a rollback plan.
    • Letting one giant use case block 20 small wins.

    Your first week mapped

    Day 1: Form the team and publish the charter.

    Day 2: Launch the Agents Directory (intake + PRD autogeneration).

    Day 3–4: Build two 1-hour agents (drafting + policy Q&A) with eval sets.

    Day 5: Ship to a pilot group with scorecards visible. Book the first backlog day.


  • Part 2 – Build & Ship a “Docs Agent” to Microsoft Teams

    Part 2 – Build & Ship a “Docs Agent” to Microsoft Teams

    (Companion guide to “Spin-Up the Microsoft Learn MCP Server”)

    Make sure you have read and setup the Docs MCP custom connector from part 1

    1. What you’ll build
    2. Prerequisites
      1. Icons to Download (optional)
    3. 1 – Create the Agent in Copilot Studio
      1. Add Suggested Prompts
      2. Agent Settings
      3. Turn Off Pointless Topics
    4. Publish & Package for Teams
      1. Submit Agent for Approval
    5. Approve Agent App (As a Teams Admin)
    6. How to Use the Agent
      1. Adding Agent to a Meeting or Chat
      2. Troubleshooting

    What you’ll build

    A Copilot Studio agent that queries the Microsoft Learn MCP server for live docs, then answers teammates inside a Teams chat or Meeting.

    Prerequisites

    NeedNotes
    Docs MCP custom connector from Part 1Already in your environment.
    (https://flowaltdelete.ca/2025/06/26/how-to-spin-up-the-microsoft-learn-mcp-server-in-copilot-studio/)
    Copilot Studio (preview) tenantGenerative orchestration enabled. (Early Features)
    Teams admin rights (or approval from your Teams Admin)To upload a custom app or publish to the org.
    Copilot Studio LicenseMessage packs or sessions
    prereq table

    Icons to Download (optional)

    Below are icons you can use for the Agent and the MCP custom connector.

    1 – Create the Agent in Copilot Studio

    In this example I am going to use the existing agent I created from Part 1.

    1. Modify or create the agent with a meaningful name, description, and icon.
      (You can use the one I provided from above or use your own)
    2. Name: MS Docs Agent
    3. Description: MS Docs Agent is your on-demand mentor for Microsoft technologies—built with Copilot Studio and powered by the Microsoft Learn MCP server. Every answer comes from the live, authoritative docs that Microsoft publishes each day, so you never rely on stale model memories or web-scraped content.
    4. Orchestration = Enabled

    5. For your Instructions for the agent, we don’t want to add too much. After much testing I found that in its current state the Docs MCP server handles the instructions well and having too much instructions causes the response to fail. So its better to leave instructions blank for now.
    6. Web Search – This should be Disabled. We only want the agent to query the docs which it does through the MCP server.
    7. Knowledge should be empty, the only thing we want this agent to do is query the Docs MCP server, so this should be the only Tool that the agent has access to.
    8. To recap, the only Tools and Knowledge this agent should have is the MCP Server (custom connector) that we created in the first blog post. If you need help setting this up refer to Part 1.

    Add Suggested Prompts

    When users interact with the agent in M365 chat (Copilot) we can show suggested prompts to help guide the user in what is possible with this agent. Here are a bunch of samples you can give your agent:

    TitlePrompt
    Dev Env for Power AppsSet up a developer environment for Power Apps—step-by-step.
    Rollup vs FormulaRollup fields vs Formula columns in Dataverse—when to use each?
    Flow 502 FixPower Automate flow fails with 502 Bad Gateway—how do I resolve it?
    Cert Path FinderFastest certification path for a Dynamics 365 functional consultant.
    PL-200 Module ListList every Microsoft Learn module covered by the PL-200 exam.
    Managed Env EnableTurn on managed environments and approval gates in Power Platform.
    Finance DLP PolicyBest-practice DLP setup for finance data in Power Platform.
    Power Fx Date FilterSample Power Fx to filter a gallery to today’s records.
    OpenAI Flow SampleMinimal example: call Azure OpenAI from Power Automate.
    Secure Env VarsSecure environment variables with Azure Key Vault in flows.
    Pipeline ChecklistChecklist to deploy a solution through Power Platform pipelines.
    PCF Chart ControlBuild a PCF control that renders a chart on a model-driven form.
    New PA FeaturesSummarize new Power Apps features announced this month.
    Preview ConnectorsList preview connectors added to Power Automate in the last 30 days.
    Explain to a ChildExplain Dataverse to a five-year-old.

    You can only add 6 Suggested Prompts. So choose carefully.

    Agent Settings

    Next we want to configure some settings on the agent.

    1. Click the Settings button on the top right.

    2. (Optional) If you want the agent to have reasoning capabilities > Under Generative AI turn on: Deep reasoning
      **Note that this is a premium feature**

    3. Scroll down to Knowledge, make sure Use general knowledge and Use information from the Web are both OFF

    4. Make sure to click Save once done.

    Turn Off Pointless Topics

    Next we will turn off the topics we don’t want the agent to use.

    1. Click on Topics tab > Under Custom > Only leave Start Over topic On.

    2. Under System > Turn Off:
      – End of Conversation
      – Escalate
      – Fallback
      – Multiple Topics Matched

    3. Next, lets modify the Conversation Start to make it sound better.
      Click Conversation Start topic > Modify the Message node:

    4. Click Save.

    Now we are ready to Publish and Package for Teams!

    Publish & Package for Teams

    Next we need to Publish our agent.

    1. Click on the Channels tab > Click Publish

    2. Once your agent is published > Click on the Teams and Microsoft 365 Copilot channel.

    3. A sidebar opens > Check the Make agent available in Microsoft 365 Copilot > Click Add channel.

    4. After the channel has been added > Click Edit details.

    5. This is where we configure the agent in Teams. We will modify the icon, give a short description, long description and allow for the agent to be added to a team and meeting chats.
      Under Teams settings > Check both:
      – Users can add this agent to a team
      – Use this agent for group and meeting chats

    6. Click Save

    Submit Agent for Approval

    Now because we want our organization to easily find and use this agent. We will submit the agent to the Agent Store. To do this follow these steps:

    1. First Publish your agent, to make sure you have the newest version you are pushing to Teams admin for approval.
    2. Next click on the Channels tab > Select the Teams and Microsoft 365 Copilot channel.
    3. Now click Availability options.

    4. Now we will configure the Show to everyone in my org.

    5. Than click Submit for admin approval.

      Now we will look at what a Teams Admin has to do.

    Approve Agent App (As a Teams Admin)

    A Microsoft Teams Admin will have to approve the Agent app before your org can use it. As a Teams Admin follow these steps:

    1. Navigate to https://admin.teams.microsoft.com/policies/manage-apps
      (Click on Manage apps under Teams apps)
    2. Search for your agent name in the search bar

    3. Click the agent > Publish.

    4. Note:: You will need Admin Approval each time you want to publish an update to the agent.

    How to Use the Agent

    Once your agent is approved by an Admin. You can easily find it in the Agent Store. Another easy way to get to your agent is to open it from Copilot Studio:

    1. Click Channels tab > Select Teams and Microsoft 365 Copilot channel > Click See agent in Teams.

    You will be brought to Teams with the agent open. You can now add it:

    Adding Agent to a Meeting or Chat

    There are a few ways to add the agent to a meeting. One easy way is to @mention the agent in the chat.

    **Note to start typing the name of the agent, and it should show up**

    Troubleshooting

    There are a few things to note that I ran into:
    1) If your getting an error on the MCP Server, remove all custom instructions

    2) Sometimes your agents details can be cached and showing old metadata. In this case you can resubmit the app approval.

    3) Always test the Agent inside Copilot Studio Test Pane with tracking topics and Activity Map turned On.

  • Add the Microsoft Learn Docs MCP Server in Copilot Studio

    Add the Microsoft Learn Docs MCP Server in Copilot Studio

    UPDATE—August 8, 2025: You no longer need to create a custom connector for the Microsoft Learn Docs MCP server. Copilot Studio now includes a native Microsoft Learn Docs MCP Server under Add tool → Model Context Protocol.
    This guide has been updated to show the first-party path. If your tenant doesn’t yet show the native tile, use the Legacy approach at the bottom.

    What changed

    • No YAML or custom connector required
    • Fewer steps, faster setup

    Model Context Protocol (MCP) is the universal “USB-C” port for AI agents. It standardizes how a model discovers tools, streams data, and fires off actions—no bespoke SDKs, no brittle scraping. Add an MCP server and your agent instantly inherits whatever resources, tools, and prompts that server exposes, auto-updating as the backend evolves.

    1. Why you should care
    2. What the Microsoft Learn Docs MCP Server delivers
    3. Prerequisites
    4. Step 1 – Add the native Microsoft Learn Docs MCP Server
    5. Step 2 – Validate
    6. Legacy approach (if the native tile isn’t available)

    Why you should care

    • Zero-integration overhead – connect in a click inside Copilot Studio or VS Code; the protocol handles tool discovery and auth.
    • Future-proof – the spec just hit GA and already ships in Microsoft, GitHub, and open-source stacks.
    • Hallucination killer – answers are grounded in authoritative servers rather than fuzzy internet guesses.

    What the Microsoft Learn Docs MCP Server delivers

    • Tools: microsoft_docs_search – fire a plain-English query and stream back markdown-ready excerpts, links, and code snippets from official docs.
    • Always current – pulls live content from Learn, so your agent cites the newest releases and preview APIs automatically.
    • First-party & fast — add it in seconds from the Model Context Protocol gallery; no OpenAPI import needed.

    Bottom line: MCP turns documentation (or any backend) into a first-class superpower for your agents—and the Learn Docs server is the showcase. Connect once, answer everything.

    Prerequisites

    • Copilot Studio environment with Generative Orchestration (might need early features on)
    • Environment-maker rights
    • Outbound HTTPS to learn.microsoft.com/api/mcp

    Step 1 – Add the native Microsoft Learn Docs MCP Server

    1. Go to Copilot Studio: https://copilotstudio.microsoft.com/
    2. Go to Tools → Add tool.
    3. Select the Model Context Protocol pill.
    4. Click Microsoft Learn Docs MCP Server.
    5. Choose the connection (usually automatic) and click Add to agent.
    6. Confirm the connection status is Connected.
    Copilot Studio Add tool panel showing Model Context Protocol category and Microsoft Learn Docs MCP Server tile highlighted.
    1. The MCP server should now show up in Tools.
    1. Click the Server to verify the tool(s) and to make sure:
      – ✅ Allow agent to decide dynamically when to use this tool
      – Ask the end user before running = No
      – Credentials to use = End user credentials

    Step 2 – Validate

    1. In the Test your agent pane. Turn on Activity map by clicking the wavy map icon:

    2. Now try a prompt like:
      – What MS certs should I look at for Power Platform?
      – How can I extend the Power Platform CoE Starter Kit?
      – What modern controls in Power Apps are GA and which are still in preview? Format as a table

    Use-Case Ideas

    • Internal help-desk bot that cites docs.
    • Learning-path recommender (your pipeline example).
    • Governance bot that checks best-practice-links.

    Troubleshooting Cheat-Sheet

    • Note that currently the Learn Docs MCP server does NOT require authentication. This will most likely change in the future.
    • If Model Context Protocol is not shown in your Tools for Copilot Studio. You may need to create an environment with Early Features turned on.
    • Do NOT reference the MCP server in the agents instructions, you will get a tool error.
    • Check Activity tab for monitoring

    Legacy approach (if the native tile isn’t available)

    Grab the Minimal YAML

    1. Open your favorite code editor or notepad. Copy and paste this YAML to a new file.
    swagger: '2.0'
    info:
      title: Microsoft Docs MCP
      description: Streams Microsoft official documentation to AI agents via Model Context Protocol
      version: 1.0.0
    host: learn.microsoft.com
    basePath: /api
    schemes:
      - https
    paths:
      /mcp:
        post:
          summary: Invoke Microsoft Docs MCP server
          x-ms-agentic-protocol: mcp-streamable-1.0
          operationId: InvokeDocsMcp
          consumes:
            - application/json
          produces:
            - application/json
          responses:
            '200':
              description: Success
    
    1. Save the file with .yaml extension.

    Import a Custom Connector

    Next we need to create a custom connector for the MCP server to connect to. We will do this by importing our yaml file we created in Step 1.

    1. Go to make.powerapps.com > Custom connectors > + New custom connector > Import OpenAPI.

    2. Upload your yaml file eg: ms-docs‑mcp.yaml, using the Import an OpenAPI file option.

    3. General tab: Confirm Host and Base URL.
      Host: learn.microsoft.com
      Base URL: /api
    4. Security tab > No authentication (the Docs MCP server is anonymously readable today).
    5. Definition tab > verify one action named InvokeDocsMcp is present.
      Also add a description.

    6. Click Create connector. Once the connector is created, click the Test tab, and click +New Connection.

      (Note, you may see more than 1 Operation after creating the connector. Don’t worry and continue on)
    7. When you create a connection, you will be navigated away from your custom connector. Verify your Connection is in Connected Status.

      Next we will wire this up to our Agent in Copilot Studio.
  • Get the difference between two dates (Updated 2025)

    Get the difference between two dates (Updated 2025)

    Many Power Automate users encounter issues with the dateDifference() function when calculating the difference between two dates. The problem arises when the output format varies depending on the duration, causing errors in extracting Days, Hours, Minutes, and Seconds.

    This blog provides a robust and easy-to-implement solution that works seamlessly in all scenarios, including durations less than a day. Learn how to use a single expression with conditional logic to avoid these common pitfalls and ensure your date calculations are accurate every time. This is your ultimate fix for handling dateDifference() errors!

    1. The Flow
      1. dateDifference expression
        1. How it works
      2. Steps to Access Each Value
    2. Download my Flow
      1. Classic designer
      2. New designer
    3. Conclusion

    The Flow

    1. Compose action: named StartDate = 2024-12-10T15:58:28
    2. Compose action: named EndDate = 2024-12-10T19:22:20
    3. Compose action: uses dateDifference() expression. see below

    Below is the expression used in the ‘Date Difference’ compose action. It dynamically handles all scenarios—when days are included and when they are not (same with hours and minutes).

    dateDifference expression

    Create a compose action for StartDate and EndDate

    if(
       contains(
         dateDifference(outputs('StartDate'), outputs('EndDate')), 
         '.'
       ),
       json(
         concat(
           '{"Days":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[0])),
           ',"Hours":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[0])),
           ',"Minutes":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[1])),
           ',"Seconds":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[2])),
           '}'
         )
       ),
       json(
         concat(
           '{"Days":0',
           ',"Hours":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[0])),
           ',"Minutes":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[1])),
           ',"Seconds":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[2])),
           '}'
         )
       )
    )

    How it works

    • The if() function checks if the dateDifference() result contains a . (dot).
    • If it does, it means the result has a days component (e.g., 1268.04:15:30), so we parse out Days, Hours, Minutes, and Seconds accordingly.
    • If it does not, it means the result is less than a day (e.g., 12:57:47.2544602), so we treat Days as 0 and parse Hours, Minutes, and Seconds directly from the string.

    Result:

    This will produce a JSON object like:
    {
    "Days": 1268,
    "Hours": 4,
    "Minutes": 15,
    "Seconds": 30
    }

    Or
    {
    "Days": 0,
    "Hours": 12,
    "Minutes": 57,
    "Seconds": 47
    }

    Steps to Access Each Value

    If you use the fixed expression directly in a Compose action (e.g., named Date_Difference), you can reference the fields like this:

    • Days: outputs('Date_Difference')?['Days']
    • Hours: outputs('Date_Difference')?['Hours']
    • Minutes: outputs('Date_Difference')?['Minutes']
    • Seconds: outputs('Date_Difference')?['Seconds']

    Use these expressions in subsequent actions (like another Compose, a Condition, or Apply to Each) to reference the specific values.

    Download my Flow

    You can easily copy and paste actions in Power Automate. Allowing you to copy and paste my example.

    1. Classic designer
    2. New designer

    Classic designer

    Step 1: Copy the code snippet

    {"id":"b6b531e2-b7b5-4a9e-86bd-7e2a069529a0","brandColor":"#8C3900","connectionReferences":{},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"Get_date_difference_object","operationDefinition":{"type":"Scope","actions":{"StartDate":{"type":"Compose","inputs":"2024-12-10T15:58:28","runAfter":{}},"EndDate":{"type":"Compose","inputs":"2024-12-10T19:22:20","runAfter":{"StartDate":["Succeeded"]}},"Date_Difference":{"type":"Compose","inputs":"@if(\r\n   contains(\r\n     dateDifference(outputs('StartDate'), outputs('EndDate')), \r\n     '.'\r\n   ),\r\n   json(\r\n     concat(\r\n       '{\"Days\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[0])),\r\n       ',\"Hours\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[0])),\r\n       ',\"Minutes\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[1])),\r\n       ',\"Seconds\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[2])),\r\n       '}'\r\n     )\r\n   ),\r\n   json(\r\n     concat(\r\n       '{\"Days\":0',\r\n       ',\"Hours\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[0])),\r\n       ',\"Minutes\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[1])),\r\n       ',\"Seconds\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[2])),\r\n       '}'\r\n     )\r\n   )\r\n)","runAfter":{"EndDate":["Succeeded"]},"metadata":{"operationMetadataId":"03c8d578-576a-41a3-8d63-609a15ce594b"}}},"runAfter":{"Add_to_time":["Succeeded"]}}}

    Step 2: In Power Automate when adding a new action click My clipboard .

    Step 3: Ctrl + V


    New designer

    Step 1: Copy the code snippet

    {"nodeId":"Get_date_difference_object-copy","serializedOperation":{"type":"Scope","actions":{"StartDate":{"type":"Compose","inputs":"2024-12-10T15:58:28"},"EndDate":{"type":"Compose","inputs":"2024-12-10T19:22:20","runAfter":{"StartDate":["Succeeded"]}},"Date_Difference":{"type":"Compose","inputs":"@if(\r\n   contains(\r\n     dateDifference(outputs('StartDate'), outputs('EndDate')), \r\n     '.'\r\n   ),\r\n   json(\r\n     concat(\r\n       '{\"Days\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[0])),\r\n       ',\"Hours\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[0])),\r\n       ',\"Minutes\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[1])),\r\n       ',\"Seconds\":', string(int(split(split(dateDifference(outputs('StartDate'), outputs('EndDate')), '.')[1], ':')[2])),\r\n       '}'\r\n     )\r\n   ),\r\n   json(\r\n     concat(\r\n       '{\"Days\":0',\r\n       ',\"Hours\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[0])),\r\n       ',\"Minutes\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[1])),\r\n       ',\"Seconds\":', string(int(split(dateDifference(outputs('StartDate'), outputs('EndDate')), ':')[2])),\r\n       '}'\r\n     )\r\n   )\r\n)","runAfter":{"EndDate":["Succeeded"]},"metadata":{"operationMetadataId":"03c8d578-576a-41a3-8d63-609a15ce594b"}}},"runAfter":{"Add_to_time":["Succeeded"]}},"allConnectionData":{},"staticResults":{},"isScopeNode":true,"mslaNode":true}

    Step 2: In Power Automate click the + to add an action. Click Paste an action

    Conclusion

    That’s it! pretty easy right? if you encounter any issues, comment below!