Config Schema
File format
MetaMCP reads .mcp.json, a JSON file with a single top-level key: mcpServers. This is the same format used by Claude Desktop and Claude Code.
{
"mcpServers": {
"<server-name>": { ... },
"<server-name>": { ... }
}
}Top-level structure
| Key | Type | Description |
|---|---|---|
mcpServers |
Record<string, ServerEntry> |
Map of server names to their configurations. Each key becomes the server's identifier used in mcp_call and the servers Proxy in mcp_execute. |
Server entry fields
Each server entry supports the following fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
command |
string | yes | The executable to run. Can be a bare command name (resolved via PATH) or an absolute path. | |
args |
string[] | no | [] |
Arguments passed to the command. |
env |
Record<string, string> | no | {} |
Environment variables scoped to this server's process. These are merged with the parent environment but do not leak to other servers. |
All configured servers are assigned "vital" criticality by default, which means they get automatic retry-on-crash behavior (one retry attempt).
Default values
These defaults apply to the MetaMCP server process itself, configured via CLI flags:
| Setting | Default | CLI Flag |
|---|---|---|
| Config path | .mcp.json (current directory) |
--config |
| Pool max connections | 20 | --max-connections |
| Pool reserve size | 0 | (not configurable via CLI) |
| Pool minimum size | 0 | (not configurable via CLI) |
| Reserve pool timeout | 5000ms | (not configurable via CLI) |
| Idle connection timeout | 300,000ms (5 minutes) | --idle-timeout |
| Circuit breaker threshold | 5 consecutive failures | --failure-threshold |
| Circuit breaker cooldown | 30,000ms (30 seconds) | --cooldown |
Example configurations
Minimal: one server via npx
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
}
}
}Multi-server setup
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
},
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "/path/to/db.sqlite"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_your_token"
}
}
}
}With environment variables
{
"mcpServers": {
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-...",
"SLACK_TEAM_ID": "T01234567"
}
}
}
}Environment variables in the env field are passed only to that server's child process. They do not affect MetaMCP or other servers.
Local binary with absolute path
{
"mcpServers": {
"custom": {
"command": "/usr/local/bin/my-mcp-server",
"args": ["--verbose", "--port", "9090"]
}
}
}Config locations
MetaMCP looks for the config file in this order:
- The path specified by
--config(if provided). .mcp.jsonin the current working directory.
If the file is not found and a .mcp.example.json exists in the working directory, MetaMCP logs a warning suggesting you copy it.
If no config file is found at all, MetaMCP starts with zero child servers. You can still use mcp_provision to discover and add servers at runtime.
Server names
The key in the mcpServers object becomes the server's name. This name is used:
- As the
serverparameter inmcp_call - As the property name on the
serversProxy inmcp_execute(e.g.,servers.playwright) - In
mcp_discoverresults and status output
Choose short, descriptive names without spaces or special characters.