The Model Context Protocol (MCP) standardizes how AI agents discover and invoke tools, access resources, and interact with external systems. An MCP server exposes capabilities -- functions the agent can call, data the agent can read -- through a structured protocol. This is a significant step toward interoperable AI tooling, but it also creates a new attack surface that needs deliberate security architecture.
An MCP server is, at its core, an API that accepts requests from AI agents instead of (or in addition to) humans. The security principles that apply to any API -- authentication, authorization, input validation, rate limiting -- apply here. But the AI agent context introduces nuances that generic API security guidance does not address.
Why MCP Security Is Different
Traditional API security assumes that the client is a piece of software controlled by a developer who understands the API contract. The developer writes code that calls specific endpoints with specific parameters. The behavior is deterministic and reviewable.
An MCP client is an AI agent. The agent decides which tools to call, with what parameters, in what order. These decisions are influenced by the LLM's interpretation of the user's intent, the system prompt, and the context from previous interactions. The behavior is non-deterministic and not fully reviewable before execution.
This has three implications for security:
You cannot trust the request intent. A traditional API client sends requests that a developer intended. An MCP client sends requests that an LLM generated based on probabilistic token prediction. The LLM may misinterpret the user's intent, hallucinate parameters, or be manipulated through prompt injection into making unintended requests.
The authorization context is layered. An MCP request has three actors: the user who initiated the conversation, the AI agent that generated the tool call, and the MCP server that executes it. Authorization must consider all three: Is the user authorized for this operation? Is the agent permitted to invoke this tool in this context? Is the request within the MCP server's security policy?
The request surface is broader. A traditional API has a fixed set of endpoints with defined parameters. An MCP server exposes tools that an agent can invoke in creative combinations. The space of possible request sequences is larger and less predictable than a traditional API.
Authentication Patterns
OAuth 2.0 with scoped tokens. The most robust authentication pattern for MCP servers. The user authenticates through an OAuth flow, receives a scoped access token, and the AI agent includes this token in MCP requests. The token's scopes limit which tools the agent can access on behalf of the user.
Scope design is critical. Define scopes at the tool level: tools:read_data, tools:write_data, tools:execute_actions. The agent should request only the scopes needed for the current task. A conversational query should not receive a token with write permissions.
Token lifetime should be short. MCP sessions typically last minutes to hours, not days. Issue tokens that expire within the session duration. If the session outlives the token, require re-authentication.
API key authentication. Simpler but less secure than OAuth. An API key identifies the client but does not encode authorization scopes or expiration. If you use API keys, implement server-side scope enforcement that maps the key to a set of permitted operations.
API keys for MCP servers should be per-user and per-application. A shared API key across users eliminates the ability to enforce per-user authorization. A shared key across applications eliminates the ability to revoke access for a single application.
mTLS for server-to-server MCP. When the MCP client is a backend service rather than a user-facing agent, mutual TLS provides strong authentication. Both the client and server present certificates, and the server uses the client certificate to determine authorization.
Authorization Architecture
Per-tool authorization. Each MCP tool should have its own authorization check. A user authorized to call list_projects is not necessarily authorized to call delete_project. Implement authorization at the tool level, not at the server level.
Parameter-level authorization. Some tools accept parameters that affect the scope of the operation. A query_data tool with a table parameter should verify that the user is authorized to access the requested table. Parameter-level authorization prevents the agent from expanding the user's access by specifying parameters the user should not have access to.
Context-aware authorization. The authorization decision may depend on the conversation context. A user who has been discussing Project A should be authorized to read Project A's data. A request to read Project B's data in the same session might indicate either a legitimate topic change or a prompt injection attack attempting lateral movement.
Implementing context-aware authorization is complex. Start with stateless, per-request authorization (check user permissions against the requested resource) and add context-based restrictions as your threat model matures.
Rate limiting per user and per tool. Rate limits prevent an agent in a loop from exhausting resources or an attacker from brute-forcing tool calls. Set rate limits at both the user level (total requests per minute) and the tool level (specific tool invocations per session).
Input Validation for MCP Requests
MCP tool parameters arrive as structured data defined by the tool's input schema. Validate every parameter.
Schema validation. MCP tools define their input schema using JSON Schema. Validate incoming parameters against this schema before processing. Reject requests with missing required parameters, unexpected extra parameters, or parameters with wrong types.
Semantic validation. Schema validation ensures structural correctness. Semantic validation ensures the values make sense. A date parameter that is structurally a valid ISO 8601 string but is set to the year 3000 might indicate an error or manipulation. A limit parameter of 999999 is structurally valid but operationally dangerous.
Injection prevention. If tool parameters are used in database queries, API calls, file paths, or command execution, apply standard injection prevention techniques. Use parameterized queries, path canonicalization, and allowlist-based command construction. The LLM-generated parameters should be treated as untrusted user input.
Resource Access Controls
MCP servers expose resources (data the agent can read) in addition to tools (actions the agent can perform). Resources need their own access controls.
URI-based access control. MCP resources are identified by URIs. Implement access control at the URI level. A user authorized to read resource://projects/123 is not necessarily authorized to read resource://projects/456.
Dynamic resource filtering. When an agent lists available resources, the list should be filtered based on the user's authorization. A user should only see resources they can access. Exposing resource URIs that the user cannot access leaks information about the existence of those resources.
Content redaction. If a resource contains fields with different access levels, redact fields the user is not authorized to see rather than blocking access to the entire resource. A project resource might expose the name and description to all users but redact the budget and internal notes for non-administrators.
Monitoring MCP Servers
Request logging. Log every MCP request with: the authenticated user, the tool or resource accessed, the parameters, the response status, and the timestamp. This log is the audit trail that compliance and incident response require.
Anomaly detection. Establish baselines for normal MCP usage patterns: typical tools invoked, typical parameter ranges, typical request rates. Alert on deviations. An agent that suddenly starts querying resources it has never accessed before warrants investigation.
Error rate monitoring. Elevated error rates on an MCP server may indicate that an agent is being manipulated into making invalid requests. A spike in 403 (forbidden) responses suggests the agent is attempting unauthorized access. A spike in 400 (bad request) responses suggests the agent is generating malformed requests, possibly due to prompt injection.
Deployment Considerations
Network isolation. MCP servers that expose sensitive data or powerful tools should not be accessible from the public internet. Deploy them behind an API gateway or in a private network that only authorized agent orchestrators can reach.
Ephemeral servers. For high-security use cases, provision MCP servers per session and tear them down when the session ends. This limits the persistence of any compromise and ensures clean state for each interaction.
Configuration as code. MCP server configurations (tool definitions, authorization rules, rate limits) should be version-controlled and deployed through CI/CD. Manual configuration changes are error-prone and unauditable.
How Safeguard.sh Helps
Safeguard.sh monitors the dependencies that MCP servers are built on -- the frameworks, libraries, and runtime environments that form the MCP server supply chain. As the MCP ecosystem matures and server implementations proliferate, the libraries they depend on become supply chain targets. Safeguard.sh provides vulnerability monitoring and SBOM generation for MCP server projects, ensuring that the infrastructure powering your AI agent integrations is free from known supply chain risks. For teams deploying MCP servers, Safeguard.sh secures the code you build on while you focus on securing what your MCP server exposes.