Book an AI Check arrow_forward

Workflow architecture for mid-sized companies: MCP server, Python and Azure

How AI assistants such as Microsoft Copilot or Claude work safely with ERP, CRM and document storage: a layered reference architecture, with an MCP server in Python, business logic on Azure, sign-in via Entra ID and an operation you can verify. With a code example and the Azure services for each task.

Book an AI Check arrow_forward Go to the reference architecture
Overview of all MCP topics The complete MCP server guide brings together architecture, tools, security and GDPR — the pillar page for this cluster.
Go to the MCP server guide arrow_forward

What is a workflow architecture with an MCP server, Python and Azure?

A workflow architecture with an MCP server, Python and Azure connects AI assistants to your business systems through a self-written, reviewed server, instead of letting the AI loose directly on ERP, CRM or document storage. The AI assistant asks, the MCP server decides on the basis of fixed tools what is allowed, and the business logic in Python fetches the data through the systems' interfaces. Azure supplies the runtime, sign-in, key management, network and audit log.

This is interesting for mid-sized companies because many businesses already work with Microsoft 365 and Entra ID. The sign-in your team uses every day then also becomes the sign-in to the AI tool. And because the rules are in code, they can be tested, versioned and reviewed by a second person. What MCP is in principle is explained in the guide What is an MCP server?.

What layers does the reference architecture consist of?

The reference architecture has four layers: AI client, MCP server, business logic and connected systems, embedded in identity, key management, network and audit log. Each layer has exactly one task, so that errors and permissions can be clearly assigned.

LayerTaskTypical technologyWho is responsible
1. AI clientReceive the question, choose the right tool, formulate the answerMicrosoft Copilot Studio, Claude, other MCP-capable assistantsIT, approval of connectors
2. MCP serverCheck sign-in, offer fixed tools, validate inputs, log every callPython with the official MCP SDK, Streamable HTTP transportDevelopment, code review
3. Business logicFetch data, filter, merge, apply rulesPython modules, run in Azure Functions or Azure Container AppsDevelopment with the business department
4. SystemsDeliver data, execute transactionsERP, CRM, DMS via their documented APIsSystem owners
Cross-cuttingIdentity, secrets, network, audit log, costsEntra ID, Key Vault, VNet and Private Endpoints, Application Insights, Cost ManagementIT operations

Layer 1: the AI client

Microsoft Copilot Studio can integrate custom MCP servers as tools. The connection uses Streamable HTTP, and OAuth 2.0 or an API key can be chosen for sign-in (Microsoft Learn). Claude and other assistants also connect via a server address. Because the server follows the MCP standard, it stays the same when you switch assistants.

Layer 2: the MCP server in Python

We write the server with the official MCP SDK for Python. According to the project page, the SDK supports the standard transports stdio, Streamable HTTP and SSE; for operation on the network we use Streamable HTTP. The server knows only the tools that are in the code, with types and validation rules for every input.

Layer 3: business logic and workers

This is where what makes the company what it is sits: which fields a quote has, how customer numbers are structured, which totals are calculated. For the runtime, Azure offers two obvious routes, both documented by Microsoft for MCP servers:

Long-running or scheduled processes, such as a nightly reconciliation, run as separate workers alongside the MCP server and not in the tool call itself.

Layer 4: the systems

ERP, CRM and document storage are connected through their documented interfaces, not through direct database access. This keeps the systems' permission checks and business logic intact. Some vendors have their own rules for AI access; SAP, for example, has regulated it in its API Policy since April 2026 (see MCP server for SAP). For Microsoft 365 as the system behind it, there is a separate guide: MCP server for Microsoft 365.

Which Azure services take on which task?

For every cross-cutting task there is a documented Azure service, so that only tools and business logic remain in your own code. The table shows what Microsoft describes for each service.

