mcp.json
Complete AGH mcp.json sidecar schema, supported locations, validation, and merge precedence.
- Audience
- Operators running durable agent work
- Focus
- Configuration guidance shaped for scanability, day-two clarity, and operator context.
mcp.json is an optional JSON sidecar for MCP server declarations. AGH accepts it at global,
workspace, agent, and skill scopes.
Quick Reference
| Field | Type | Default | Valid values | Description |
|---|---|---|---|---|
mcpServers | object map | empty | Server-name keys with server objects. | Camel-case top-level MCP server map. |
mcp_servers | object map | empty | Server-name keys with server objects. | Snake-case top-level MCP server map. |
<server>.transport | string | inferred | stdio, http, or sse. | MCP transport. url without transport is HTTP. |
<server>.command | string | required for stdio | Non-empty after trimming. | Local MCP server command. |
<server>.url | string URL | required for remote | Absolute URL. | Remote MCP endpoint for http or sse. |
<server>.auth | object | empty | OAuth 2.1 PKCE config. | Remote auth metadata and client settings. |
<server>.args | string array | empty | Strings. | Command arguments for stdio servers. |
<server>.env | string map | empty | String keys and values. | Literal environment values for stdio servers. |
Unknown JSON fields fail parsing. Trailing JSON values after the first document also fail parsing.
Missing mcp.json files are treated as absent.
There is no implemented mcp.json tool-mapping schema today. The current parser accepts MCP server
definitions only.
Supported Locations
| Location | Scope | Applies when |
|---|---|---|
$AGH_HOME/mcp.json | Global top-level MCP | General runtime config loads. Defaults to ~/.agh/mcp.json. |
<workspace>/.agh/mcp.json | Workspace top-level MCP | A workspace root is resolved for the command or session. |
<agent-dir>/mcp.json | Agent-local MCP | Next to AGENT.md. |
<skill-dir>/mcp.json | Skill-local MCP | Next to SKILL.md. |
Complete Example
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/work"],
"env": {
"LOG_LEVEL": "info"
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"secret_env": {
"GITHUB_TOKEN": "vault:mcp/github/env/GITHUB_TOKEN"
}
},
"remote-docs": {
"transport": "sse",
"url": "https://mcp.example.com/sse",
"auth": {
"type": "oauth2_pkce",
"issuer_url": "https://auth.example.com",
"client_id": "agh-desktop",
"client_secret_ref": "env:REMOTE_DOCS_MCP_CLIENT_SECRET",
"scopes": ["mcp.read", "mcp.write"]
}
}
}
}The snake-case form is also accepted:
{
"mcp_servers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}Top-Level Keys
| Key | Type | Default | Valid values | Description |
|---|---|---|---|---|
mcpServers | object map | empty | Keys are server names; values are server objects. | Primary JSON form. |
mcp_servers | object map | empty | Keys are server names; values are server objects. | Alternate JSON form. Loaded after mcpServers inside the same file. |
If both top-level keys are present in the same file and both define the same server name,
mcp_servers replaces the whole server object from mcpServers.
Server Object
| Field | Type | Default | Valid values | Description |
|---|---|---|---|---|
| Map key | string | required | Non-empty after trimming. Duplicate trimmed names fail. | Server name. |
transport | string | inferred | stdio, http, or sse. | Transport kind. Local command servers default to stdio; URL servers default to http. |
command | string | required for stdio | Non-empty after trimming. | Executable command. Only valid with stdio transport. |
url | string URL | required for remote | Absolute URL. | Remote MCP endpoint. Required for http and sse; invalid for stdio. |
auth | object | empty | OAuth config listed below. | Remote MCP auth configuration. Only valid for remote transports. |
args | string array | empty | Strings. | Process arguments for stdio servers. |
env | string map | empty | String keys and values. | Literal environment values. AGH does not expand $VAR, ~, or shell syntax here. |
secret_env | string map | empty | env:NAME or vault:mcp/<server>/env/<KEY> refs. | Secret environment bindings for stdio servers. Values are resolved at launch and redacted from diagnostics. |
Remote OAuth Auth Object
Remote MCP servers can use OAuth 2.1 authorization code with PKCE. The config contains only
metadata and client settings; access tokens, refresh tokens, authorization codes, PKCE verifiers,
and client-secret values are stored or handled by the auth subsystem and are never written to
mcp.json.
AGH-managed MCP secret refs live in the Vault under the mcp namespace. Use
vault:mcp/<server>/env/<KEY> for stdio secret_env bindings and
vault:mcp/<server>/oauth/client-secret for OAuth client secrets that AGH owns.
| Field | Type | Default | Valid values | Description |
|---|---|---|---|---|
type | string | required | oauth2_pkce | Enables the OAuth 2.1 PKCE lifecycle. |
client_id | string | required | Non-empty. | OAuth client ID registered with the remote MCP provider. |
client_secret_ref | string | empty | env:NAME or vault:mcp/<server>/oauth/client-secret. | Optional ref containing the OAuth client secret when the provider needs one. |
issuer_url | string URL | optional | Absolute http or https URL. | Issuer used for /.well-known/oauth-authorization-server discovery. |
metadata_url | string URL | optional | Absolute http or https URL. | Explicit OAuth authorization-server metadata URL. |
authorization_url | string URL | optional | Absolute http or https URL. | Direct authorization endpoint. Must be paired with token_url. |
token_url | string URL | optional | Absolute http or https URL. | Direct token endpoint. Must be paired with authorization_url. |
revocation_url | string URL | optional | Absolute http or https URL. | Optional token revocation endpoint used by agh mcp auth logout. |
scopes | string array | empty | Non-empty strings when present. | Requested OAuth scopes. |
One of metadata_url, issuer_url, or the pair authorization_url plus token_url is required.
Merge And Override Rules
mcp.json uses whole-object replacement. TOML uses field-level merging.
| Situation | Behavior |
|---|---|
Same-name TOML [[mcp_servers]] overlay | Fields merge by name. Non-empty transport, command, URL, auth fields, args, and env keys overlay the existing server. |
Same-name mcp.json sidecar overlay | The sidecar replaces the entire existing server object. |
Same-name inline AGENT.md and agent-local mcp.json | Agent-local sidecar replaces the whole inline server object. |
Same-name SKILL.md metadata and skill-local mcp.json | Skill-local sidecar replaces the whole frontmatter server object. |
| Duplicate names inside one JSON document after trimming | Loading fails. |
Runtime Precedence
Top-level configuration loads in this order:
- Built-in defaults.
$AGH_HOME/config.toml.$AGH_HOME/mcp.json.<workspace>/.agh/config.toml.<workspace>/.agh/mcp.json.
Daemon boot uses home config for boot-time daemon settings. MCP sidecars are applied by the general config loader used for session and runtime resolution.
Session startup then resolves MCP servers in this order:
- Top-level config MCP servers.
- Provider MCP servers.
- Agent MCP servers.
- Active skill MCP servers.
Provider and agent MCP servers use field-level merging when they come from TOML or YAML. Agent and skill sidecars replace same-name inline servers as whole objects.
Validation Errors
| Error case | Result |
|---|---|
| Unknown top-level key | Parse error. |
| Unknown server field | Parse error. |
| Trailing JSON value | Parse error. |
| Empty server name after trimming | Validation error. |
| Duplicate trimmed server name | Validation error. |
Missing stdio command | Validation error. |
command on remote transport | Validation error. |
Missing remote url | Validation error. |
url on stdio transport | Validation error. |
auth on stdio transport | Validation error. |
| Incomplete OAuth metadata | Validation error. |
Non-string values in args or env | JSON decoding error. |
| Missing file | Ignored. |
Examples By Scope
Global MCP Server
~/.agh/
config.toml
mcp.jsonUse this for tools every workspace may use.
Workspace MCP Server
my-project/
.agh/
config.toml
mcp.jsonUse this for tools that only make sense inside one project.
Agent MCP Server
~/.agh/agents/reviewer/
AGENT.md
mcp.jsonUse this when the tool belongs to one agent.
Skill MCP Server
~/.agh/skills/docs-search/
SKILL.md
mcp.jsonUse this when the tool belongs to one skill. Marketplace skill MCP servers are blocked unless the
skill is explicitly allowlisted in [skills].allowed_marketplace_mcp. Skill-local mcp.json
symlinks must resolve inside the skill directory; AGH rejects sidecars that escape the approved
skill root.
Related Pages
- config.toml documents top-level and provider MCP fields.
- Vault documents
env:versusvault:refs and redacted metadata management. - AGENT.md documents agent-local MCP declarations.
- SKILL.md documents skill-local MCP declarations.