The Problem
MCP servers grant AI agents access to tools, but there is no standard mechanism to audit what permissions each server exposes or to enforce scope restrictions. An MCP server that provides search might also expose file system access, database queries, or email sending. When multiple MCP servers are connected to an agent, the cumulative permission surface is unknown. A compromised or misconfigured server can give an agent capabilities that were never intended. The MCP specification does not include a permission model, so enforcement falls entirely on the integrator.
The Scavio Solution
Build a permission audit layer that inventories every tool exposed by every MCP server in your deployment, categorizes them by risk level, and enforces an allowlist. Before an agent can call a tool, the permission layer checks whether that tool is in the approved scope for that agent role. Scavio's MCP server at mcp.scavio.dev/mcp exposes only search tools with no file system, database, or email capabilities, making it the lowest-risk MCP server to connect. The audit layer logs every tool invocation for compliance review.
Before
Before permission enforcement, MCP servers granted agents broad, unaudited tool access. No one knew the cumulative permission surface across connected servers, and a misconfigured server could silently expose dangerous capabilities.
After
After building the permission audit layer, every MCP tool invocation is checked against an approved scope list. The team knows exactly what each agent can access, and unauthorized tool calls are blocked and logged for review.
Who It Is For
Platform engineers and security teams deploying MCP servers in production who need visibility into the permission surface area. Anyone connecting multiple MCP servers to agents without a centralized permission model.
Key Benefits
- Inventory all tools exposed by every connected MCP server
- Risk categorization flags high-risk tool capabilities
- Allowlist enforcement blocks unauthorized tool invocations
- Audit logging for compliance and security review
- Scavio MCP exposes only search tools with minimal risk surface
Python Example
import json
from dataclasses import dataclass
@dataclass
class MCPPermission:
server: str
tool: str
risk_level: str # low, medium, high
approved: bool
def audit_mcp_servers(servers: dict) -> list[MCPPermission]:
"""Audit MCP server permissions and flag risk levels."""
permissions = []
high_risk_patterns = ["file", "database", "email", "exec", "shell", "write"]
medium_risk_patterns = ["delete", "update", "create"]
for server_name, tools in servers.items():
for tool in tools:
tool_lower = tool.lower()
risk = "low"
if any(p in tool_lower for p in high_risk_patterns):
risk = "high"
elif any(p in tool_lower for p in medium_risk_patterns):
risk = "medium"
permissions.append(MCPPermission(
server=server_name,
tool=tool,
risk_level=risk,
approved=risk != "high",
))
return permissions
def enforce_permissions(permissions: list[MCPPermission], server: str, tool: str) -> bool:
"""Check if a tool call is allowed."""
for p in permissions:
if p.server == server and p.tool == tool:
return p.approved
return False # Deny by default
# Example: Audit connected MCP servers
servers = {
"scavio_mcp": ["search_google", "search_youtube", "search_amazon", "search_reddit", "search_tiktok"],
"internal_mcp": ["query_database", "read_file", "write_file", "send_email", "search_docs"],
}
perms = audit_mcp_servers(servers)
print("MCP Permission Audit:")
for p in perms:
status = "APPROVED" if p.approved else "BLOCKED"
print(f" [{p.risk_level:6s}] {p.server}/{p.tool} -> {status}")
high_risk = [p for p in perms if p.risk_level == "high"]
print(f"\nHigh-risk tools found: {len(high_risk)}")
for p in high_risk:
print(f" {p.server}/{p.tool} -> BLOCKED")JavaScript Example
function auditMcpServers(servers) {
const highRisk = ["file", "database", "email", "exec", "shell", "write"];
const medRisk = ["delete", "update", "create"];
const perms = [];
for (const [server, tools] of Object.entries(servers)) {
for (const tool of tools) {
const lower = tool.toLowerCase();
let risk = "low";
if (highRisk.some((p) => lower.includes(p))) risk = "high";
else if (medRisk.some((p) => lower.includes(p))) risk = "medium";
perms.push({ server, tool, risk, approved: risk !== "high" });
}
}
return perms;
}
const servers = {
scavio_mcp: ["search_google", "search_youtube", "search_amazon", "search_reddit", "search_tiktok"],
internal_mcp: ["query_database", "read_file", "write_file", "send_email", "search_docs"],
};
const perms = auditMcpServers(servers);
console.log("MCP Permission Audit:");
for (const p of perms) console.log(` [${p.risk.padEnd(6)}] ${p.server}/${p.tool} -> ${p.approved ? "APPROVED" : "BLOCKED"}`);
const blocked = perms.filter((p) => p.risk === "high");
console.log(`\nHigh-risk tools blocked: ${blocked.length}`);Platforms Used
Web search with knowledge graph, PAA, and AI overviews
YouTube
Video search with transcripts and metadata
Amazon
Product search with prices, ratings, and reviews
Walmart
Product search with pricing and fulfillment data
Community, posts & threaded comments from any subreddit
TikTok
Trending video, creator, and product discovery