TaskAzure serviceWhat Microsoft documentsSource
Running the MCP serverAzure Container AppsOwn container with HTTPS ingress, scaling, optional Entra ID sign-inLearn
Running the MCP server serverlessAzure Functions (Flex Consumption)SDK servers as custom handlers, preview, stateless only with Streamable HTTPLearn
User sign-inMicrosoft Entra IDThe app platform's built-in sign-in implements the MCP authorization specification and redirects to Entra IDLearn
Server sign-in to Azure servicesManaged identitiesTokens from Entra ID without stored credentials, permissions via RBACLearn
API keys and credentialsAzure Key VaultCentral store for tokens, passwords, API keys, access via Entra ID and Azure RBAC, access log to Azure MonitorLearn
Audit log and monitoringApplication Insights, Log AnalyticsTraces, metrics and logs via the Microsoft OpenTelemetry Distro for PythonLearn
Private networkVNet, Private EndpointsContainer Apps environment without a public endpoint, Key Vault via Private Endpoint, VNet integration for Flex ConsumptionLearn, Learn
Central gateway (optional)Azure API ManagementManage MCP servers with rate limiting, JWT validation, IP filtering and monitoring, currently tools only, no resources and promptsLearn
Keeping an eye on costsCost Management budgetsAlerts on actual or forecast costs; resources are not stopped in the processLearn

As of 28 October 2026, each read on Microsoft Learn.

Region: We plan in the Azure region Germany West Central (Frankfurt). Not every service and variant is available in every region; the Flex Consumption plan, for example, currently does not support all regions according to Microsoft. That is why we check availability per service before building. The region of the MCP server also says nothing about where the AI assistant computes. If a US provider is in the path, we cannot assure that data never leaves Europe.

Why code rather than low-code for this architecture?

For the layer between AI and business systems, one thing above all speaks for code: security boundaries can be written down there in a verifiable way, instead of being spread across click-through interfaces. Specifically:

The drawbacks belong here too. Code has to be maintained: dependencies get security updates, the MCP SDK keeps evolving, vendors' interfaces change. Whoever runs the code needs Python skills in-house or a service provider with a maintenance contract. And for a small change, a commit with review is more effort than a click in an interface.

When is a low-code tool enough? If a process works without AI, that is, has fixed triggers and fixed steps, touches few systems and moves no sensitive data, a low-code or integration tool is often the faster route. This applies to notifications, simple data transfers or forms, for example. As soon as a language model selects tools itself and accesses HR, customer or financial data, we recommend keeping the limits in code.

What does an MCP tool look like in Python?

An MCP tool in Python is a typed function with a description that the official SDK offers as a tool. The following example reads the status of a customer order, read-only and with validation of the order number. We tested it on 28 October 2026 with the package mcp in version 2.3.0. In version 2 the server class is called MCPServer; in version 1 it was called FastMCP (migration guide).

import os
from typing import Annotated

import httpx
from pydantic import BaseModel, Field

from mcp.server import MCPServer
from mcp.types import ToolAnnotations

mcp = MCPServer("auftragsstatus")


class Auftragsstatus(BaseModel):
    gefunden: bool
    status: str | None = None
    liefertermin: str | None = None
    offene_positionen: int | None = None


ERP_URL = os.environ.get("ERP_API_URL", "https://erp.example.internal/api")


@mcp.tool(annotations=ToolAnnotations(read_only_hint=True))
async def auftragsstatus(
    auftragsnummer: Annotated[str, Field(pattern=r"^A-\d{6}$", description="Auftragsnummer, z. B. A-104233")],
) -> Auftragsstatus:
    """Liefert Status, Liefertermin und offene Positionen eines Kundenauftrags."""
    async with httpx.AsyncClient(timeout=10) as client:
        antwort = await client.get(
            f"{ERP_URL}/auftraege/{auftragsnummer}",
            headers={"Authorization": f"Bearer {os.environ['ERP_API_TOKEN']}"},
        )
    if antwort.status_code == 404:
        return Auftragsstatus(gefunden=False)
    if antwort.status_code != 200:
        # Keine Fremd-Fehlertexte an das Modell durchreichen
        raise RuntimeError("Abfrage im ERP fehlgeschlagen")
    daten = antwort.json()
    # Nur die Felder, die der Anwendungsfall braucht
    return Auftragsstatus(
        gefunden=True,
        status=daten["status"],
        liefertermin=daten["liefertermin"],
        offene_positionen=daten["offene_positionen"],
    )


if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8000, stateless_http=True)

What the example shows:

What the example deliberately leaves out belongs in a production server: user sign-in via Entra ID, fetching the ERP token from Key Vault instead of an environment variable, logging of every call and rate limiting. How we implement this for clients is described in the guide Having an MCP server developed.

