MCP Permissions: Access Control for Tools
What This Article Covers
- How MCP permissions work for AI agents.
- Implementing access control for MCP tools.
- Granting agents only the permissions they need.
- Practical examples for filesystem, database, and API permissions.
- Security best practices and the principle of least privilege.
Introduction: Understanding MCP Permissions
MCP (Model Context Protocol) connects agents to tools. Permissions determine which tools an agent can use and what it can do with them. Not “all tools for everyone,” but rather “only necessary tools, only necessary actions.”
This article is for anyone configuring MCP permissions for agents. For foundational concepts, see MCP and Tool Permissions.
Why Do You Need MCP Permissions?
Imagine your agent has access to the filesystem. Without permissions, it can read, write, and delete all files. With permissions, it can only read from /data, cannot write, and cannot delete. That’s least privilege in action: only the permissions needed for the job.
MCP Permissions Explained
MCP tools have permissions: read, write, execute, delete. An agent receives only the permissions necessary for its task. A research agent needs read access but not write. An admin agent needs write access, but only to specific paths.
The core principle is simple: least privilege, only necessary permissions.
Who Is This Article For?
- Security-conscious teams who want to lock down their agents.
- Developers building MCP tools with permission controls.
- System administrators implementing access control.
- DevOps engineers deploying agents safely.
Key Terms
- MCP - Model Context Protocol. Use when: integrating tools.
- Tool Permissions - Access control. Use when: securing your system.
- Least Privilege - Minimal permissions. Use when: hardening security.
- Prompt Injection - Attack vectors. Use when: assessing risks.
Permission Model
# Define MCP tool permissions
tools = {
"filesystem": {
"permissions": ["read", "write"],
"allowed_paths": ["/data", "/tmp"],
"denied_paths": ["/etc", "/var", "/root"]
},
"database": {
"permissions": ["read", "insert"],
"allowed_tables": ["users", "logs"],
"denied_tables": ["admin", "secrets"]
},
"api": {
"permissions": ["get", "post"],
"allowed_endpoints": ["/api/data", "/api/status"],
"rate_limit": 100 # Requests per hour
}
}
Example 1: Filesystem Permissions
class FileSystemTool:
"""Filesystem tool with permissions"""
def __init__(self):
self.permissions = {
"read": True,
"write": True,
"delete": False, # No delete permission
"allowed_paths": ["/data", "/tmp"],
"denied_paths": ["/etc", "/var", "/root", "/home"]
}
def check_permission(self, action, path):
"""Check permission for an action"""
# Is the action allowed?
if not self.permissions.get(action, False):
raise PermissionError(f"Action '{action}' not allowed")
# Is the path allowed?
if not any(path.startswith(p) for p in self.permissions["allowed_paths"]):
raise PermissionError(f"Path '{path}' not allowed")
# Is the path denied?
if any(path.startswith(p) for p in self.permissions["denied_paths"]):
raise PermissionError(f"Path '{path}' is denied")
return True
def read_file(self, path):
"""Read a file (with permission check)"""
self.check_permission("read", path)
with open(path) as f:
return f.read()
def write_file(self, path, content):
"""Write a file (with permission check)"""
self.check_permission("write", path)
with open(path, "w") as f:
f.write(content)
Example 2: Database Permissions
class DatabaseTool:
"""Database tool with permissions"""
def __init__(self):
self.permissions = {
"read": True,
"insert": True,
"update": False, # No update permission
"delete": False, # No delete permission
"allowed_tables": ["users", "logs", "events"],
"denied_tables": ["admin", "secrets", "credentials"]
}
def query(self, table, filters):
"""Query with permission check"""
# Is the table denied?
if table in self.permissions["denied_tables"]:
raise PermissionError(f"Table '{table}' is denied")
# Is the table allowed?
if table not in self.permissions["allowed_tables"]:
raise PermissionError(f"Table '{table}' not allowed")
# Execute query
return self.db.query(table, filters)
Example 3: API Permissions
class APITool:
"""API tool with permissions"""
def __init__(self):
self.permissions = {
"get": True,
"post": True,
"put": False,
"delete": False,
"allowed_endpoints": [
"/api/data",
"/api/status",
"/api/users"
],
"rate_limit": 100 # Requests per hour
}
self.request_count = 0
def call_api(self, method, endpoint, data=None):
"""Call API with permission check"""
# Is the method allowed?
if method.lower() not in self.permissions:
raise PermissionError(f"Method '{method}' not allowed")
if not self.permissions[method.lower()]:
raise PermissionError(f"Method '{method}' is denied")
# Is the endpoint allowed?
if endpoint not in self.permissions["allowed_endpoints"]:
raise PermissionError(f"Endpoint '{endpoint}' not allowed")
# Check rate limit
if self.request_count >= self.permissions["rate_limit"]:
raise RateLimitError("Rate limit exceeded")
self.request_count += 1
return self.http_request(method, endpoint, data)
Permissions per Agent
# Different agents, different permissions
agents = {
"research_agent": {
"tools": {
"filesystem": {"read": True, "write": False},
"web_search": {"search": True},
"database": {"read": True}
}
},
"writer_agent": {
"tools": {
"filesystem": {"read": True, "write": True},
"database": {"read": True, "insert": True}
}
},
"admin_agent": {
"tools": {
"filesystem": {"read": True, "write": True, "delete": True},
"database": {"read": True, "insert": True, "update": True, "delete": True},
"system": {"execute": True}
}
}
}
Security Guidelines
- Least Privilege: Only grant necessary permissions. See Tool Permissions.
- Path Restrictions: For filesystem tools, restrict to allowed paths only, never root directories.
- Rate Limiting: For APIs, enforce rate limits to prevent abuse.
- Audit Logging: Log all permission violations. See Audit Logging.
- Prompt Injection: Agents may attempt to bypass permissions. See Prompt Injection.
Common Pitfalls
- Excessive permissions: Agents should not have unrestricted access. Apply the principle of least privilege.
- No path restrictions: Agents should not be able to access all file paths.
- Missing rate limits: Without rate limits, agents can overwhelm APIs.
- Permissions not validated: Permissions must be checked before each action.
- No audit trail: Permission violations should be logged.
Further Reading
- MCP - Model Context Protocol.
- MCP Filesystem - Filesystem MCP.
- Custom MCP Tools - Building tools.
- MCP Security - Security.
- Tool Permissions - Permissions.
- Audit Logging - Logging.
Key Takeaways:
- MCP permissions: least privilege for tools.
- Filesystem: only allowed paths, no root access.
- Database: only allowed tables, no admin tables.
- API: rate limits and endpoint restrictions.
- Audit: log all permission violations.
FAQ
What are MCP permissions?
What is least privilege?
How do I implement permissions?
What types of permissions exist?
Can an agent bypass permissions?
How do I log permissions?
Should different agents have different permissions?
What are default permissions?
Sources and Further Reading
- MCP - Model Context Protocol.
- Least Privilege - Security principle.


