Model Context Protocol (MCP) is the architectural standard that replaces dangerous, unconstrained Text-to-SQL with secure, typed, and auditable tool contracts between AI agents and enterprise systems of record. By abstracting ERP databases behind structured JSON-RPC interfaces, enterprises can grant autonomous agents real-time operational context without exposing raw schema or bypassing transaction validation rules.

1. Beyond Text-to-SQL: Why Enterprises Need MCP

In 2024 and 2025, early enterprise AI implementations attempted to connect Large Language Models (LLMs) to ERP databases via dynamic SQL generation ("Text-to-SQL"). The failure modes became immediately catastrophic:

  • Schema Hallucinations & Cartesian Explosions: Enterprise ERP schemas carry immense complexity—Microsoft Dynamics 365 F&O spans over 11,000 tables with hundreds of relational junction entities. Unconstrained models routinely join unindexed historical tables, locking production database engines with runaway table scans.
  • Bypassing Financial Logic: In accounting systems, you cannot simply execute an UPDATE or INSERT on a ledger table. A general ledger posting requires balanced debits and credits, active financial dimension sets, and currency revaluation rules. Raw SQL writes destroy ledger integrity.
  • Security & Exfiltration: Prompt injection attacks easily manipulate Text-to-SQL generators into appending UNION SELECT statements, leaking executive salaries, credit card tokens, and proprietary margin data.

The open-source Model Context Protocol (MCP) solves this by standardizing an explicit, typed client-server architecture. Instead of guessing raw database queries, the AI agent is presented with a discrete catalog of governed tools and resources with strictly validated parameter schemas.

2. The Three MCP Primitives: Resources, Tools & Prompts

An MCP server exposes three foundational primitives to any connected LLM agent (whether running in Claude, ChatGPT, Copilot Studio, or custom LangGraph/AutoGen loops):