Where are the security boundaries in this architecture?

The security boundaries lie in the sign-in before the MCP server, in the tool design of the server and in the network behind it, each in such a way that one layer catches the mistakes of the others.

The privacy side, with data processing, processing location and deletion concept, is described in the guide MCP server, security and GDPR.

How do you operate the architecture: CI/CD, tests, monitoring, costs?

The architecture is operated like any other enterprise software: with automated delivery, tests before every release, monitoring in live operation and budget alerts.

CI/CD

The code lives in a Git repository, and every change goes through a pull request with review. After the merge, a pipeline builds the container image and delivers it. For Container Apps, Microsoft describes this with GitHub Actions: every push to the defined branch triggers the workflow, and Container Apps creates a new revision from it (Microsoft Learn). Because every delivery is its own revision and Container Apps can split traffic between revisions, a new version can first be tested with a share of the requests.

Tests

Monitoring

The server sends traces, metrics and logs via the Microsoft OpenTelemetry Distro to Application Insights. These feed alerts for error rates, runtimes and unusually many calls to a tool. The content of responses does not belong in the log, only metadata of the call.

Cost control

Costs arise on three levels: Azure resources, the language model of the AI client and, where applicable, quotas of the connected systems. For Azure we set budgets with warning thresholds in Cost Management. Important to know: a budget warns, it does not stop resources. On top of that come technical brakes in the code, namely rate limiting, result caps and caching for expensive queries. We discuss concrete orders of magnitude in the AI Check, depending on the number of users, systems and use cases.

How do you get started with this architecture?

Start with a read-only use case on one system and build identity, audit log and pipeline properly from the outset, because these parts later carry all further tools.

  1. Choose a use case: a frequent, clearly answerable question, for example order status or open items.
  2. Check the interface: Is there a documented API, what permissions does it need, are there vendor rules for AI access?
  3. Set up the foundation: repository, pipeline, Entra ID app, Key Vault, Application Insights, network.
  4. Build and test the tool: with negative tests and a list of test questions.
  5. Pilot with a small group: Check answers against the system, analyse audit logs.
  6. Extend: more tools, more systems, later write actions with approval.

We set the timeline after the AI Check.

Related guides: What is an MCP server? · Having an MCP server developed · Security and GDPR · MCP server for Microsoft 365 · Time tracking and project management

Frequently asked questions

Why Python for the MCP server?

Python is widely used for data processing and interfaces in mid-sized companies, and there is an official MCP SDK for it. The SDK derives input schemas directly from type annotations, so validation rules are visible in the code.

Do I need Azure for an MCP server?

No. An MCP server runs wherever Python runs. Azure is a good fit if you already use Microsoft 365 and Entra ID, because sign-in, key management and audit log then come from a single source.

Azure Functions or Azure Container Apps?

Container Apps is the general route for an MCP server as a container. Azure Functions can also host SDK-based servers, according to Microsoft currently as a preview, stateless only with Streamable HTTP and on the Flex Consumption plan. We decide this per project based on network requirements and load profile.

Can Microsoft Copilot use the MCP server?

Yes. Copilot Studio integrates MCP servers via Streamable HTTP, and sign-in runs via OAuth 2.0 or an API key. Whether a connector may be used is regulated by your IT through the data policies of the Power Platform.

Does the data stay in Germany?

The MCP server and the business logic can run in the Azure region Germany West Central (Frankfurt). Where the AI assistant's language model computes depends on the provider and contract. If a US provider is in the path, we cannot assure that data never leaves Europe.

Isn't a low-code tool enough?

For fixed processes without an AI decision, often yes. For the layer in which a language model selects tools and accesses sensitive data, we rely on code, because limits can be tested, versioned and reviewed there.

Who maintains the code after the project?

Either your IT, if Python skills are in-house, or we do, under a support agreement. We settle this before the project starts, because dependencies, SDK and interfaces need regular updates.

Does the architecture fit your IT?

Tell us briefly which systems the AI assistant should reach. You get a written feasibility assessment, with no appointment and no sales call.

Thank you, your enquiry has arrived.

You will receive a written assessment by email within one working day.

check_circle Free
check_circle Written reply
check_circle No call needed

Prefer to talk directly? Book a 30-minute AI Check