Custom permissions
ToolHive includes a permission system that lets you control an MCP server's access to your host's file system and network resources. This helps you maintain security and ensures that MCP servers operate within defined boundaries.
Understanding permission profiles
Permissions are defined using permission profiles—JSON files that specify both file system and network access rules for an MCP server. Each MCP server can use only one permission profile at a time, so you include all necessary permissions in a single profile.
Permission profiles control two types of access:
- Host file system access specifies paths on your host that are mounted into the MCP server container — see file system access for detailed examples
- Network access rules let you restrict outbound HTTP(S) connectivity from the MCP server — see network isolation for architecture details and examples
Profile structure
Profiles are defined in JSON format and can include the following properties:
read
: List of paths on your host file system that the MCP server can readwrite
: List of file system paths that the MCP server can write to (this also implies read access)network
: Network access rules for outbound connections:outbound
: Outbound network access rules, which include:insecure_allow_all
: If set totrue
, allows unrestricted outbound network access. This isn't recommended for production use.allow_host
: List of allowed hostnames or IP addresses for outbound connections. To allow all subdomains of a domain, prefix the domain with a period (e.g.,.github.com
allows any subdomain ofgithub.com
). Wildcards are not supported.allow_port
: List of allowed ports for outbound connections
Default permissions in the ToolHive registry
ToolHive includes default least-privilege permissions for MCP servers in the built-in registry. These defaults balance functionality and security, but you should review them to make sure they meet your specific requirements.
View these permissions using the following command:
thv registry info <SERVER_NAME>
In the output, look for the "Permissions" section:
Permissions:
Network:
Allow Host: .google.com
Allow Port: 443
This example shows that the MCP server can make outbound network connections to
*.google.com
(note the leading .
which enables subdomain matching) on
port 443.
For security reasons, none of the MCP servers in the registry have any default
file system permissions defined. This means they cannot read or write to any
paths on your host system unless you explicitly grant access using a custom
permission profile or use the --volume
flag when running the server.
Always verify the default permissions and override them with a custom profile if needed to meet your security policies.
Add --format json
to the
thv registry info
command to get the
output in JSON format for easier customization. Use the contents of the
permissions
section as a starting point for creating a custom profile.
Built-in profiles
ToolHive includes two built-in profiles for network access that you can use without creating a custom file:
-
network
: Permits all outbound network access. This is the default profile applied to MCP servers when you run a custom server without the--permission-profile
flag.importantThis profile is useful for development and testing but isn't recommended for production use since it doesn't restrict network destinations. Create a custom profile that specifies the allowed hosts and ports when possible.
-
none
: Restricts all network access. Use this for MCP servers that don't require external connectivity.
Both built-in profiles provide no file system access by default. To add file system permissions, either:
- Use the
--volume
flag to mount specific paths - Create a custom profile that includes both network settings and file system permissions
Create a custom permission profile
You can create a JSON file with your desired permissions. Include file system permissions, network permissions, or both in the same profile.
Example: Combined file system and network permissions
When your MCP server needs both file access and network connectivity, include both types of permissions in a single profile:
{
"read": ["/home/user/documents", "/home/user/config"],
"write": ["/home/user/output"],
"network": {
"outbound": {
"insecure_allow_all": false,
"allow_host": ["api.github.com", ".googleapis.com"],
"allow_port": [443]
}
}
}
This profile:
- Mounts
/home/user/documents
and/home/user/config
as read-only paths - Mounts
/home/user/output
with read and write access (note thatwrite
also implies read access) - Allows outbound HTTPS connections to
api.github.com
and any subdomain ofgoogleapis.com
Example: Network-only permissions
Use this approach when your MCP server needs to make API calls but doesn't require file system access:
{
"network": {
"outbound": {
"allow_host": ["host.docker.internal", ".intranet.example.com"],
"allow_port": [8080, 3000]
}
}
}
This profile allows the server to connect to local development servers and internal company resources without granting any file system access.
See network isolation for more details about network permissions and how isolation works.
Example: File system-only permissions
Use this when your MCP server works with local files but doesn't need network access:
{
"read": ["/var/log"],
"write": ["/tmp/mcp-output"]
}
This profile grants file system access without defining any network permissions.
(Note, to actually block network access, use the --isolate-network
flag when
running the server.)
See file system access for more details and specific examples.
Apply a permission profile
Using a built-in profile
To run an MCP server with unrestricted network access (the default):
thv run --permission-profile network <SERVER>
To run an MCP server with no network access:
thv run --isolate-network --permission-profile none <SERVER>
Using a custom profile file
To run an MCP server with your custom profile:
thv run --isolate-network --permission-profile /path/to/custom-profile.json <SERVER>
Security best practices
When creating and using permission profiles:
- Use the
none
profile when possible for MCP servers that don't require network or file access - Only grant necessary permissions
- Avoid enabling
network.outbound.insecure_allow_all
, as this allows unrestricted outbound network access - Review and test custom profiles thoroughly
- Keep permission profiles in version control to track changes and share them with your team