← Back to selected work
Field Service MCP · Development case study

From business intent
to agent orchestration.

I built a Python MCP integration that lets Copilot Studio retrieve and combine Dynamics 365 Field Service data. The real development story is how bounded tools became useful business answers—and where explicit rules had to take over.

Live-data prototype4 read-only toolsAzure + Copilot StudioJanuary–March 2026
The operational challenge

A simple question.
Several system lookups.

A dispatcher’s question can span work orders, bookings and technicians. My goal was to expose useful Field Service capabilities so an assistant could retrieve that context through a small, defined integration surface.

My contribution: business framing, capability design, application authentication, Python implementation, direct tool validation, Azure deployment and Copilot integration—documented in a twelve-part development journal.

The demonstrated scenario

Ask once. Bring the context together.

QUESTION TESTED IN COPILOT STUDIO“Who are the technicians currently handling in-progress work orders?”
01 / RETRIEVEFind in-progress work

Copilot calls the work-order tool with a status filter.

02 / CONNECTInspect related bookings

It calls work-order details to obtain assignment context.

03 / EXPLAINConsolidate the answer

It presents technicians alongside the relevant work orders.

A multi-tool question answered in Copilot
A multi-tool question answered in Copilot
Original screenshot from the development article, showing technician assignments against sample work orders. Source ↗

This is the agentic behavior demonstrated here: selecting and combining available read tools in response to a business question. The prototype does not autonomously dispatch technicians or update work orders.

The integration foundation

Small capabilities. Composable behavior.

Copilot Studio connects to a Python FastMCP server hosted in Azure Container Apps. The server uses an Entra application identity to call the Dataverse Web API. Authentication, data access and MCP tool definitions are separated in the code.

get_work_orders

Retrieve work orders using supported filters and result limits.

get_work_order_details

Retrieve a specific work order and related detail.

list_field_technicians

Expose the field-resource lookup capability.

list_service_accounts

Expose service-account context.

Four capabilities exposed to Copilot Studio
Four capabilities exposed to Copilot Studio
The published tool configuration connects the business-oriented contract to the assistant. Source ↗

Identity boundary: this build uses a shared application identity. Dataverse roles and permissions govern its access. Per-user on-behalf-of authorization is a later design consideration, not a demonstrated feature of this implementation.

How the build matured

Validate each layer before adding the next.

1. Establish access

Register the Entra application and verify OAuth and Dataverse connectivity independently, using Postman and Python.

2. Design and test the tools

Map business questions to defined inputs and outputs. Validate discoverability and invocation directly in MCP Inspector.

3. Host and orchestrate

Package the server as a container, publish through Azure Container Registry and Container Apps, then connect the HTTPS endpoint to Copilot Studio.

Test the capability before the conversation
Test the capability before the conversation
MCP Inspector exposes the work-order tool’s status filter and bounded result input. Source ↗
The most useful design lesson

Flexible questions.
Explicit business calculations.

When the conversation moved from record retrieval to technician completion rates and overdue-work-order KPIs, raw tools were no longer enough. A metric needs an agreed definition, a denominator and repeatable calculation steps.

I explored a dedicated Copilot Topic to retrieve the required counts and apply the defined formula. The assistant could still handle natural-language interaction, while the business calculation followed an explicit path.

The architectural lesson

Use generative orchestration to find and connect context. Encode the rules when a business result must be calculated consistently.

The boundary that changed the design
The boundary that changed the design
The article records a technician list without the requested completion-rate result—making the missing calculation capability visible. Source ↗
Evidence & delivery stage

What the work establishes.

Demonstrated in the journalProduction work still to establish
Application authentication, Python data access and four read-only MCP tools.Identity model appropriate to each audience, including delegated access where needed.
MCP Inspector validation, Azure hosting and Copilot integration.Load testing, failure recovery, support ownership and systematic negative-access tests.
Conversational retrieval and a multi-tool assignment question.Repeatable evaluation across realistic operational scenarios and measured business outcomes.
A deterministic Topic approach for defined KPI calculations.Governance and ALM controls implemented and verified across environments.

The governance and ALM chapters develop the next-stage design. This case study does not claim a production rollout, quantified ROI or autonomous transactional execution.

Article-by-article analysis

The decisions behind the build.

Each chapter contributes a different piece of evidence. These notes distinguish the implementation, its design rationale and the work proposed for later stages.

01 · Frame the operational problem

Dispatch context is fragmented across work orders, customers and technicians.

What it establishes: The opportunity is faster access to operational context; customer self-service is a future vision.

Read article ↗
02 · Bound the first release

A read-only plan starts with two work-order capabilities.

What it establishes: The final four-tool implementation grew from this bounded starting point. Performance and adoption figures here are targets.

Read article ↗
03 · Establish an application identity

Entra app registration establishes a separate integration identity.

What it establishes: The build uses application credentials, not per-user delegated access.

Read article ↗
04 · Prove access before adding AI

Postman and Python validate OAuth and Dataverse connectivity.

What it establishes: Successful authentication establishes a foundation; it does not establish complete negative-access testing.

Read article ↗
05 · Design business capabilities

OpenAPI maps business intent to constrained inputs, entities and outputs.

What it establishes: Contracts clarify capabilities; Dataverse permissions remain the authorization boundary.

Read article ↗
06 · Build the MCP server

Python separates authentication, the Dataverse client and the MCP server.

What it establishes: FastMCP, MSAL and httpx support reusable, asynchronous tool execution and token reuse.

Read article ↗
07 · Validate the tool contract

MCP Inspector discovers tools and invokes a bounded work-order query.

What it establishes: Direct testing makes the contract observable before adding a conversational layer.

Read article ↗
08 · Move from local to hosted

A container moves through Azure Container Registry to Azure Container Apps.

What it establishes: A reachable HTTPS endpoint enables Copilot integration; this is not proof of production load readiness.

Read article ↗
09 · Let Copilot compose the tools

Copilot queries live Field Service data and combines work-order and booking lookups.

What it establishes: The multi-tool technician question is the clearest demonstration of agent orchestration.

Read article ↗
10 · Define the governance gap

The series examines shared identity, least privilege, audit, secrets and environment controls.

What it establishes: These are production-readiness considerations; not every proposed safeguard is demonstrated as implemented.

Read article ↗
11 · Coordinate two release lifecycles

Container releases and Power Platform solutions need coordinated promotion.

What it establishes: The article sets out an ALM approach rather than evidencing a fully deployed CI/CD pipeline.

Read article ↗
12 · Reflect on the architecture

Four bounded tools form a composable external integration layer.

What it establishes: The lesson is to pair flexible orchestration with explicit operational boundaries.

Read article ↗
↳ · Side study: generative orchestration

Read-oriented questions can trigger generative tool selection without a predefined topic.

What it establishes: Tool execution is observable; logs do not reveal the model’s private reasoning.

Read article ↗
↳ · Side study: deterministic business rules

Raw retrieval does not reliably produce a defined completion or overdue KPI.

What it establishes: A dedicated Topic supplies agreed counts and calculation rules; the article also explores an Outlook draft action.

Read article ↗
Consulting relevance

Build the right capability.
Prove the useful behavior.

I bring ERP process knowledge into the agent development lifecycle: define a worthwhile operational question, choose the access model, build bounded tools, validate their behavior and plan the controls needed for adoption.

This Field Service exploration shows how I approach that work—from integration foundations to the decision between flexible orchestration and deterministic business logic.