web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / The Dynamics GP Blogster / Same Agent, Two Architectur...

Same Agent, Two Architectures: When MCP Wins (and When It Doesn't)

MG-16101311-0 Profile Picture MG-16101311-0 26,225
Same Agent, Two Architectures: connector agent versus MCP agent in Copilot Studio


I know, I know. It has been almost five years since my last post, and in that time the masthead changed, the name changed, and frankly, the entire technology landscape changed with them. But I did not want to relaunch this blog with a ceremonial hello-world post, so instead, this first post from The Workbench starts out the way many of my posts have over the years: with a question.

The question comes up in just about every architecture review I sit in these days, whether in my day job as CTO or in conversations with folks in the community, and it goes something like this:

"Should we be using MCP for our Copilot Studio agents?"

I will be the first to tell you this is the wrong question. And rather than argue the point in the abstract, I built the same agent twice to prove it. Let's see how it's done!

Background

Model Context Protocol -- MCP for short, introduced by the folks at Anthropic -- has gone from curiosity to checklist item in record time, much like microservices did a few years back, and just like then, everyone wants to know where it fits before anyone has agreed on when it should. So, I put together a lab around a fictional but very realistic engineering program called Project Orion: a customer-facing web application mid-way through a major release cycle, with its operational truth split across two systems, the way it always is in real life:

  • GitHub Issues holds the code-level activity: 35 issues covering bugs, feature work, blockers, and performance problems.
  • A SQL Server database holds the delivery truth: five sprints of history, 70 work items, and 30 days of health metrics, including a release readiness score, critical bug counts, blocker counts, and velocity trend.

Now, the seeded data tells a story on purpose. Sprint 3 completed 38 of 45 points. Sprint 4 dropped to 33 of 44 with 11 points of rollover. The latest health snapshot shows a release readiness score of 52, three critical bugs, three blockers, and a velocity trend of Declining. Suffice to say, this project is quietly going sideways, and the signals are scattered across two systems that do not talk to each other.

With the stage set, I built the same agent twice in Microsoft Copilot Studio and asked both versions the same questions.

Version 1: the connector agent

The first agent uses nothing but the GitHub connector. Ten minutes of work, most of which is authentication, and here is the part that surprises people every time I demo it: this agent is good.

Ask it "What critical bugs are open in Project Orion?" and it answers cleanly, with issue numbers, titles, and labels. Ask it "What issues are labeled as blocked?" and it nails that one too. For questions whose answer lives entirely inside GitHub, the connector agent is fast, correct, and required exactly zero infrastructure from me -- no server to provision, nothing to patch, and it sits comfortably inside the tenant's existing governance and data loss prevention story, which your IT department will certainly appreciate.

Now, that's all cool, but then you ask it the ONE question your VP actually cares about: "What is blocking the Project Orion release?"

And there it is -- the ceiling! The agent can see three critical bugs in GitHub, so it reports three critical bugs. It cannot see that the release readiness score sits at 52 and falling, it cannot see that velocity has declined two sprints in a row, and it cannot see that two of the blocked work items have been stalled for over a week. Keep in mind, its answer is not wrong. It is something worse than wrong: it is confidently incomplete. A stakeholder reading that answer would walk away thinking the release has three bugs to fix, when the data says the release is structurally at risk.

In the lab version of this agent I made the limitation explicit, and I recommend you do the same for any single-source agent you ship. Its instructions include the following line:

"I can only see GitHub Issues data. For full project health including sprint metrics and release readiness, you would need access to the project health database."

An agent that states its blind spots is an agent you can trust. An agent that answers everything with whatever fraction of the truth it can reach is a liability wearing a chat interface. It just doesn't work!

Version 2: the MCP agent

The second agent is the same Copilot Studio agent rebuilt on two MCP servers: the GitHub MCP Server for issue data, and a custom TypeScript MCP server I wrote that fronts the Project Orion SQL database.

The custom server exposes seven tools, and I would encourage you to study the tool list closely, because this is where the real design work lives. These are not generic "run a query" endpoints; each one answers a question a human being would actually ask:

  • get_current_sprint: the active sprint with planned versus completed points
  • get_sprint_history: velocity and completion history across completed sprints
  • get_critical_work_items: open Critical and High priority items, including blocked ones
  • get_work_items_by_sprint: work items for a sprint, optionally filtered by status
  • get_latest_health_metrics: the current health snapshot, readiness score included
  • get_health_metrics_trend: readiness score over the last N days
  • get_stalled_work_items: items sitting in Active or New with no movement

Two implementation details will save you a considerable amount of head scratching, so pay close attention. First, as it turns out, Copilot Studio speaks HTTP, not stdio. Most MCP tutorials out there show the stdio transport, because that is what desktop clients use, but Copilot Studio requires the streamable HTTP transport running in stateless mode, with a fresh transport and server instance created for each incoming request. For brevity sake, I am only showing the shape of it:

// Copilot Studio requires HTTP transport in stateless mode
const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: undefined, // stateless: critical for Copilot Studio
});
// a fresh server + transport pair is created per incoming request
app.post('/mcp', async (req, res) => {
  const server = buildProjectOrionServer();
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

Second, validate your tool inputs. The model -- not you, not your code -- is choosing the parameter values at runtime, so every tool takes a schema, not a prayer:

server.tool(
  'get_health_metrics_trend',
  'Returns the release readiness score trend over the last N days ' +
  'to show whether project health is improving or declining.',
  { days: z.number().optional().default(14) },
  async ({ days }) => {
    const rows = await getHealthMetricsTrend(days);
    return { content: [{ type: 'text', text: JSON.stringify(rows) }] };
  }
);

A few things to note before moving on. That tool description string is not documentation for humans; it is the interface the model reasons over when deciding which tools to call and in what combination. Write your tool descriptions the way you would write requirements for a sharp new team member, because for all practical purposes, that is exactly what they are.

The moment it earns its keep

Now ask the rebuilt agent the same question: "What is blocking the Project Orion release?"

This time the agent calls get_critical_work_items and get_latest_health_metrics on the SQL side, pulls the open critical issues from the GitHub side, and then does the thing no single-source agent can do: it correlates. The three critical GitHub bugs map to blocked work items in the sprint; the blockers explain the 11 points of rollover in Sprint 4; the rollover explains the declining velocity trend; and all of it together explains a readiness score of 52. And voila! The answer reads like something a good release manager would write, complete with a one-line risk summary at the end, because the agent finally has the same field of vision the release manager has.

Ask it "Are there any patterns between our open GitHub issues and our sprint health?" and it produces an answer that did not have a data path to exist in Version 1. That is the difference, and it is worth being precise about it: not better answers to the old questions, but answers to questions that were previously UNANSWERABLE.

What MCP costs you

Here is the part the hype conveniently skips, and the part I lean on hardest whenever I present this material: everything above has a bill attached.

With the connector agent, Microsoft runs the integration. With the MCP agent, I run the integration. In the lab, the server is a TypeScript process on my laptop reached through an Azure Dev Tunnel, which is perfectly fine for a demo and perfectly irresponsible for production.

NOTE: the moment this architecture goes to production, you own hosting, authentication, TLS, availability, logging, patching the SDK, and the security review for a brand-new surface area that reaches directly into a database. The connector came pre-governed; your MCP server is governed by whatever you remembered to build.

So the honest comparison is not "MCP versus connector." It is "cross-source reasoning versus operational simplicity." Sometimes that trade is spectacular, and sometimes it amounts to buying yourself a server bill to answer questions a connector already answered. It is your job as an architect to know which of the two situations you are standing in.

The decision signal

After building both versions side by side, the rule I trust fits in one sentence:

When your agent needs to reason across sources it did not know about at design time, that is your MCP signal.

In practice, I walk through the following four questions:

  • Does the answer live in one system? Use the connector. You are done, and you inherited Microsoft's operations team for free.
  • Does the answer require correlating two or more systems in a single reasoning pass? That is your MCP signal. No amount of prompt engineering will give a single-source agent data it cannot reach.
  • Will the source list grow? MCP servers compose. Adding a third source to the Orion agent is another server registration, not a rebuild.
  • Can you operate a service? If the answer is no, that is not a character flaw, but keep in mind the connector ceiling is your ceiling until that answer changes.

Build it yourself

Everything in this post is reproducible from the lab I published for my Community Summit NA 2026 session in Nashville, "Same Agent, Two Architectures: When MCP Wins (And When It Doesn't)". The repository contains the SQL schema and seed data, a script that creates all 35 GitHub issues, scaffold prompts for the MCP server and a Next.js health dashboard, and the Copilot Studio prompts for both agents -- including the intentionally limited one:

github.com/dgpblogster/project-orion-lab

You need VS Code, Node 18+, SQL Server Express, the GitHub CLI, Azure Dev Tunnels, and a Copilot Studio license -- a trial works just fine. Budget an afternoon, and make sure you build toward the moment where you ask both agents the release-blocker question back to back, because watching one agent hit the ceiling and the other reason straight through it will teach you more about agent architecture than any slide deck, including mine. The effort is well worth it!

If there is interest, my next installment will walk through hardening this MCP server for real production use -- authentication, hosting, and telemetry -- so please drop a note in the comments if you would like to see that. It is good to be back at the bench.

Until next post!

MG.-
Mariano Gomez Bent
Former Microsoft BizApps MVP  


This was originally posted here.

Comments

*This post is locked for comments