Skip to content

Config Schema

The dynmcp config file declares which upstream MCPs to proxy and how to connect to each one. The schema is defined and validated with Zod at runtime, and published as a JSON Schema at https://dynamicmcp.tools/config.json for editor support.

JSON and YAML both work. The file extension picks the parser: .json for JSON, .yml or .yaml for YAML.

FieldTypeRequiredDescription
$schemastringNoPointer to the published JSON Schema. Not interpreted at runtime — used purely for editor validation.
env"enable" | "dotenv" | "process" | "disable"NoControls environment variable interpolation. Default: "enable". See Environment Variables.
mcpRecord<string, McpEntry>YesMap of upstream MCPs, keyed by MCP name. Must contain at least one entry.

The MCP name (the key under mcp) must match the regex /^[a-z0-9][a-z0-9-]*$/. It is used as the namespace prefix for all of that MCP’s tools (e.g. tool browser_navigate under MCP chrome-devtools is exposed as chrome-devtools/browser_navigate).

These fields are valid on every entry, regardless of transport.

FieldTypeRequiredDescription
transport"stdio" | "streamable-http" | "sse"YesHow dynmcp connects to this upstream MCP.
descriptionstringNoWhen present, marks this MCP as lazy (dynamic discovery). Must be a non-empty string after environment-variable interpolation. The presence of this field on any entry enables dynamic discovery for the proxy as a whole.

Spawns the upstream MCP as a child process.

FieldTypeRequiredDescription
commandstringYesThe executable to spawn.
argsstring[]NoArguments passed to the command. Default: [].
envRecord<string, string>NoEnvironment variables to set for the spawned process.
{
"filesystem": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}

Connects to a remote MCP over HTTP.

FieldTypeRequiredDescription
urlstringYesThe URL of the remote MCP endpoint. Must be a valid http:// or https:// URL.
headersRecord<string, string>NoHTTP headers included on every request. Typically used for static bearer-token auth (e.g. Authorization: Bearer ${TOKEN}).
authobjectNoPre-registered OAuth client credentials. Omit to use Dynamic Client Registration on first dynmcp login. See OAuth reference.
{
"aws-knowledge": {
"transport": "streamable-http",
"url": "https://knowledge-mcp.global.api.aws"
}
}

Connects to a remote MCP over Server-Sent Events.

FieldTypeRequiredDescription
urlstringYesThe URL of the remote SSE endpoint. Must be a valid http:// or https:// URL.
headersRecord<string, string>NoHTTP headers included on the connection request.
authobjectNoPre-registered OAuth client credentials. Omit to use Dynamic Client Registration on first dynmcp login. See OAuth reference.
{
"remote-sse": {
"transport": "sse",
"url": "https://example.com/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}

Optional. Use this to supply pre-registered OAuth client credentials. When auth is omitted, dynmcp login uses Dynamic Client Registration to register a fresh client automatically.

FieldTypeRequiredDescription
auth.client_idstringYes (if auth present)Pre-registered OAuth client ID.
auth.client_secretstringNoPre-registered client secret for confidential clients. Omit for public (PKCE-only) clients.
auth.scopestringNoSpace-separated OAuth scopes to request. Overrides scopes advertised by the server’s protected-resource metadata.
{
"github": {
"transport": "streamable-http",
"url": "https://api.githubcopilot.com/mcp",
"auth": {
"client_id": "${GITHUB_OAUTH_CLIENT_ID}",
"client_secret": "${GITHUB_OAUTH_CLIENT_SECRET}",
"scope": "repo"
}
}
}

auth is rejected on stdio entries. See the OAuth Authentication guide for the full flow, and the OAuth reference for keychain storage and runtime behavior.

The following are enforced at startup; violations are reported before any upstream MCP is contacted:

  • The mcp map must contain at least one entry. An empty mcp: {} is a startup error.
  • stdio entries must not include url, headers, or auth.
  • streamable-http and sse entries must not include command, args, or env.
  • streamable-http and sse url fields must be valid http:// or https:// URLs.
  • description, if present, must be non-empty after environment-variable interpolation. An empty or whitespace-only description is a startup error.
  • auth.client_id, if auth is present, must be non-empty after environment-variable interpolation.
  • Unknown keys inside the auth block are rejected.
  • MCP names (keys under mcp) must match /^[a-z0-9][a-z0-9-]*$/.

Reference the published JSON Schema at the top of your config file and any editor with JSON Schema support (VS Code, JetBrains IDEs, Neovim with an LSP) will give you autocomplete and inline validation:

{
"$schema": "https://dynamicmcp.tools/config.json",
"mcp": {
"filesystem": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
}

For YAML, use a comment-based hint instead:

# yaml-language-server: $schema=https://dynamicmcp.tools/config.json
mcp:
filesystem:
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
{
"$schema": "https://dynamicmcp.tools/config.json",
"env": "enable",
"mcp": {
"chrome-devtools": {
"description": "Browser automation via Chrome DevTools Protocol. Navigate pages, take screenshots, inspect the DOM, run JavaScript in page context.",
"transport": "stdio",
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest"]
},
"filesystem": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
},
"remote-http-mcp": {
"transport": "streamable-http",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
},
"remote-sse-mcp": {
"transport": "sse",
"url": "https://example.com/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN:-anonymous}"
}
}
}
}