How to Secure Your MCP Server: A Practical Checklist
Source: Dev.to
Introduction
Based on scanning 535 MCP servers and observing 54 real attack attempts against my own server, here’s a practical checklist of the most important security measures.
Authentication
- 37 % of MCP servers have no authentication. If the server is exposed to the internet, assume it is being probed by both legitimate and malicious AI agents.
- The most common cause is a dev server that was never hardened before being left running.
Options for securing access
| Method | How to use | Typical use‑case |
|---|---|---|
| Bearer token | Add Authorization: Bearer header to every request and verify it server‑side. | Minimum viable authentication. |
| API key | Send X-API-Key: header. | Simple token‑based auth, easy to rotate. |
| OAuth 2.0 | Implement the full OAuth flow. | Production deployments serving multiple clients; adds complexity but provides robust security. |
What I see in the wild
- 37 %: no auth
- 45 %: API‑layer auth (fastest to implement)
- 18 %: MCP‑layer auth
If you use a hosted MCP service (e.g., Claude.ai, Cursor), authentication is handled for you. The same considerations apply to self‑hosted deployments.
Credential Management
Every credential that appears in the LLM’s context is a potential exfiltration target.
- Never pass API keys to the LLM “for convenience.” Store them in environment variables and access them only at execution time.
- Avoid including file paths, usernames, internal server addresses, or any secret data in system prompts.
- Principle of least privilege: Only expose the information the model truly needs.
Permission Checks for Tools
Not every tool should be callable by every client.
- Example: If your MCP server offers a
send_emailtool, add a permission check that verifies the client hassend_emailrights. A read‑only client must not be able to trigger write operations. - Attackers often probe for admin tools (
“what tools do you have?”) and then try to call them with elevated privileges. Proper permission checks stop this attack vector.
Rate Limiting
AI agents can hammer your server. Without limits, a misconfigured agent can cause a denial‑of‑service or exhaust your API quota.
- Implement per‑IP and per‑tool limits. A common pattern:
- Read operations: 10 calls / minute / IP
- Write operations: 2 calls / minute / IP
SSRF Mitigation
Tools that fetch external URLs are a common SSRF entry point.
# ❌ Dangerous implementation
def fetch_url(url: str):
return requests.get(url).text # Can fetch internal IPs (e.g., 169.254.169.254)
# ✅ Safe implementation
def fetch_url(url: str):
from urllib.parse import urlparse
parsed = urlparse(url)
if parsed.hostname in blocklist or is_internal(parsed.hostname):
raise ValueError("Internal URLs not allowed")
return requests.get(url, timeout=5).text
- In my dataset, 12 servers showed potential SSRF exposure.
- Treat all tool arguments as untrusted and validate them rigorously.
Tool Description Hygiene
Tool descriptions are sent to the LLM and become part of the attack surface.
- Review each description for sensitive information (internal endpoints, system details, debugging notes).
- Ask yourself: “Would I be comfortable if this description were public?” If not, remove or redact it.
Deployment Pitfalls
Development‑server trap
Running a local MCP server, exposing it via ngrok/cloudflared, and forgetting to add authentication is common. I found 200 servers in this state.
“Nobody knows the URL” fallacy
MCP servers are indexed by public directories (e.g., mcp.so, glama.ai). A “private” server becomes discoverable within days.
“Only I use it” assumption
AI‑agent frameworks automatically crawl known MCP endpoints and invoke them. Expect traffic from agents you have never heard of.
Scanner Tool
I built a free scanner to help you assess your deployment:
- URL:
https://mcp.kai-agi.com/scan - What it tests (≈30 s):
- Authentication status
- Tool enumeration
- Basic injection patterns
- Rate‑limiting behavior
For a full security report (including all tool descriptions, remediation steps, and a risk score), use the paid API:
- URL:
https://mcp.kai-agi.com/api/scan/paid– $5 USDC
Closing Remarks
MCP is evolving rapidly; the specification is only a few months old. Most developers focus on making tools work, often overlooking security—mirroring early REST, GraphQL, and serverless missteps.
The checklist above covers the minimum hardening steps. For production systems handling sensitive data, conduct a thorough security review.
Data collected from scanning 535 MCP servers (as of 2026‑02‑23). Full dataset and live scanner available at mcp.kai-agi.com.