Child MCP servers
Agents can use named child MCP servers, declared in YAML frontmatter.
Two transport types are supported:
stdio
httpstdio child MCP
mcp_servers:
filesystem:
type: stdio
command: tuls
args: ["filesystem", ".", "--allow", "filesystem.read"]The child process:
- runs locally as a direct exec of
command, with the OS identity of thetulsprocess; - starts in the agent workspace;
- has
kill_on_dropenabled; - receives a minimal inherited environment;
- does not implicitly inherit unrelated credentials;
- uses MCP
2026-07-28discovery.
Explicit child environment
If a child MCP server itself needs a credential, pass only that credential:
mcp_servers:
external:
type: stdio
command: external-mcp
args: ["serve"]
env: { EXTERNAL_API_KEY: "${EXTERNAL_API_KEY}" }${NAME} placeholders selectively expose individual variables from the tuls agents process environment to the child; nothing else is inherited. A missing variable fails the child startup.
HTTP child MCP
mcp_servers:
issues:
type: http
url: https://mcp.example.com/mcp
headers: { Authorization: "Bearer ${ISSUE_MCP_TOKEN}" }HTTP child MCP clients use bounded timeouts and do not follow redirects. Header values support the same ${NAME} environment interpolation.
Child tool selectors
Selector format:
server/tool
server/*Example:
tools:
- filesystem/read_text_file
- filesystem/search_files
- fetch/*
disallowed_tools:
- fetch/some_tool_nameSelector rules
- Empty
toolsmeans no child MCP tools (default deny). server/*grants all tools advertised by that named child server.server/toolgrants one exact child tool.disallowed_toolsalways overridestools.- A selector referencing an unknown configured server is rejected.
- After connection, an exact selector referencing a tool not actually advertised by that child server is rejected.
- Authorization is based on this explicit policy, not child-provided read-only/destructive annotations.
- A child tool's reported
isErroris preserved and committed to the agent conversation as an error output; the run continues. - A call that times out or fails after dispatch has an ambiguous outcome (the tool may have executed) and the session is marked non-resumable.
- Completed sessions are resumable:
send_inputon a completed agent starts a new run that continues the retained conversation.
Defense in depth
For built-in child servers, restrict both layers.
Good:
tools:
- filesystem/*
mcp_servers:
filesystem:
type: stdio
command: tuls
args: ["filesystem", ".", "--allow", "filesystem.read"]This means:
- the child filesystem process itself exposes only read operations;
- the agent policy grants only tools from that child server.
Don't rely on one layer for high-risk tools
For high-risk tools, restrict the child process and the agent policy. Do not rely on only one of those layers.
Related
- Agent configuration — the
tools/disallowed_toolsfields. - Agent profiles — layered example profiles.