Key Architectural Principles
- 01.Model Context Protocol (MCP) replaces fragile bespoke plugins with standard JSON-RPC contracts.
- 02.Strict JSON Schema boundary definitions eliminate LLM parameter hallucination before execution.
- 03.Enforce tenant isolation and zero-trust permission tokens prior to agent tool execution.
- 04.Instrument OpenTelemetry activity spans on every agent action for complete enterprise auditability.
In modern AI development, the biggest architectural hurdle is not model capability—it is context boundary management. When integrating LLMs with enterprise systems, bespoke tool plugins quickly become an unmaintainable maze of security holes and brittle parsers.
The Model Context Protocol (MCP) introduces a standardized, JSON-RPC-based protocol that separates the model client from enterprise tool providers. In this article, we examine how to build a robust .NET MCP server that exposes database schemas, telemetry, and business APIs safely.
By adhering to strict schema contracts and decoupling runtime infrastructure from prompt templates, software architects can treat AI agents like microservices: bounded, observable, and testable.
1. The Contract Isolation Boundary
Without formal contracts, LLMs frequently invent tool arguments or provide ambiguous parameters that cause runtime exceptions. MCP enforces strict JSON Schema definitions for every exposed capability.
In .NET, we leverage C# attributes and source generators to translate strong types directly into MCP JSON schemas, ensuring that the model receives exact constraints for enums, required fields, and value bounds.
2. Security & Zero-Trust Tenant Scoping
Enterprise agents cannot run with unrestricted credentials. Every MCP call in our architecture propagates caller claims, tenant identifiers, and scoped OAuth tokens down to the tool handler.
Before executing any file, database, or API action, the tool handler validates authorization scopes against the active security context, preventing lateral privilege escalation by compromised model prompts.
3. Enterprise Observability with OpenTelemetry
Autonomous agent loops can easily get stuck in expensive retry cascades. By injecting System.Diagnostics.Activity tracing into each MCP invocation, teams obtain full visibility into tool latencies, tokens consumed, and error rates in Jaeger or Azure Application Insights.
// .NET 8 MCP Server Tool Registration with OpenTelemetry Tracing
public class DatabaseQueryTool : IMcpToolHandler
{
private readonly ISqlExecutor _sqlExecutor;
private readonly ActivitySource _telemetry = new("Enterprise.Agents.Mcp");
[McpTool("query_readonly_metrics", "Executes parameterized read-only analytical queries")]
public async Task<McpToolResult> ExecuteAsync(
[McpParameter("Read-only SQL query string", Required = true)] string query,
[McpParameter("Query timeout in seconds")] int timeoutSeconds = 15,
CancellationToken cancellationToken = default)
{
using var activity = _telemetry.StartActivity("McpTool.ExecuteQuery");
activity?.SetTag("mcp.tool.name", "query_readonly_metrics");
// 1. Enforce safety validation boundary
if (ContainsMutationKeywords(query))
{
activity?.SetStatus(ActivityStatusCode.Error, "Mutation attempt blocked");
return McpToolResult.Failed("Write queries are strictly prohibited on this tool endpoint.");
}
// 2. Execute under tenant context with bounded timeout
var result = await _sqlExecutor.ExecuteReadOnlyAsync(query, TimeSpan.FromSeconds(timeoutSeconds), cancellationToken);
return McpToolResult.Success(result);
}
}