SecureMCP: The Production Layer for MCP
Identity, Policy, Audit, and Observability for MCP Servers
The Prototype-to-Production Gap
MCP server development has become remarkably accessible. FastMCP and similar frameworks reduce a working tool server to a few lines of code. FastMCP 3.x ships with OAuth primitives, middleware hooks, and token verification. The protocol is sound, the tooling is maturing, the ecosystem is growing.
Then comes production.
Your MCP server works. Now: who is calling it? Are they permitted? Can you prove what happened? These questions pull teams into custom infrastructure that has nothing to do with the tools they set out to build. Across many enterprise MCP deployments we have reviewed, the same pattern emerges: teams prototype quickly, then spend months on security plumbing. Each team solves the same problems independently. Each solution diverges over time.
This document describes the production gap and how SecureMCP addresses it.
MACAW: Trust Infrastructure for AI
Before diving into MCP specifics, context on MACAW.
MACAW is a trust layer for AI systems—built on the same cryptographic primitives that secure distributed systems, applied to agentic workloads. It provides a control plane for managing identity, policy, and audit across agents, tools, LLMs, and the applications that connect them. The architecture includes a hosted control plane, lightweight endpoint SDKs that run alongside your code, and adapters for common frameworks (OpenAI, Anthropic, LangChain, MCP).
SecureMCP is the MCP adapter. It brings MACAW's trust infrastructure to MCP servers with minimal integration effort.
What MCP Provides (and What It Does Not)
MCP is a transport protocol. It standardizes how tools advertise capabilities and how clients invoke them:
MCP PROTOCOL SCOPE:
──────────────────
What MCP Defines: What MCP Does Not Define:
┌─────────────────────────┐ ┌─────────────────────────┐
│ • Tool schemas │ │ • Caller identity │
│ • Parameter types │ │ • Authorization policy │
│ • Transport (SSE/HTTP) │ │ • Audit trails │
│ • Request/response flow │ │ • Rate limiting │
│ • Error formats │ │ • Multi-tenancy │
│ │ │ • Per-request isolation │
└─────────────────────────┘ └─────────────────────────┘
Protocol Layer Production Layer
This separation is intentional. MCP focuses on protocol; production concerns are left to the deployment environment.
The Real Challenge
The challenge is not that MCP frameworks lack features. FastMCP has OAuth middleware. You can write identity validation. You can add logging. The challenge is what happens at scale:
Ten MCP servers means ten implementations. Each server gets its own OAuth integration, its own audit logging, its own policy logic. Each diverges over time. Each requires maintenance.
No centralized control plane. Want to see which users accessed which tools across all servers? Want to update a policy and have it take effect everywhere? Want consolidated audit logs? You are building a platform, not deploying a server.
Maintenance compounds. OAuth specifications evolve. Your IDP releases updates. Security vulnerabilities emerge. Every server in your fleet needs attention.
Some problems need architectural solutions. Middleware helps, but certain issues—like the shared context problem—require guarantees that per-server code cannot provide.
Identity: The First Problem
In prototype, MCP servers trust localhost. In production, every request must carry verified identity: which user, through which application, with which permissions. Identity must propagate from the user's SSO session through agent reasoning to tool execution.
Today, this means OAuth code in every MCP server. JWT validation. Token refresh. IDP-specific quirks. Depending on your identity provider and requirements, you're looking at 100-400 lines of security plumbing per server—before you write a single line of business logic.
The question is not whether you can write this code. You can. The question is whether you should. Your team has enough on its plate building the tools that matter. Every hour spent on OAuth integration is an hour not spent on the capabilities that differentiate your product.
Now multiply by the number of MCP servers in your fleet. Now maintain when Okta updates their SDK. Now add Azure AD support because a customer requires it.
The Shared Context Problem
Even if you implement identity correctly, a subtler issue lurks.
MCP servers—particularly stdio transport—often run as long-lived processes handling requests from multiple users. For efficiency, organizations deploy shared server instances rather than per-user processes. This creates an identity isolation problem:
THE SHARED CONTEXT PROBLEM:
──────────────────────────
Request 1: Alice Request 2: Bob
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ MCP SERVER PROCESS (shared) │
│ │
│ context.user = "alice" ─────────────────────────────────▶ context.user = "alice" (STALE)
│ │
│ Bob's request executes with Alice's identity │
│ Audit log: "alice called tool X" ← WRONG │
│ Policy check: alice's permissions ← WRONG │
└─────────────────────────────────────────────────────────────┘
Alice sends a request; context variables retain her identity. Bob sends the next request through the same process. If the server does not explicitly reset identity context, Bob's request executes with Alice's credentials.
We see many teams optimize for connection efficiency without considering per-request identity boundaries. This is a known failure mode in shared-process architectures—not unique to MCP, but MCP's deployment patterns make it common. Middleware can help, but the guarantee must be architectural. It cannot depend on every server author remembering to reset context correctly.
Trust as Infrastructure
SecureMCP addresses these challenges by moving identity, policy, and audit out of application code and into infrastructure.
┌─────────────────────────────────────────────────────────────────────────────┐
│ IDENTITY PROVIDERS │
│ Okta │ Azure AD │ Keycloak │ Auth0 │
└────────────────────────────────┬────────────────────────────────────────────┘
│ OAuth 2.0 / OIDC
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ MACAW TRUST LAYER │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Identity │ │ Policy │ │ Audit │ │Observability│ │
│ │ Bridge │ │ Enforcer │ │ Logger │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │Per-invocation│ │ Centralized │ │ Signed & │ │ Metrics & │ │
│ │ isolation │ │ hierarchical│ │tamper-proof │ │ tracing │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└────────────────────────────┬───────────────────┬────────────────────────────┘
│ │
┌──────────────┴───────┐ ┌───────┴──────────────┐
▼ ▼ ▼ ▼
┌──────────────────────────┐ ┌──────────────────────────────────────────────┐
│ YOUR MCP SERVERS │ │ THIRD-PARTY MCP SERVERS │
│ (SecureMCP) │ │ (SecureMCPProxy) │
│ │ │ │
│ Business logic only │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ No security code │ │ │Snowflake │ │Databricks│ │Salesforce│ │
│ │ │ └──────────┘ └──────────┘ └──────────┘ │
└──────────────────────────┘ └──────────────────────────────────────────────┘
The Identity Bridge abstracts IDP-specific protocols. Switching from Okta to Azure AD is a configuration change in the control plane—your MCP servers do not change.
Per-invocation isolation is guaranteed by the runtime. Every tool call creates a fresh security context bound to a cryptographic session—identity from request N cannot leak into request N+1, regardless of transport or process model. This is an architectural guarantee, not a coding convention.
SecureMCP: Drop-In Integration
SecureMCP is a thin wrapper that brings MACAW's trust layer to MCP. It follows FastMCP patterns and extends them with multi-tenancy, session management, and per-invocation isolation.
For servers you control, integration is one import change:
# Before: FastMCP
from fastmcp import FastMCP
mcp = FastMCP("calculator")
@mcp.tool()
def add(a: float, b: float) -> float:
return a + b
# After: SecureMCP
from securemcp import Server
server = Server(name="calculator")
@server.tool("add")
def add(a: float, b: float) -> float:
return a + b
Tool implementation is identical. The wrapper handles identity, policy, and audit. Your business logic remains yours—no lock-in, no framework coupling beyond the decorator.
For third-party servers you cannot modify, SecureMCPProxy acts as an inline gateway:
from macaw_adapters.mcp import SecureMCPProxy
# HTTP transport
proxy = SecureMCPProxy(
app_name="snowflake-mcp",
upstream_url="https://mcp.snowflake.internal"
)
# stdio transport
proxy = SecureMCPProxy(
app_name="salesforce-dx",
command=["npx", "@salesforce/mcp"]
)
Connect to the upstream, discover its tools, re-expose them through the trust layer. Upstream code is untouched.
Both paths deliver the same properties: verified identity per invocation, centralized policy, cryptographic audit.
Identity from the Runtime
With SecureMCP, servers contain no IDP-specific code. Identity flows from the MACAW runtime:
- Users authenticate through your existing SSO. The runtime handles token exchange.
- Servers receive verified identity on every invocation. No OAuth code required.
- Switching IDPs is a control plane operation. Servers do not change.
The shared context problem is solved at infrastructure. Every invocation gets fresh, isolated context. Your server code does not manage this—the runtime guarantees it.
Beyond Identity
Because MACAW operates at the trust layer, additional capabilities come as infrastructure:
Audit trails are built in. Every invocation is logged with verified identity, parameters, timestamp, and outcome. Logs are cryptographically signed. There is no audit code to write.
Policy enforcement layers in when ready. Centralized policies govern which identities can call which tools with what parameters. Policies update without server restarts. This is optional—start with identity, add policy when requirements demand it.
Observability aggregates across servers. Request rates, latency, errors, policy denials—visible across your entire MCP fleet through the control plane.
Summary
MCP frameworks give you protocol. Production requires identity, policy, audit, and isolation. You can build these per-server—but ten servers means ten implementations, ten maintenance burdens, ten opportunities for divergence.
SecureMCP provides these capabilities as infrastructure. One import change for servers you control. A proxy for servers you cannot modify. Identity from the runtime. Audit built in. Policy when you need it.
Your servers contain tools. The trust layer handles the rest.
If we can help with your MCP deployment, reach out: securemcp@macawsecurity.com
Resources
- SecureMCP: github.com/macawsecurity/secureAI
- Documentation: macawsecurity.ai/docs
- Console: macawsecurity.ai
SecureMCP: The Production Layer for MCP