An order-qualification demo I built for a conference runs on three Copilot Studio specialist agents, and they have genuinely different permissions. The Sales agent cannot pull a credit profile. The Finance agent cannot see inventory. That finding, and why the maker portal hides it behind a single shared connector name, is Works on My Agent, the New "Works on My Computer", published November 6, 2026. The agents themselves, their custom MCP server and the demo database are published at cronus-order-management-agents, so none of what follows has to be taken on trust.
Then I went looking for the code that enforces those permissions, and that is where this stopped being a documentation story.
The setup, briefly
An orchestrator with no tools of its own delegates to the three specialists, and all three reach business data through a single custom MCP server holding eight tools. Custom in the Copilot Studio sense: one I wrote and added by URL, rather than one picked from the gallery. Each agent's action declares UseSpecificTools with its own disjoint slice of those eight: four for Sales, two for Finance, two for Inventory. A real constraint rather than a prompt, and it holds whatever the model decides it wants.
Where I expected to find the check
On the server. A tool grant that matters is one the data source also believes in, so I opened the MCP server source expecting an API key check or a bearer token, something that would reject a call for get_inventory arriving on a Finance credential.
There is no authentication in it at all. No key check, no token, no identity. The server answers whatever reaches /mcp.
The connector agrees, which is the part worth looking at, because it means this was not an oversight on one side only. From the exported connector definition:
"securityDefinitions": {},
"security": []
Those two empty values are an OpenAPI definition saying there is no authentication scheme and no scheme applied to any operation. The connector's connectionparameters.json is likewise an empty object. Copilot Studio is not quietly holding a credential back; it has none to send, and the server would not check one if it did.
So what exactly is the grant?
Real, and entirely client-side.
Copilot Studio honors the tool list. The Finance agent cannot call get_inventory, today or under a prompt-injection attempt, because the tool is not in its catalog. That is worth having. What it is not is a permission on the data: it constrains what the model may ask for and does nothing to anyone talking to the server directly. My own setup notes for that demo said devtunnel create --allow-anonymous, so for as long as the tunnel was up the whole eight-tool surface was one URL away for anybody who had it.
None of this is a Copilot Studio defect. It did precisely what it documents. The mistake was mine, and it is an easy one: I read a tool list as an access control. A catalog governs what the orchestrator may reach for; a permission governs what the data will answer. They look identical right up until the caller is not your agent.
Putting the control where it cannot be routed around
Which raises the obvious question: should this be a custom server at all, when Microsoft ships MCP servers for SQL?
The first thing most of us reach for is the wrong one. The Azure MCP Server has a sql namespace, and it is control-plane: list servers, get database details, list firewall rules and elastic pools, create a server. It manages the resource, it cannot read your rows, and it replaces nothing that answers a business question.
The data-plane one is SQL MCP Server, part of Data API builder. It exposes seven generic DML tools, read_records and execute_entity among them.
NOTE: that word generic is a trap, and it is this whole post in miniature. My eight tools are domain-specific, and the domain specificity is what makes UseSpecificTools expressive. Hand an agent a generic DML surface and the most precise grant you can write is read_records, which reads every entity you exposed. The scoping does not get weaker; it stops existing.
Two features turn that around. Its role-based access control is per entity and per field, and the documentation is explicit that those rules apply automatically to every MCP tool. And a stored procedure can be registered as a named MCP tool with "custom-tool": true, so a credit-exposure calculation stays a named tool instead of dissolving into read_records. Together they move the grant to the server side, where neither the orchestrator nor anyone holding the URL can route around it.
That is a rewrite rather than a migration, so I am not going to wave at it in a closing paragraph and call it advice. Actually rebuilding the eight tools that way is the subject of another post.
Most SQL Server is not in Azure
Worth saying out loud, because everything above reads like an Azure story and it is not one. Data API builder is open source and free, and the documentation describes the server as self hosted, able to run locally through the DAB command line. It reaches a database over a connection string. Your data does not have to move, and neither do you.
SQL Server 2025's own what's-new list carries SQL MCP Server under Developer, pointing at that same documentation, so there is no separate on-premises MCP server to go hunting for. And the feature-availability matrix marks stored-procedure custom tools as supported for MSSQL, which is the one capability this post leans on hardest.
What does not change is reach. Copilot Studio still has to get to the endpoint, so the tunnel-or-host question is identical whether the database sits in Azure SQL or in your own rack. Moving the grant to the server is a governance decision, not a migration.
The lab
Inside the repo linked at the top, the server's DEPLOYMENT.md carries the three routes and their sources: dev tunnel, hosting it properly, and the Data API builder question above. The six-table demo database ships as a SQL script, so the whole thing runs. The checklist for the sharing side is in connected-agent-access. Fair warning: it publishes a server with no authentication and says so in the first section of its README, because the point of publishing it is that the gap is visible.
Final Notes
There is one question to ask of any tool grant in any orchestrator, and it is not whether the grant is honored. It is: who enforces this when the caller is not the agent?
If the answer is the orchestrator, you have a catalog: useful, worth configuring carefully, not a permission. If it is the server or the identity the call runs under, you have a permission, and the catalog is a convenience sitting on top of one.
What I learned from this exercise: a control you can only see from inside the thing it is controlling is a control you have not tested.
Until next post!
MG.-
Mariano Gomez Bent
Former Microsoft BizApps MVP

Comments