DEV Community

Thezenmonster
Thezenmonster

Posted on

Securing Your MCP Server in 2026 — A Practical Guide

MCP servers are the new attack surface. 97 million monthly SDK downloads, 10,000+ in production, and most have zero security. Here's what can go wrong and how to fix each one.

The Threat Model

An MCP server exposes tools that AI agents call remotely. Without security, any agent can:

  • Call any tool — including destructive ones (delete, execute, transfer)
  • Exfiltrate data — read sensitive files or databases via tool calls
  • Inject prompts — embed malicious instructions in tool arguments
  • Impersonate — claim to be a trusted agent with no verification
  • Chain attacks — Agent A calls your server, then Agent B calls Agent A. You're two hops from the attacker.

Red Hat, Bright Security, and the MCP roadmap team have all flagged these risks in March 2026. The protocol itself is adding auth and gateway patterns, but those specs aren't final yet. You need to secure your server now.

1. Rate Limiting

Problem: An agent can flood your server with requests, consuming resources or exploiting race conditions.

Fix: Sliding window rate limiter per caller.

import { McpGuard } from 'mcp-trust-guard';

const guard = new McpGuard({
  rateLimit: { window: 60, max: 30 }, // 30 requests per minute per caller
});
app.use('/mcp', guard.middleware());
Enter fullscreen mode Exit fullscreen mode

2. Agent Identity

Problem: You don't know who's calling. Any agent, any deployer, any model.

Fix: Require an identity header. Then verify the deployer.

# Check who deployed this agent
curl https://agentscores.xyz/api/verify/deployer?github=their-username
Enter fullscreen mode Exit fullscreen mode

A deployer with 5 years of GitHub history and 50 repos is different from an account created yesterday. You can't eliminate risk, but you can quantify it.

3. Abuse Database

Problem: An agent was caught exfiltrating data from another server last week. Your server has no idea.

Fix: Check the KYA abuse database before allowing access.

const guard = new McpGuard({
  abuseCheck: true,
  abuseBlockLevel: 'CAUTION', // block agents with 2+ reports or high severity
});
Enter fullscreen mode Exit fullscreen mode

Community-driven. Anyone can report. Anyone can check. Free, no API key.

Report: POST https://agentscores.xyz/api/abuse/report
Check: GET https://agentscores.xyz/api/abuse/check?agent=name
Enter fullscreen mode Exit fullscreen mode

4. Tool-Level Permissions

Problem: A "data analyst" agent requests access to delete_database. That's anomalous.

Fix: Classify tools by risk and set minimum trust thresholds.

const guard = new McpGuard({
  rules: [
    { minTrust: 0,  tools: ['get_*', 'read_*', 'list_*'] },
    { minTrust: 30, tools: ['create_*', 'update_*'] },
    { minTrust: 60, tools: ['delete_*', 'admin_*'] },
  ],
});
Enter fullscreen mode Exit fullscreen mode

You can also analyse requested tools programmatically:

curl -X POST https://agentscores.xyz/api/verify/permissions \
  -H "Content-Type: application/json" \
  -d '{"tools": ["read_file", "delete_database"], "agent_type": "data analyst"}'
# → anomaly detected: analyst requesting CRITICAL tools
Enter fullscreen mode Exit fullscreen mode

5. Audit Logging

Problem: Something went wrong. You have no record of what agent called what tool and when.

Fix: Enable audit logging.

const guard = new McpGuard({
  audit: true, // logs to console
  // or: audit: (entry) => db.insert('audit_log', entry)
});
Enter fullscreen mode Exit fullscreen mode

Every tool call logged with: timestamp, caller, tool, trust score, allowed/denied, reason.

6. Code Verification

Problem: An MCP tool you installed from npm was updated overnight. The new version sends data to an unknown endpoint.

Fix: Verify the code before trusting it.

curl "https://agentscores.xyz/api/verify/code?repo=owner/repo&npm=package-name"
Enter fullscreen mode Exit fullscreen mode

Checks: open source, licence, dependency count, install scripts (common malware vector), maintenance activity, last commit date.

7. Deployment Context Awareness

Problem: A local stdio agent and a remote autonomous agent chain have very different risk profiles, but your server treats them identically.

Fix: Factor in how the agent is deployed.

curl "https://agentscores.xyz/api/verify/deployment?transport=http&human_in_loop=false&orchestrated=true"
# → risk: HIGH (remote, autonomous, orchestrated)
Enter fullscreen mode Exit fullscreen mode

Local + human oversight = lower risk. Remote + autonomous + multi-hop = maximum caution.

The Full Stack

All seven layers in one setup:

import { McpGuard } from 'mcp-trust-guard';

const guard = new McpGuard({
  abuseCheck: true,
  abuseBlockLevel: 'CAUTION',
  rateLimit: { window: 60, max: 30 },
  rules: [
    { minTrust: 0,  tools: ['get_*', 'read_*'] },
    { minTrust: 30, tools: ['create_*', 'update_*'] },
    { minTrust: 60, tools: ['delete_*', 'admin_*'] },
  ],
  audit: true,
});

app.use(express.json());
app.use('/mcp', guard.middleware());
Enter fullscreen mode Exit fullscreen mode

Or run all six KYA checks with one API call:

curl -X POST https://agentscores.xyz/api/verify \
  -H "Content-Type: application/json" \
  -d '{"agent":"name","github":"deployer","model":"claude","tools":["read_file"],"transport":"http"}'
Enter fullscreen mode Exit fullscreen mode

What's Coming

The MCP 2026 roadmap includes OAuth 2.1, DPoP tokens, workload identity federation, and gateway patterns. When those specs land, they'll handle authentication at the protocol level. KYA handles what auth can't — reputation, abuse history, code auditability, and deployment risk.

Auth tells you WHO someone is. KYA tells you WHETHER you should trust them.

Top comments (0)