Tag: Power Platform

  • How MCP Actually Works Under the Hood When an Agent Calls a Tool

    How MCP Actually Works Under the Hood When an Agent Calls a Tool

    Diagram showing how MCP works under the hood between an AI agent and a tool server

    Most people treat MCP as the thing that lets their agent call tools, as if it were a fancier function-calling wrapper. That mental model gets you through demos and breaks the moment you try to run something real. If you want to understand how MCP works under the hood, you have to stop thinking about it as a plugin format and start thinking about it as a stateful client-server protocol built on JSON-RPC 2.0.

    Towards Data Science published a solid walkthrough of the protocol recently, MCP Explained: How Modern AI Agents Connect to the Real World, and it lines up with what I have been reading in the official Model Context Protocol spec. This post is my attempt to compress the mechanism into a mental model you can actually use when you design servers for Power Platform agents.

    The Surface Behaviour: What You See When an Agent Calls an MCP Tool

    From the outside, an MCP call looks trivial. You wire an MCP server into Copilot Studio or a Power Apps agent, the agent picks a tool, arguments get filled in, a result comes back, and the model uses it in the next turn. It feels indistinguishable from a REST connector.

    That is the illusion. Underneath, three things are happening that a REST connector never does: the client and server negotiated capabilities before any tool call happened, the server is exposing tools, resources, and prompts as separate primitives, and the connection is a live session, not a stateless request. The agent is not just calling an endpoint. It is holding a conversation with a server that has told it what it can do.

    Underneath: JSON-RPC, the Handshake, and Capability Negotiation

    MCP rides on JSON-RPC 2.0. Every message is a JSON object with a method, params, and either an id (for requests) or no id (for notifications). Nothing exotic. What matters is the sequence.

    When an MCP client connects to a server, the first thing it sends is an initialize request. This carries the client’s protocol version and its capabilities. The server responds with its own protocol version, its capabilities, and metadata like server name and version. The client then sends an initialized notification to confirm the handshake is done. Only after this does tool discovery happen, usually through a tools/list call.

    Capability negotiation is the piece people miss. The server advertises whether it supports tools, resources, prompts, sampling, logging, and so on. The client picks up only what it understands. This is why an MCP server built against a newer spec can still work with an older client. Backward compatibility is baked into the protocol.

    Then there are the three primitives:

    • Tools are model-invoked. The agent decides when to call them.
    • Resources are application-controlled. The host app decides what to expose.
    • Prompts are user-invoked. Templates the user can trigger.

    Most people conflate all three into tools. That is why their MCP servers feel bloated. If a chunk of data is really a reference document, it should be a resource, not a tool. Tools are for actions with side effects or computed answers.

    Edges and Limits: Transports, Session State, Schema Drift, and Auth

    MCP is transport-agnostic in principle but the two real options are stdio and HTTP with Server-Sent Events (or the newer streamable HTTP transport). Stdio is fine for local dev. For anything hosted, you are on HTTP, and that opens the usual questions about session identity, reconnection, and load balancing.

    Session state is the first sharp edge. An MCP session is stateful. If your server is behind a load balancer with no sticky sessions, you will see broken initialize sequences and mysterious method not found errors after a reconnect. This is not a bug. It is the protocol working as designed against infrastructure that assumed statelessness.

    Schema drift is the second. Tool schemas are exchanged at tools/list time. If your server changes a tool’s input schema mid-session without notifying the client via notifications/tools/list_changed, the agent will keep calling the old shape and fail silently or noisily depending on how strict your validation is. The new Dataverse MCP server tool shape is a good example of what a clean split between metadata inspection, querying, and search actually looks like in practice.

    Auth is the third. The core MCP spec deliberately left auth as a transport concern for a long time. The newer authorization spec pins it to OAuth 2.1. If you are wiring an MCP server into an enterprise agent, this is where you spend most of your time, not on the tool logic itself.

    What This Means When You Build an MCP Server for Power Platform Agents

    A few concrete implications for anyone pointing Copilot Studio or Power Apps agents at MCP.

    Design tool descriptions as retrieval hints, not documentation. I wrote about this in how Copilot Studio agent tool selection actually works. The orchestrator scores names, descriptions, and parameter names together. MCP does not change that. It just gives you a cleaner surface to expose them from.

    Split tools, resources, and prompts properly. If you dump everything as tools, you inflate the tool count, degrade selection quality past ten to fifteen entries, and force the model to reason about things that should have been passive context.

    Treat session lifetime as part of your design. Idle timeouts, reconnect logic, and schema change notifications are not edge cases. They are the load-bearing parts of a production MCP server. The same session and state management issues are a core reason AI agents fail in production when they worked fine in testing.

    MCP is not a plugin format. It is a protocol. Build servers like protocol servers and the sharp edges stop cutting. Skip that and you are building another silo with extra JSON on top. In my day-to-day, that shift in framing is what changes the design.

    Frequently Asked Questions

    How does MCP work under the hood when an agent calls a tool?

    MCP is a stateful client-server protocol built on JSON-RPC 2.0, not a simple function-calling wrapper. Before any tool call happens, the client and server go through a capability negotiation handshake, the server declares what it supports, and only then does tool discovery take place. The connection stays live as a session rather than being a stateless request like a REST call.

    What is the MCP handshake and why does it matter?

    When an MCP client connects to a server, it sends an initialize request containing its protocol version and capabilities, and the server responds with its own. The client then sends an initialized notification to confirm the exchange before any tools are listed or called. Skipping this step or misunderstanding it is a common reason real implementations break outside of demos.

    What is the difference between MCP and a standard REST connector?

    A REST connector is stateless, meaning each request stands alone with no shared context. MCP maintains a live session, negotiates capabilities upfront, and exposes tools, resources, and prompts as distinct primitives. This makes it better suited for agents that need to understand what a server can do before deciding how to use it.

    Why does MCP use JSON-RPC 2.0 instead of a simpler format?

    JSON-RPC 2.0 gives MCP a lightweight but structured message format that distinguishes requests from notifications and pairs responses to the correct request using an id field. This structure supports the sequenced, session-based communication that MCP requires, while remaining simple enough to implement across different clients and servers.

    This post was inspired by MCP Explained: How Modern AI Agents Connect to the Real World via Towards Data Science.

  • Dataverse Plugin for Coding Agents Landed in the Cursor Marketplace and I Want to Wire It Up Today

    Dataverse Plugin for Coding Agents Landed in the Cursor Marketplace and I Want to Wire It Up Today

    Dataverse plugin cursor marketplace listing shown inside the Cursor editor

    Microsoft shipped the Dataverse plugin for coding agents to the Cursor Marketplace on July 21. That is the dataverse plugin cursor marketplace listing I have been waiting for since the plugin first landed for GitHub Copilot. Cursor is where a lot of developers I talk to actually spend their day, and now they can query, generate, and reason about Dataverse from inside that editor without switching windows.

    I am going to install this today. Here is what it does, why the distribution channel matters more than the feature list, and what I am pointing it at this week.

    What the dataverse plugin cursor marketplace listing actually does

    The plugin exposes Dataverse to Cursor’s agent as a tool surface. It reads live metadata from a connected environment, so when you ask the agent to generate a plugin, a custom API, a PCF control, or a complex Power Automate expression, it grounds the output in the actual table schema, column logical names, and relationships that exist in your target environment.

    That is the same grounding story I wrote about when the plugin first landed for coding agents. The model is not guessing at new_customerid versus cr123_customerid based on training data from tutorials. It is querying your environment and diffing against what is really there.

    Practically, in Cursor that means:

    • Ask the agent to scaffold a plugin registration and it uses your real entity metadata.
    • Ask it to write a fetchXML query and it validates against columns that exist.
    • Ask it to generate a TypeScript client for a custom API and the signatures match your published definitions.

    You connect it with an app user in a dev environment. Not System Administrator on prod. That was the wrong setup for the Copilot version and it is still the wrong setup here.

    Why the Cursor Marketplace channel matters

    The feature itself is not new. The distribution is. Microsoft meeting developers inside Cursor is a signal, and I think it is the more interesting story than the plugin capabilities.

    Cursor is not a Microsoft product. Two years ago I would not have expected the Power Platform team to ship a first-party plugin into a competing editor’s marketplace. That they did says the pro-code path into Dataverse is now considered strategic enough to follow developers wherever they already are, rather than trying to pull them back into VS Code or the maker studio.

    Marketplace distribution also changes the adoption math. Installing a plugin from a marketplace with a single click is a completely different friction curve than cloning a repo, running a setup script, and fighting with auth. I have watched pro devs skip the Dataverse story entirely because the tooling did not meet them where they work. This removes that excuse.

    There is a governance angle too. When your devs are pulling MCP-style tools from random community repos, your platform team has no view into what is connected. A first-party plugin in a known marketplace is auditable. It is the same trust-signal argument I made about certified MCPs in the July Dataverse update, just applied to the coding surface instead of the runtime surface.

    What I would do with it this week

    I have a dev environment with a solution I have been slowly refactoring. Custom tables, a few plugins, one custom API that needs a proper TypeScript client, and a PCF control that is still half-configured. That is my test bed.

    My plan for the week:

    • Install the plugin from the Cursor Marketplace and connect a least-privilege app user scoped only to the dev environment.
    • Point Cursor’s agent at the custom API and have it generate a typed client. Diff the output against what I would have written by hand.
    • Ask it to write a plugin that reacts to a specific message on a custom table and check whether it correctly uses my column logical names, not invented ones.
    • Try a deliberately ambiguous prompt (“add validation to the account form”) and see whether it grounds the answer in real metadata or hallucinates a JavaScript path.
    • Compare the same prompts side by side in Cursor and in the GitHub Copilot version to see if the tool responses diverge. The new Dataverse MCP server tool shape splits metadata inspection and querying into cleaner boundaries, so I am curious whether that distinction surfaces differently across editors.

    I will write up what I find. My prior from building things internally is that grounding fixes maybe 70 percent of the hallucination problem on Dataverse code, and the remaining 30 percent is prompt discipline and knowing when to stop trusting the agent. Curious to see whether Cursor’s agent loop changes that ratio in either direction. If you want a framework for thinking about where that remaining cost lands, the useful work per dollar measurement approach I laid out for Power Platform agents applies here too.

    If you live in Cursor, install it today and try it against a real solution, not a demo one.

    This post was inspired by Dataverse Plugin for Coding Agents Now Available in Cursor Marketplace via Microsoft Power Platform Blog.

  • Power Apps MCP Server Just Got Closed-Loop Learning and I Want to Point It at a Real Agent This Week

    Power Apps MCP Server Just Got Closed-Loop Learning and I Want to Point It at a Real Agent This Week

    Power Apps MCP server closed-loop learning diagram for enterprise agents

    Microsoft dropped the June 2026 Power Platform feature update on June 11, and the headline for me is Power Apps MCP server closed-loop learning for enterprise agents. Not a UX refresh. Not another connector. A real change in how agents get better after you ship them.

    The rest of the update is worth reading too, but this is the one I want to test against a real internal agent this week.

    What shipped on June 11

    The Power Apps MCP server now supports closed-loop learning. In practice that means the agent can adjust its grounding and skill selection based on how it is actually being used, without a developer manually rewriting prompts or retraining anything.

    Before this, teaching an agent your org meant one of two paths. Either you fed it documents and custom instructions and hoped the retrieval was good enough, or you stood up a data science workflow to run evaluation and optimization cycles yourself. Both paths break down at maintenance time. Docs go stale. Nobody wants to rerun eval jobs every quarter.

    Closed-loop learning changes the shape of that problem. Outcome signals from real usage flow back into the agent’s behavior at runtime.

    What Power Apps MCP server closed-loop learning actually does

    To be precise about what is and is not happening here: the underlying model is not being fine-tuned. What is being updated is the agent’s grounding layer and its skill selection policy, based on outcome data that lands in Dataverse.

    I wrote about this separation before in my post on the MCP server as the feedback layer. Skills are the policy layer. The MCP server signals are the feedback layer. Keep those two straight and the mental model holds up.

    The technical surface, as far as I can read from the docs and the Power Platform learn pages, looks like this. When a user interacts with the agent, outcomes get captured. Not just accept or reject clicks, but structured signals about what worked and what did not. Those signals feed a learning loop that updates how the agent grounds itself and which skills it reaches for in a given context. The Dataverse MCP server tool shape update that split metadata inspection, querying, and search into cleaner boundaries is part of what makes this grounding layer more precise.

    That is closer to how a good colleague gets better at their job than how a model gets fine-tuned. Which is the point.

    Why this changes the agent maintenance story

    Most internal agents I see, and most I hear about from people at other organisations, are frozen at deploy time. They make the same mistake in month four that they made in week one, until someone finally opens a ticket and a developer patches the prompt. That is not maintenance. That is triage. It is also exactly the kind of failure pattern I covered in why AI agents fail in production when they worked fine in testing.

    Closed-loop learning breaks that pattern if you set it up carefully. The agent adapts to how the process actually runs, not how the process was documented eighteen months ago when the SOP was last updated. Process drift stops being invisible.

    The trade-off is real though. Runtime learning means the audit story gets harder. Version history now has to cover learned behavior, not just authored skills. If a policy owner asks why the agent behaved differently in July than it did in May, someone has to be able to answer that from data, not from memory. Microsoft has not fully answered that governance question yet, and I want to see how the audit surface actually looks in a live environment.

    The other risk is signal quality. If your team treats every user click as positive feedback, you are teaching the agent that fatigue clicks and correct clicks mean the same thing. They do not. The learning loop is only as good as the signals you decide to trust.

    What I would do with it this week

    I have an internal agent in mind that has been quietly degrading for a few months. Not broken, just noticeably less useful than at launch. Perfect candidate.

    The plan looks like this. First, turn on closed-loop learning in a non-production copy and run it against a shadow traffic sample for a few days. Second, define the outcome signals I actually trust ahead of time, before I look at any data. Accept-without-edit is one signal. Accept-with-edit is another and it means something different. Explicit thumbs down is the cleanest. Fatigue clicks I want to filter out entirely.

    Third, set a review cadence. Not because I do not trust the loop, but because I want to see what it learns and whether the changes match the policy the skill owner would have made themselves. Having a clear way to measure whether the agent is actually improving is where a framework like measuring useful work per dollar for Power Platform AI agents becomes useful alongside the learning loop.

    If the learned behavior lines up with what a human policy owner would do, the loop is doing its job. If it drifts somewhere I did not expect, that is the interesting part.

    This is the first update in a while where I closed the browser tab and immediately opened a new one to start planning a test. I cannot wait to see how it holds up on a real workload.

    This post was inspired by What’s new in Power Platform: June 2026 feature update via Microsoft Power Platform Blog.

  • Link to Fabric Just Got a UX Refresh and the Setup Friction Finally Drops

    Link to Fabric Just Got a UX Refresh and the Setup Friction Finally Drops

    Link to Fabric UX refresh setup screen in Power Platform

    Microsoft announced a Link to Fabric UX refresh on July 20, 2026. Same underlying capability, cleaner setup path. If you have been putting off wiring Dataverse into Fabric because the old flow felt heavy for anyone who is not a data engineer, this is the week to revisit it.

    I have set this thing up more times than I want to count. The capability was solid. The setup screens were where people bailed.

    What the Link to Fabric UX refresh actually does

    The refresh does not change what Link to Fabric is. You are still creating a managed replication of Dataverse tables into a Fabric workspace, landing them as Delta Parquet, and getting a SQL analytics endpoint on top. That plumbing is unchanged.

    What changed is the front door. The old flow had too many decision points stacked in the wrong order. You picked a workspace, then got prompted about capacity assignment, then got a table picker that dumped every table in the environment on you, then had to reason about which relationships and long-term retention flags mattered. Makers who were building a Power App and just wanted their data in Fabric for a Copilot grounding source would get halfway in and close the tab.

    The new flow collapses those decision points. Table selection is filtered and searchable by default. The workspace and capacity checks happen up front so you fail fast if permissions are wrong, instead of after you have already picked twelve tables. The confirmation screen actually tells you what will happen and roughly when.

    It is a UX pass, not a feature drop. That is fine. The feature was already there.

    Why the Link to Fabric UX refresh matters

    Setup friction is one of those things that sounds like a small thing until you count how many projects it kills. I have watched teams decide against Fabric entirely because their first attempt at Link to Fabric turned into a two-week ticket exchange with the platform team over capacity and workspace roles. By the time it was sorted, someone had already built a Power BI dataflow against the Dataverse connector and moved on.

    The other reason this matters is agents. I wrote about low-latency sync for Dataverse to Fabric going GA a while back. That closed the freshness gap. This closes the onboarding gap. If you are building agents that ground on Dataverse data through Fabric, both of those need to be easy. A capable data path that nobody sets up correctly is not a data path.

    The people who benefit most here are not the data engineers. They already had the old flow memorised. It is the Power Platform makers who own a solution end to end and need analytics or agent grounding without filing a ticket to a separate team. That is a real audience, and it has been underserved on this specific path for a while. If you are thinking about how to evaluate what that grounding work actually costs versus what it returns, measuring useful work per dollar for your Power Platform AI agents is worth reading alongside this.

    What you give up: nothing that I have found. The advanced controls are still there, they are just not in your face on step one.

    What I would do with it this week

    Three concrete things.

    First, take a Dataverse environment where you previously gave up on Link to Fabric and try it again. Time the setup. If it went from a half-day of back and forth to under thirty minutes, that is your signal to standardise on this path for future work.

    Second, wire a small agent against the resulting Fabric tables. Nothing fancy. A Copilot Studio agent with a knowledge source pointed at two or three tables you replicated. See how the answers feel with fresh data underneath. If you are still weighing whether to pull from SharePoint or Dataverse for that knowledge source, my SharePoint vs Dataverse as a Copilot Studio knowledge source comparison lays out the decision rule clearly. This is the loop I keep coming back to, and I have written more about how I think about grounding sources on my LinkedIn.

    Third, revisit your Link to Fabric documentation and admin guardrails. The easier the setup gets, the more makers will do it themselves, which means capacity governance and workspace access reviews matter more, not less. Easier onboarding without governance turns into skill sprawl’s cousin: workspace sprawl.

    The pattern here is familiar. Microsoft ships the capability, then eighteen months later ships the UX that makes people actually use the capability. That gap is where a lot of good features go to die. Glad this one did not.

    Next up on my watchlist: whether the same treatment lands on the mirroring configuration screens.

    This post was inspired by Announcing Link to Fabric UX refresh via Microsoft Power Platform Blog.

  • SharePoint Copilot Apps Just Hit Public Preview and the Structured UX Layer Is What Caught My Eye

    SharePoint Copilot Apps Just Hit Public Preview and the Structured UX Layer Is What Caught My Eye

    SharePoint Copilot Apps public preview structured UX layer inside Microsoft 365 Copilot

    Microsoft shipped SharePoint Copilot Apps public preview this week on the Microsoft 365 Developer Blog. The pitch is simple: guided, action-oriented business experiences that live inside the Microsoft 365 Copilot flow, combining natural language reasoning with structured UX, validation, permissions, and deterministic operations. Source is here.

    I read the post twice. Not because it is dense, but because this fills a gap I have been complaining about internally for months.

    What it actually does

    A SharePoint Copilot App is a declarative app definition that sits inside SharePoint and surfaces inside Microsoft 365 Copilot as a first-class action target. When a user asks Copilot to do something that matches the app’s intent, Copilot hands off to the app, which then renders a structured form or guided flow with validated inputs, honors SharePoint permissions, and executes deterministic operations against SharePoint data.

    So instead of Copilot free-forming a response and hoping the model picked the right list columns, the app enforces the shape of the operation. Required fields are required. Dropdowns are dropdowns. Permissions are the permissions the underlying SharePoint site already has. The reasoning layer stays in Copilot. The execution layer is deterministic.

    It is not a Power App. It is not a Copilot Studio agent. It is a SharePoint-native app model that Copilot knows how to invoke.

    Why it matters

    Pure natural-language Copilot interactions are great for exploration and terrible for repeatable business actions. I have written about this before in the Copilot in Power Apps post: coherent is not the same as correct. When an agent writes a record based on a chatty back-and-forth, you get answers that sound complete and quietly did the wrong thing.

    The pattern I keep seeing is teams reaching for a full Copilot Studio agent when what they actually need is a form with three fields, a validation rule, and a write to a SharePoint list. That is overbuild. It is also brittle, because now you have a system prompt, tool definitions, and a Power Automate flow all trying to model behavior that a simple structured input would have handled correctly the first time. If you want to understand why that brittleness compounds once the agent hits production, Why Do AI Agents Fail in Production When They Worked Fine in Testing covers exactly that failure pattern.

    SharePoint Copilot Apps land right in that gap. If the process is SharePoint-heavy, the data already lives there, and the action is well-shaped, this is closer to your use case than a custom agent. You get the Copilot entry point without paying the tax of building deterministic execution on top of a probabilistic layer.

    The trade-off is real. You are locked into SharePoint as the substrate. You give up the flexibility of a Copilot Studio agent that can orchestrate across multiple systems. And you inherit whatever SharePoint permission model you already have, which is a gift or a curse depending on how tidy your sites are.

    There is also the honest question of where this sits against Power Apps. A canvas app already does structured input against SharePoint. What Copilot Apps add is the Copilot invocation surface. Users do not have to know the app exists or navigate to it. They say what they want in Copilot and the app appears in the flow. That is the actual delta.

    What I would do with it this week

    I would pick one high-volume, low-complexity SharePoint process. Something like a request submission, a status update, or a document check-in with metadata. The kind of thing that today is either a clunky SharePoint form or a Power App that nobody uses because they forget the URL.

    Then I would rebuild it as a SharePoint Copilot App and see two things. First, does Copilot route to it reliably when users describe the intent in their own words. Second, does the structured form catch the mistakes that a free-form Copilot conversation would have quietly committed. Both of those are testable in a day.

    If routing is unreliable, that is the same failure mode I flagged in the multi-agent orchestration post. Descriptions matter more than trigger phrases. Write them like documentation, not marketing copy. The same principle applies inside Copilot Studio — How Copilot Studio Agent Tool Selection Actually Works Under the Hood is worth reading alongside this if you want to understand how the orchestrator scores and selects actions.

    For deeper Copilot extensibility context, the Microsoft 365 Copilot extensibility docs are the reference I would keep open while building. And if you want to compare notes on where this fits in the stack, I am usually posting about it on LinkedIn.

    I want to see how the routing behaves under real user language before I commit to a pattern, but this is the first structured action surface inside Copilot that feels appropriately scoped rather than oversized.

    This post was inspired by SharePoint Copilot Apps Now in Public Preview: From Intent to Action in Microsoft 365 Copilot via Microsoft 365 Developer Blog.

  • How Copilot Studio Agent Tool Selection Actually Works Under the Hood

    How Copilot Studio Agent Tool Selection Actually Works Under the Hood

    Diagram of copilot studio agent tool selection at runtime

    Most people building agents think copilot studio agent tool selection works like this: you attach a few tools, write a description for each, and the LLM reads the list and picks the right one. That is directionally correct and completely misses what is actually happening at runtime. The orchestrator runs a planning pass. It scores your tools against the current turn. Descriptions, input schemas, and even the order of your tools all feed that scoring.

    Once you see the mechanism, you stop writing tool descriptions like documentation and start writing them like retrieval hints. That changes how you name inputs, how many tools you attach to one agent, and when you split an agent instead of adding a fourteenth tool.

    What you see from the maker portal

    In the maker studio, you attach a tool to an agent. You give it a name, a description, and an input schema (either from a connector, a Power Automate flow, an MCP server, or a prompt). At runtime, you type a message, the agent thinks for a moment, and calls one of the tools. The trace view shows you which tool was picked and what inputs were passed.

    That surface makes it look like the model reads the list top to bottom and picks the best match. It is not that simple. The trace hides the planning pass, and the planning pass is where 80% of the reliability of your agent lives. Microsoft’s generative orchestration docs hint at this but do not spell it out in the way a builder needs.

    What the orchestrator is actually doing

    Between the user turn and the tool call, the orchestrator does something closer to retrieval than dispatch. It takes the current turn, the conversation history, and the agent instructions, and it scores each attached tool for relevance. The scoring uses the tool name, description, input parameter names, parameter descriptions, and enum values if present. Tools with vague names and thin descriptions score badly regardless of how logically correct they are.

    Then the planner picks a candidate tool, resolves inputs from the turn context (or asks the user for missing ones), and invokes. If the invocation fails or the result is empty, the planner may retry with a different tool. That retry loop is where token budget disappears and latency creeps up.

    This is the same pattern you see in the Copilot Studio release plans that describe how tools and knowledge sources get grounded per turn. It is a retrieval problem wearing a routing costume.

    Where the mechanism breaks down

    Three failure modes show up over and over. I wrote about the schema version of this in the Dataverse MCP server tool shape post, but it applies to every tool surface.

    Overlapping descriptions. Two tools both say something like “Get information about an order.” The planner cannot tell them apart at the description layer, so it falls back to parameter matching, which is noisier. You get silent misrouting where the agent confidently picks the wrong tool.

    Vague input schemas. A parameter called id of type string tells the planner nothing. A parameter called customerAccountNumber with a description like “6-digit customer account, not the order number” gives the planner something to bind against.

    Long tool lists. Once you attach more than roughly 10 to 15 tools, scoring quality degrades. The signal gets noisy. This mirrors what happens when you stuff too much into a system prompt, which I covered in the business skills post.

    How to build once you know this

    Write tool descriptions as retrieval hints, not documentation. State what the tool does, when to use it, and critically, when not to use it. “Use this to look up an order by its order number. Do not use this for customer profile lookups.” That negative clause is doing work.

    Name parameters like a human would search for them. orderNumber beats id. Add a description on every parameter, even the obvious ones. Enum values are gold because they narrow the planner’s search space to something concrete.

    Cap tool count per agent. If you find yourself attaching a fourteenth tool, split the agent by domain and use multi-agent orchestration to route between them. A focused agent with 6 well-described tools outperforms a monster agent with 20 tools every time. The same principle applies when deciding where your agent reads its data from — something I break down in SharePoint vs Dataverse as a Copilot Studio Knowledge Source.

    Test the routing, not just the tools. Write a set of representative user turns and check which tool the planner picks. If two tools tie or the wrong one wins, fix the descriptions before you touch the model or the instructions. That is the fastest debugging loop I have found, and it is one I keep coming back to in my own work.

    The mechanism is not magic. It is retrieval with extra steps. Once you build for that, your agents get more predictable, cheaper to run, and easier to explain to a stakeholder.

    Frequently Asked Questions

    How does Copilot Studio agent tool selection actually work at runtime?

    Rather than simply reading a list of tools and picking the best match, the orchestrator runs a planning pass that scores each tool based on relevance to the current turn. It factors in the tool name, description, input parameter names, and any enum values before selecting a candidate and resolving the required inputs. This scoring process is closer to retrieval than traditional routing.

    Why does my Copilot Studio agent keep picking the wrong tool?

    Vague tool names and thin descriptions are the most common cause, as the orchestrator scores tools for relevance and poorly described tools rank badly even if they are logically the right choice. Writing descriptions as retrieval hints rather than documentation, and being specific with parameter names, will improve selection accuracy significantly.

    How do I write better tool descriptions for a Copilot Studio agent?

    Instead of writing descriptions like reference documentation, treat them as signals that help the orchestrator match the tool to user intent. Be specific about what the tool does, what inputs it expects, and when it should be used rather than a similar tool. Precise parameter names and enum values also feed into the scoring process.

    When should I split one Copilot Studio agent into multiple agents instead of adding more tools?

    As the number of attached tools grows, the scoring pass has more candidates to evaluate and the risk of the wrong tool being selected increases. If you find yourself adding a large number of tools to a single agent, splitting responsibilities across multiple agents can improve reliability and reduce latency caused by retry loops.

  • OpenAI Published a Map of AI’s Impact on EU Jobs and the Workflow Change Bucket Is Where I Live

    OpenAI Published a Map of AI’s Impact on EU Jobs and the Workflow Change Bucket Is Where I Live

    OpenAI EU AI workforce report covering job automation and workflow change in Europe

    OpenAI published Mapping Europe’s AI Workforce Opportunity this week, a report that tries to sort EU occupations by how AI will hit them. The OpenAI EU AI workforce report breaks roles into three buckets: jobs facing automation, jobs likely to grow, and the massive middle where workflows get reshaped without the role itself disappearing. That middle bucket is where I have spent the last several years of my career.

    The doom headlines will focus on bucket one. I want to talk about bucket two, because that is where the actual work is.

    What the OpenAI EU AI workforce report actually does

    The report maps occupations across the EU labour market against AI exposure, using task-level analysis rather than blunt job-title categorisation. It pulls from O*NET-style task decomposition and overlays current model capabilities to score how much of each role can be done by AI, augmented by AI, or left largely untouched.

    Three buckets come out the other end.

    The automation bucket holds roles where a large share of tasks are model-doable today. Think structured data entry, basic translation, first-line content moderation. The growth bucket holds roles that get more valuable because AI exists, including AI-adjacent engineering, training data work, and oversight roles. The workflow change bucket is the biggest of the three by headcount, and it covers knowledge workers whose individual tasks shift but whose overall job sticks around.

    The report is careful. It does not predict timelines. It does not claim to know how regulation, adoption rates, or organisational inertia will shape the actual outcome. It is a map of exposure, not a prophecy.

    Why it matters

    The workflow change bucket is the entire job description of a Power Platform developer, an RPA engineer, an automation consultant, or anyone who builds Copilot Studio agents for a living. We are the people who go into a role, decompose the tasks, and figure out which ones get handed to a flow, an agent, or a model call, and which ones the human still owns.

    The report is essentially describing the next five years of demand for this work.

    Where I think it is right: the middle bucket is huge, and most people underestimate it. Headlines about full job replacement get clicks, but the operational reality is task-level reshaping inside roles that keep their name on the org chart. A finance analyst is still a finance analyst, but half their reconciliation work now runs through an agent and they spend more time on exception handling and commentary.

    Where I think it understates the reality: the report treats workflow change as if it happens because the technology exists. It does not. Workflow change happens when someone redraws decision rights, and most organisations avoid that conversation because it is uncomfortable. I have watched plenty of automation projects stall not because the tech failed but because nobody was willing to say who owns the decision after the agent makes its recommendation.

    The report also does not capture the latency problem. A reshaped workflow where the AI step takes two seconds and the human approval step takes two days is not actually reshaped. It just has a faster front end and a longer queue.

    What I would do with it this week

    If you build automations for a living, read the report and find the occupations in your organisation that sit in the workflow change bucket. Not the automation bucket. The middle one. Those are the roles where you have the most leverage in the next twelve months, because the people in them are not afraid of being replaced. They want the boring parts gone.

    Then pick one task inside one of those roles. Just one. Decompose it. Figure out which steps a Power Automate cloud flow handles, which steps need a Copilot Studio agent, and where the human stays in the loop. Build a small version. Ship it to one team.

    This is the work. It is unglamorous. It is also exactly what the OpenAI EU AI workforce report says the EU economy is going to need a lot of, for a long time.

    I have been doing this work for a while and have written about the patterns that show up across these projects. The report does not change my day-to-day. It validates it.

    The next five years are going to be a lot of careful task decomposition inside roles that keep their names. That is fine by me.

    This post was inspired by Mapping Europe’s AI Workforce Opportunity via OpenAI.

  • Dataverse MCP Server Got a New Tool Shape and the Metadata Inspection Story Is What Stands Out

    Dataverse MCP Server Got a New Tool Shape and the Metadata Inspection Story Is What Stands Out

    Dataverse MCP server tool shape diagram showing metadata inspection and query tools

    Microsoft published a new post on June 8, 2026 walking through the updated Dataverse MCP server tool shape. The headline is that agents can now inspect metadata, query records, and search across structured and unstructured data through cleaner, well-defined tool boundaries. You can read the original write-up on the Power Platform blog.

    This is not a feature dump. It is a redesign of how the agent talks to Dataverse. And that is more interesting than it sounds.

    What it actually does

    The old tool surface gave agents a handful of broad tools and expected them to figure out the rest from context. In practice, that meant the agent would call a query tool, get back something it could not interpret, call again with different parameters, fail, and burn tokens guessing at column logical names. I have watched this happen in traces. It is not pretty.

    The new shape breaks the surface into clearer categories. Metadata inspection is its own thing now. The agent can ask what tables exist, what columns a table has, what the relationships look like, before it tries to query anything. Record querying sits next to that with predictable inputs. Search across structured and unstructured data is its own tool boundary, so the agent does not have to invent a strategy for whether to hit the relational side or the knowledge side.

    The practical effect: fewer wasted tool calls, less prompt bloat from stuffing schema hints into the system prompt, and more predictable agent behavior when it hits a Dataverse environment cold.

    Why it matters

    This connects directly to a pattern I keep hitting. When you wire an agent to business data, the model is rarely the problem. The friction is the discovery loop. The agent does not know your schema. It does not know your naming conventions. It does not know that your account table has a custom column called cr1a3_segment that nobody documented.

    The old answer was to dump schema into the system prompt. That works until your prompt crosses a few hundred tokens and agent reliability starts degrading. I wrote about this in the context of business skills in Dataverse, and the same logic applies here. Pushing knowledge into a managed, queryable surface beats stuffing it into a prompt every time.

    The new tool shape gives the agent a path to discover the schema on demand instead of carrying it around. That is the architectural shift. It is the same lesson I keep seeing play out across the agent stack: tighter tool boundaries beat broader ones, because they shrink the search space the model has to reason about.

    It also pairs well with the low-latency Dataverse to Fabric sync story. If your agent can inspect metadata cleanly on the operational side and pull near real-time analytical data on the Fabric side, the data path behind the agent finally starts feeling coherent instead of stitched together.

    What I am skeptical about: tool shape changes are easy to undo if the team gets feedback that agents want more flexibility. I hope Microsoft holds the line on the boundaries. Broad, do-everything tools are how you end up back where you started.

    What I would do with it this week

    First, point an agent at a non-production Dataverse environment with the updated MCP server and watch the tool call traces. Not the chat output. The traces. That is where you see whether the new shape actually reduces wasted calls or just renames them.

    Second, strip schema hints out of system prompts on any existing Copilot Studio agent wired to Dataverse, and let the metadata inspection tool do the work. Compare reliability before and after. I expect the shorter prompt wins, based on what I have seen building internally and on what I keep reading from peers at other organisations. The Dataverse plugin for coding agents that Microsoft shipped at Build 2026 is worth reading alongside this, because it tackles the same hallucination-from-missing-schema problem from a different angle. You can also check the Power Platform docs for the current setup steps.

    Third, write down which tool should handle which question type for your agent and treat that as a contract. If the agent starts calling the search tool for things that should hit the query tool, that is a sign your boundary is wrong, not that the tool is wrong. I have been writing about these patterns on LinkedIn for a while now, and the discipline of writing the contract down before deployment saves you a month-six cleanup project.

    If the new tool shape holds up under real workloads, this becomes the default way agents talk to business data on the Microsoft stack.

    This post was inspired by Dataverse MCP Server: Understanding the New Tool Shape via Microsoft Power Platform Blog.

  • Low-Latency Sync for Dataverse to Fabric Hit GA and This Closes a Real Gap in Near Real-Time Reporting

    Low-Latency Sync for Dataverse to Fabric Hit GA and This Closes a Real Gap in Near Real-Time Reporting

    Low-latency sync Dataverse to Fabric GA architecture diagram

    Microsoft announced on June 9 that low-latency sync for Dataverse to Fabric is GA. If you have ever tried to build operational reporting or trigger Fabric pipelines off Dynamics 365 CE or F&O data, you know the old replication window was the bottleneck. Low-latency sync for Dataverse to Fabric GA cuts that window down to something close to real-time, and it ships without requiring you to rearchitect the Link to Fabric setup you already have.

    I have been waiting for this one. The old 15 to 60 minute lag killed a lot of conversations before they started.

    What it actually does under the hood

    Link to Fabric has been around for a while. The original mechanism mirrored Dataverse tables into a Fabric OneLake shortcut using a delta sync that ran on a schedule. Reliable, cheap, fine for daily or hourly reporting. Useless for anything operational.

    Low-latency sync changes the replication path. Instead of waiting for the batch interval, Dataverse pushes change events into the Fabric-side tables on a much tighter cadence. Same OneLake destination. Same Delta format. Same shortcut model. The difference is the lag between a row being written in Dataverse and that row being queryable in Fabric.

    You enable it in the Link to Fabric configuration in the Power Platform admin center. Existing links can opt in. You do not have to tear down what you built. That is the part that made me actually want to test it this week instead of next quarter.

    One thing worth flagging. Low-latency sync is for the CE and F&O tables you already mirror. It is not a streaming pipeline replacement. If you need event streaming with custom transformations mid-flight, you still want Eventstream or a proper Spark job. This is operational reporting territory, not Kafka territory.

    Why this matters for reporting and agent scenarios

    Two reasons I care about this.

    First, operational dashboards. Anyone who has had the conversation with a sales ops lead about “can we see pipeline movement today” knows the answer was usually no, or we faked it with a direct Dataverse query that fell over at any real volume. With low-latency sync, the Fabric copy is fresh enough that a Power BI report on the OneLake shortcut actually reflects what is happening on the floor. That is a real shift in what you can promise.

    Second, and this is the one I am more interested in, agent scenarios. I have written before about Dataverse as the agent data platform. Agents that need to reason over historical or cross-table data are better off hitting the Fabric copy than hammering Dataverse directly. The old lag meant any agent reading from Fabric was working with stale context. A sales agent answering “what is the status of this account” off 30 minute old data is useless. Off near real-time data, it is finally credible.

    The latency question on agentic workflows is one I keep coming back to. It is not always the model that is slow. Often it is the data path behind the model. That same theme came up when I covered how Microsoft Build 2026 made Fabric and Azure Databases the foundation for agentic apps, and the low-latency sync GA feels like a direct follow-through on that direction.

    What I would do with it this week

    Three things, none of which require rearchitecting.

    One. Pick an existing Link to Fabric setup on a non-prod environment and enable low-latency sync on it. Measure the actual end-to-end lag. Write a row in Dataverse. Time how long until it shows up in a Fabric notebook query. The marketing number and the real number for your tenant are usually different. I want to know my number.

    Two. Take one Power BI report that currently runs on a scheduled Dataverse refresh and repoint it at the OneLake shortcut. See if the freshness story holds up when a business user pokes at it. This is the cheapest way to prove the value internally.

    Three. Wire a Fabric data pipeline to trigger off a Dataverse table change through the low-latency path and have it call back into a Power Automate flow via a webhook. This is the pattern I want to validate for agent grounding scenarios. Whether the trigger-to-action loop is tight enough to feel real-time end to end is the actual question. If you are also thinking about how Dataverse surfaces structured knowledge to agents, the post on Microsoft shipping business skills in Dataverse is worth reading alongside this one. The Link to Fabric docs have the setup details.

    I will probably write up what I find. Curious how this lands for anyone running heavy F&O workloads where the table volumes are an order of magnitude bigger than CE.

    This is the kind of plumbing release that does not get a keynote slot but quietly unblocks a year of stalled conversations.

    This post was inspired by Announcing Low-latency sync for Dataverse to Fabric in GA via Microsoft Power Platform Blog.

  • Microsoft Shipped a Dataverse Plugin for Coding Agents and This Fixes the Hallucination Problem

    Microsoft Shipped a Dataverse Plugin for Coding Agents and This Fixes the Hallucination Problem

    Dataverse plugin coding agents architecture diagram

    On June 4, Microsoft announced the Dataverse plugin for coding agents as a companion to their Build 2026 session. The pitch is simple. Coding agents are powerful, but without domain tooling they hallucinate and produce broken solutions. The Dataverse plugin for coding agents gives GitHub Copilot, Claude Code, and other agents guardrailed access to tables, columns, relationships, views, security roles, and solutions.

    I have been waiting for this one. Every time I let a coding agent touch a Power Platform solution, I spent half the session correcting hallucinated table names, fake column logical names, and FetchXML that referenced relationships that do not exist. This is the missing context layer.

    What it actually does

    The plugin exposes Dataverse as a tool surface that coding agents can call directly. Instead of the agent guessing what your account table looks like in your environment, it queries the actual metadata. Tables, columns with their real logical names, relationships, option sets, views, security roles, and solution boundaries. All grounded in the environment you point it at.

    It also handles writes through the same guardrailed path. The agent can scaffold a new table, add columns, set up a relationship, or modify a view, but it does it through the Dataverse API with proper solution awareness, not by generating XML files and hoping the import does not blow up. Solution context matters here. The plugin respects which solution you are working in, so the agent is not silently dropping unmanaged customizations into the default solution.

    The trade-off is permissions. The agent runs with the credentials you give it, which means scoping matters. You do not want a coding agent with System Administrator on a production environment. A dedicated app user with a least-privilege role on a dev environment is the sane setup.

    Why the Dataverse plugin for coding agents matters

    I have been saying for months that the hardest part of agent work is not the model, it is the context. Microsoft Just Shipped Business Skills in Dataverse and This Is How You Teach Agents Your Org fixed this for runtime agents. This fixes it for build-time agents.

    Think about what coding agents were doing before this. You ask Claude or Copilot to write a plugin against the contact table. It writes confident C# that references new_customerstatus as a column. That column does not exist in your environment. It exists in a tutorial the model saw during training. You compile, deploy, fail, debug, fix, repeat. The agent was fast at producing wrong code.

    With the plugin wired in, the agent reads your actual schema first. The generated code references real columns. FetchXML targets relationships that exist. Security role assignments use role IDs that resolve. The output goes from speculative to diffable.

    This is the same architectural shift the Power Pages agentic coding tools made. Ground the agent in the environment, then let it generate. The grounding is what turns these tools from impressive demos into something a pro dev team can commit to in CI.

    One more thing. This is explicitly a pro dev tool. It is not for citizen devs. The audience is the team writing plugins, custom APIs, PCF controls, and complex flows where hallucinated metadata costs hours. If your shop is doing solution-aware Power Platform work in source control, this changes the daily loop.

    What I would do with it this week

    I would spin up a sandbox environment with a copy of one of our more complex solutions. Maybe twenty tables, a handful of plugins, a few custom APIs. Wire the plugin into a coding agent against that environment with an app user scoped to a non-destructive role.

    Then I would run three tests. First, ask the agent to generate a plugin that does something the existing code already does, and diff the output against the real code. That tells me how close the grounded output gets. Second, ask it to extend an existing entity with new logic and check whether it picks the right solution context. Third, ask it to write FetchXML against a relationship chain three hops deep, because that is where hallucination used to be the worst.

    If those three pass, the next step is figuring out where this fits in the actual development workflow. Local agent runs for scaffolding, reviewed PRs into source control, normal pipeline deploys. The plugin does not change the deployment story. It changes what shows up in the PR. If you want to see how Microsoft has been building toward this foundation, the Microsoft Build 2026 Fabric and Azure Databases session makes the data-first direction clear.

    The Dataverse plugin for coding agents is the kind of release that is boring on the surface and quietly reshapes how a team builds. Read the Power Platform docs on it, scope an app user, and start testing this week. I will be writing more about what I find on LinkedIn as I push it through real workloads.

    The grounding layer for build-time agents has arrived. Now the work is wiring it into how teams actually ship.

    This post was inspired by Microsoft Dataverse Plugin: Unleashing Coding Agents on the Enterprise – Microsoft Build 2026 via Microsoft Power Platform Blog.