· AI Agents · 4 min read
Model Context Protocol (MCP) in the Enterprise: Standardising Agent-to-Tool Integration
Bespoke tool connectors create an unsustainable N-by-M integration nightmare. Discover how the Model Context Protocol (MCP) acts as a universal interface for enterprise AI agents, complete with security guardrails.
As enterprises scale from a single experimental AI assistant to dozens of specialised agents across Finance, DevSecOps, and Customer Operations, a familiar architectural bottleneck emerges: the $N \times M$ integration problem.
Every time you introduce a new agent framework or switch between frontier models (such as Claude Opus 5.5 and Gemini 4), engineering teams are forced to rewrite custom glue code for Snowflake, Jira, GitHub, ServiceNow, and internal microservices. Worse still, each bespoke connector handles authentication, pagination, error formatting, and rate-limiting differently.
The Model Context Protocol (MCP) solves this by introducing an open, standardised protocol between AI hosts (clients) and enterprise data sources or tools (servers). Think of MCP as USB-C for Enterprise AI Context.
Why MCP Changes Enterprise Agent Architecture
Before MCP, tool definitions were tightly coupled to the agent’s orchestration code. With MCP, domain teams own and expose a lightweight MCP Server alongside their existing microservice or data platform, publishing three standardised primitives:
- Resources (Read-Only Context): URI-addressable data streams (e.g.,
bigquery://finance/q3_variance_reportorgit://repo/main/schema.sql) that agents can inspect without side effects. - Tools (Executable Actions): Strongly typed functions with JSON Schema contracts (e.g.,
provision_sandbox_namespaceorissue_credit_note) that the model can invoke. - Prompts (Reusable Templates): Curated, version-controlled interaction workflows exposed directly by the domain service.
The 3 Non-Negotiable Rules for Enterprise MCP Servers
Exposing an internal database via an MCP server is not the same as exposing a traditional REST API to a frontend web app. An LLM is a reasoning engine with a finite context window and a susceptibility to prompt injection. Your MCP servers must follow three rules:
1. Context-Safe Pagination and Summarisation
A traditional REST endpoint might return 5,000 rows of JSON. If an MCP tool dumps 5,000 rows into an agent’s context window, it will blow the token budget and degrade reasoning. Enterprise MCP tools must return semantic summaries and pagination cursors, guiding the agent to narrow its filter criteria.
2. Scoped OBO (On-Behalf-Of) Identity Propagation
Never authenticate an MCP server using a single god-mode service account. The MCP client must pass the invoking user’s identity token (via OAuth2/OIDC On-Behalf-Of flows) so downstream systems enforce strict Row-Level Security (RLS) and Role-Based Access Control (RBAC).
3. Human-in-the-Loop (HITL) Approval Gates for Mutating Tools
Read-only tools can execute autonomously. Mutating tools (such as modifying cloud infrastructure or approving a refund above £500) must require cryptographic approval tokens or interrupt the agent execution graph for human sign-off.
Production Pattern: Building a Governed Enterprise MCP Server in Python
Below is an out-of-the-box example of how to build a context-safe, governed MCP tool server in Python using FastMCP with strict input validation, row budgets, and audit logging.
import logging
from typing import Dict, Any, List
from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP
logging.basicConfig(level=logging.INFO)
audit_logger = logging.getLogger("EnterpriseMCPAudit")
# Initialise the Enterprise FinOps MCP Server
mcp = FastMCP("AlpsAgility-FinOps-MCP")
class CostAnomalyQuery(BaseModel):
business_unit: str = Field(..., description="Target business unit code, e.g., 'EMEA-RETAIL'")
min_daily_spend_gbp: float = Field(100.0, ge=0, description="Minimum daily spend threshold in GBP")
max_results: int = Field(10, ge=1, le=25, description="Hard cap to protect agent context window")
@mcp.resource("finops://policies/tag-governance")
def get_tagging_policy() -> str:
"""Exposes the corporate FinOps tagging policy as a read-only MCP Resource."""
return (
"Mandatory Tags: [cost_centre, owner_email, environment, data_classification]. "
"Untagged non-production compute instances older than 48h are flagged for hibernation."
)
@mcp.tool()
def query_cloud_cost_anomalies(query: CostAnomalyQuery, caller_principal: str) -> Dict[str, Any]:
"""
Queries anomalous cloud spend for a specific business unit.
Returns a compact, context-engineered summary rather than raw billing rows.
"""
audit_logger.info(
f"MCP_TOOL_CALL | principal={caller_principal} | unit={query.business_unit}"
)
# Simulated downstream warehouse result
raw_anomalies: List[Dict[str, Any]] = [
{"service": "BigQuery", "project": "analytics-prod", "delta_gbp": 1420.50, "cause": "Unpartitioned scan"},
{"service": "GKE", "project": "ml-training-dev", "delta_gbp": 890.00, "cause": "Idle A100 node pool"},
]
filtered = [
row for row in raw_anomalies if row["delta_gbp"] >= query.min_daily_spend_gbp
][: query.max_results]
return {
"business_unit": query.business_unit,
"returned_count": len(filtered),
"total_anomalous_spend_gbp": sum(r["delta_gbp"] for r in filtered),
"anomalies": filtered,
"next_step_hint": "Call 'propose_remediation_plan' with the target project ID to generate a fix.",
}
if __name__ == "__main__":
mcp.run()Notice the next_step_hint field in the response payload. Including affordance hints in tool responses is a powerful agentic UX pattern: it guides the model toward the correct follow-up tool without bloating the global system prompt.
Why Alps Agility?
At Alps Agility, we combine deep AI expertise with advanced engineering to help you implement autonomous agents that cut costs and improve operational efficiency.
Contact us today to start transforming your enterprise with Agentic AI.
Struggling to move AI from prototype to production? We help enterprises build robust, scalable AI architectures. Book a Generative AI Readiness Assessment.