MCP PrimitiveERP Functional RoleExecution CharacteristicsEnterprise Security Posture
ResourcesContextual, read-only operational telemetry (e.g., erp://inventory/item/SKU-9921/availability).Read-only; deterministic; cacheable; zero side effects.Protected by Role-Based Access Control (RBAC); sensitive PII redacted at the transport layer.
ToolsExecutable business logic and workflows (e.g., create_purchase_order, place_credit_hold).Stateful mutations with side effects; requires JSON Schema parameter validation.Gated by policy evaluation; mutations require human cryptographic sign-off.
PromptsPre-engineered, parameterized task templates (e.g., triage_ap_variance, audit_inventory_shrinkage).Standardizes enterprise interaction guidelines and output structures.Version-controlled in Git; immune to runtime user prompt drift.

3. Building a Governed MCP Server for Dynamics 365

In a modern enterprise architecture, the MCP server is deployed as a secure containerized microservice running in Azure Container Apps or AWS ECS. It communicates with the AI agent client via Server-Sent Events (SSE) over HTTPS and authenticates with Dynamics 365 Dataverse via Azure Entra ID service principals.

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';

const server = new Server(
    { name: 'datadaur-dynamics365-gateway', version: '2.0.0' },
    { capabilities: { tools: {}, resources: {} } }
);

// 1. Expose typed, governed tool definitions
server.setRequestHandler(ListToolsRequestSchema, async () => ({
    tools: [
        {
            name: 'get_inventory_balance',
            description: 'Queries real-time on-hand stock balance and reserved quantities for a specific item across warehouse locations.',
            inputSchema: {
                type: 'object',
                properties: {
                    itemNumber: { type: 'string', description: 'The exact ERP Item Number (e.g., SKU-10492)' },
                    siteId: { type: 'string', description: 'The operational site or distribution center code' }
                },
                required: ['itemNumber']
            }
        },
        {
            name: 'request_credit_hold_release',
            description: 'Submits a formal request to release a sales order blocked by customer credit limit exceedance.',
            inputSchema: {
                type: 'object',
                properties: {
                    salesOrderNumber: { type: 'string', description: 'The Sales Order ID' },
                    justification: { type: 'string', description: 'Business rationale for temporary credit extension' }
                },
                required: ['salesOrderNumber', 'justification']
            }
        }
    ]
}));

// 2. Execute business operations via Dataverse Web API with strict validation
server.setRequestHandler(CallToolRequestSchema, async (request) => {
    const { name, arguments: args } = request.params;
    
    if (name === 'get_inventory_balance') {
        const itemNumber = String(args?.itemNumber);
        // Call Dataverse Web API with bound parameters (no SQL string concatenation)
        const response = await fetch(`https://org.crm.dynamics.com/api/data/v9.2/products?$filter=productnumber eq '${encodeURIComponent(itemNumber)}'`, {
            headers: { Authorization: `Bearer ${await getEntraToken()}` }
        });
        const data = await response.json();
        return {
            content: [{ type: 'text', text: JSON.stringify(data.value) }]
        };
    }
    
    throw new Error(`Unsupported tool: ${name}`);
});

4. Security Architecture: RBAC & Field-Level Masking

An enterprise MCP server must not act as a god-mode credential holder. If an employee chatting with a Copilot or internal agent does not have permission to view payroll records in Dynamics 365, the agent must be denied access to that data at the MCP gateway level.

Implement three defensive security tiers:

  • On-Behalf-Of (OBO) Token Exchange: Never use a static super-admin connection string. Exchange the user's Entra ID JWT for an OBO token scoped to Dataverse, ensuring existing Dynamics 365 security roles, business units, and field-level security profiles apply automatically.
  • Dynamic Response Masking: For sensitive financial data (e.g., vendor bank account numbers, tax identifiers, executive salaries), the MCP server intercepts the JSON response and masks non-essential characters before passing the payload back to the LLM context window.
  • Payload Size Guardrails: Large Language Models suffer from context window degradation when fed megabytes of raw JSON. The MCP server must enforce strict pagination (default 20 records per response) and project only relevant fields, stripping internal database metadata.

5. Fail-Closed Action Gateways for Financial Mutations

The most dangerous misconception in agentic AI is allowing an autonomous agent to execute irreversible financial mutations without human approval. An agent hallucinating a vendor bank account change or misinterpreting a bulk discount schedule can drain working capital within seconds.

In high-reliability enterprise architecture, read operations (Resources) are autonomous, while write operations (Tools) are routed through a fail-closed action gateway:

  1. Intent Proposal: The agent synthesizes an intent payload (e.g., "Post vendor invoice #9921 for $42,500 against PO #4410").
  2. Cryptographic Interception: The action gateway (such as DataDaur's proprietary Issa framework) freezes the transaction, generates a SHA-256 state hash, and dispatches a verified approval card to the authorized controller.
  3. Secure Channel Verification: Outbound notifications and multi-factor approval links are dispatched through scoped, authorized gateways like SadaSend, preventing prompt-injected agents from sending exfiltrated data to arbitrary endpoints.
  4. Idempotent Execution: Only upon receiving a signed cryptographic confirmation does the MCP server unlock the write tool and commit the ledger entry. If the human rejects or ignores the request within the SLA window, the transaction fails closed.

6. Production Deployment & Observability Checklist

Before exposing production systems of record to autonomous agent loops, verify the following architectural controls:

  • Transport Security: Expose MCP servers exclusively over TLS 1.3 with mutual authentication (mTLS) or OAuth 2.0 bearer validation. Disallow unauthenticated local sockets in shared compute environments.
  • Structured Audit Logging: Record every tool invocation, input payload, user identity, latency, and response code in an immutable SIEM log (Azure Sentinel or AWS CloudWatch).
  • Rate Limiting & Circuit Breakers: Prevent runaway agent loops by capping maximum tool calls per user session (e.g., no more than 15 tool executions per minute per user).
  • Strict Type Validation: Reject any tool request whose arguments do not conform 100% to the published JSON Schema. Never allow dynamic or loose parameter casting inside tool execution code.