Learn how Material built a secure, open Model Context Protocol (MCP) server to connect AI agents directly with enterprise email security detection and remediation capabilities.
Material is a powerful security platform, and we’re making it more powerful by bringing it to the tools security teams already use. Until recently, working with Material meant clicking through the UI or writing scripts against our beta API.
That's fine for some workflows, but many of our customers are building something bigger. They're plugging Material's detection and remediation capabilities into a larger security stack of SIEMs, SOARs, and UBAs, and they need better API access to do it well.
At the same time, AI is changing how security teams operate. Customers are experimenting with agents, building custom workflows, and trying things no one anticipated several years ago. Not every experiment will work out, but this is exactly the kind of innovation that we want to support. To meet customers where they are, we need to plug directly into the tools they're building with. Today, the most seamless way to do that is MCP—the Model Context Protocol, an open standard that lets AI agents connect to external tools and data sources over a single interface.
How We Built It
We shipped new API v1 endpoints right before launching our MCP server, which made it straightforward to build MCP directly on top of them. MCP tools parameters are auto-generated from the API endpoint specs, so there's guaranteed parity between the two interfaces for any tools we add to the MCP. Anything an agent can do via MCP can also be done through the REST API.
We chose to implement our own JSON-RPC server rather than using a standard MCP SDK. Our existing auth middleware, permission model, and rate limiting infrastructure already handled the hard problems, like token validation, per-tool access control, audit logging, and we wanted MCP requests to flow through the same stack. Building on top of what we had meant the security model came for free instead of being bolted on after the fact.
Adding a new MCP tool is now a small amount of wiring: point it at an API endpoint, add a natural language description, and the schema, permissions, and audit logging carry over automatically.
But a good schema isn't enough. While the API spec tells an agent what parameters exist, agents need more than that to use tools well. We had to add and iterate on tool descriptions—natural language explanations that tell agents when and why to use a tool. Improving these descriptions had an outsized impact on whether agents could discover and select the right tool for a given task.
For example, our get_issue description includes "use this to review a specific issue before deciding whether to change its verdict." That's not something the input schema can express; it's teaching the agent a workflow. Without it, an agent asked to resolve an issue often skips straight to updating it. With the hint, it reads the issue first.
We also ran into some surprises along the way. Agents will confidently claim to have sorted a list of results without actually doing it, so we had to add server-side sort parameters to make sure the ordering is correct before agents ever see the data. One popular LLM coding tool rejects dotted parameter names (e.g., filter.status), something we only discovered through testing, not documentation.
What It Does Today
Material's MCP server exposes four tools: list_issues, get_issue, patch_issue, and get_message. Together, they let AI agents query, triage, and update email security issues programmatically.
Setup is straightforward. Admins opt in via a "MCP Server" toggle in settings, then copy a one-click connection snippet for their favorite AI agent directly from the Material UI.
Once connected, you can ask an agent in natural language:
"Show me all open critical-severity issues from today."
The agent calls list_issues with the filters and returns a summary. From there, you can stay in the conversation:
"That first one looks like a false positive. Mark it as ignored."
The agent calls patch_issue to update the issue status and classification. No tab-switching, no clicking through the UI. The same workflow that would take a dozen clicks happens in two sentences.
Where this gets more interesting is when you combine it with other context the agent already has. If you're investigating an incident and your agent is connected to both Material and your SIEM, you can ask it to correlate what Material detected with what your SIEM logged, and triage directly from the same conversation.
Security
MCP gives AI agents the ability to read and modify security data, so the access controls around it have to be tight. We designed the system with defense in depth: multiple independent gates that all have to pass before a tool call goes through.
Authentication
We initially shipped MCP using API token auth to ship fast: requests authenticate using the same API tokens that power our REST API. Under the hood, it resolves to a specific user, which means every MCP action is attributable to the person whose token was used, and subject to their role and permissions.
We’ve rolled out OAuth integration setup flow in v1.60. The consent flow reuses your existing Material login (SAML, Google, or Microsoft), so there's no new identity layer to manage. Connecting Material to an agent works seamlessly: click authorize, approve the scopes, and you're connected. Plus, OAuth is just a better security model than having long-lived API tokens running around.
We make authenticating with OAuth easy to do by offering easy to follow instructions for the most popular AI agent harnesses that customers are using, including Cursor, Claude, ChatGPT, Codex, Grok, and more.
Enablement Gates
Before any tool call is evaluated, the request has to pass independent checks:
- An admin has toggled the MCP on in Material’s settings. This defaults to off; customers explicitly opt in.
- If a user has access to multiple tenants, MCP is only available if every one of those tenants has enabled it. This is a deliberate tradeoff: we'd rather block access entirely than risk an agent inadvertently operating across a mix of opted-in and opted-out tenants.
Tool-Level Permissions
Connecting to the MCP server doesn't grant access to every tool. Each tool inherits the same permissions as the underlying API endpoint it wraps. A user who can read issues but not update them will see list_issues and get_issue in their tool list, but not patch_issue. Similarly, message content access is gated by the same read permissions that govern what a user can see in the UI.
When an agent calls tools/list to discover what's available, the server filters the response to only show tools the authenticated user is permitted to use. And permissions are re-checked at execution time, so a stale tool list can't be used to bypass access controls.
Rate Limiting
MCP requests are rate-limited per tenant, enforced via Redis. This is a fail-fast limit. If a runaway agent starts hammering the server, it gets a clear error rather than silently queuing up work.
Audit Trail
Every tool call, whether it succeeds or fails, is written to the audit log. The log records which tool was called, what filters or parameters were used, who made the call, and whether it resulted in an error. For write operations like patch_issue, the specific changes (status, classification, remediation actions) are logged, but free-text fields and message content are deliberately excluded. These audit events appear as API activity in Material's audit log, so admins can review MCP usage alongside other API and UI actions.
What's Next
The most common request we hear is broader coverage. Customers want to search messages directly (not just messages tied to issues), search files, and work with detections through the MCP server. We're working on expanding the tool set based on what customers are actually trying to build and taking our time to ensure all new integrations are high quality with well-defined access controls. Some things coming soon to our API and MCP include the ability to interact with accounts and groups, and also full access to our new OAuth App content.

