4.7 KiB
pyMCPBroker Specification
Purpose
pyMCPBroker exposes a very small stable API to a language model while
wrapping one or more MCP servers running over stdio.
The model never sees raw MCP tools directly. It only sees three stable meta-tools:
meta_treemeta_descmeta_call
Normal workflow:
- call
meta_treeto navigate - call
meta_descon a leaf path - call
meta_callwith arguments matching the schema returned bymeta_desc
Terminology
- entry: logical element exposed to the model
type=node: navigation nodetype=tool: callable leaf- path: stable absolute URL-like identifier
- source: real MCP backend mounted on a node
backend=stdio: MCP process launched locally over stdin/stdout
Public API
POST /meta_tree
Input:
{
"path": "/"
}Returns the direct children of a node path.
Errors if the path does not exist or if it points to a tool leaf.
POST /meta_desc
Input:
{
"path": "/repo/read/get_file"
}For a node path, returns node metadata and optionally summarized children.
For a tool path, returns:
- stable path
- summary
- description
- exact
args_schema - optional
example_args
POST /meta_call
Input:
{
"path": "/repo/read/get_file",
"args": {
"owner": "myorg",
"repo": "demo-repo",
"ref": "main",
"filePath": "README.md"
}
}The broker validates args against the dynamic schema
previously returned by meta_desc, then calls the real MCP
tool.
Config format
The config is static JSON loaded at startup.
Top-level shape:
{
"tree": [ ... ]
}or:
{
"tree": {
"path": "/",
"type": "node",
"children": [ ... ]
}
}The explicit root node is optional. If omitted, / is
created implicitly.
Node fields
pathtype="node"summaryoptionaldescriptionoptionalchildrenoptionalsourceoptional
Source fields
backend: currently only"stdio"command: shell command to launch the MCP servertool_filter: optional unordered list of allow/deny glob patternstool_overrides: optional per-tool overridespath_aliases: optional mapping from real MCP tool name to exposed leaf name
Environment variables
${ENV_VAR} substitution is supported in strings,
especially in command.
Missing variables fail at startup.
Source mounting model
A source mounted on a node causes the broker to:
- start the MCP process
- initialize the MCP session
- fetch
tools/list - apply
tool_filter - apply
tool_overrides - expose the remaining tools as child leaves under the node path
The exposed leaf path is:
parent_path + / + alias, ifpath_aliasesdefines one- otherwise
parent_path + / + tool_name
Example:
- node path:
/repo/read - real tool:
get_file_contents - alias:
get_file - exposed path:
/repo/read/get_file
Filter semantics
tool_filter is optional.
Positive patterns allow tools. Patterns prefixed with !
deny tools.
Rules:
- if there is no positive pattern, all tools are allowed first, then deny rules are applied
- if at least one positive pattern exists, only tools matching a positive pattern are allowed, then deny rules are applied
- pattern order does not matter
Examples:
[]→ expose all tools["!delete_*"]→ expose everything except delete tools["get_*", "list_*"]→ expose only get/list tools["get_*", "!get_secret_*"]→ expose get tools except secret ones
Overrides
tool_overrides is optional.
Supported fields:
summarydescriptionmax_output_charstimeoutexample_argsrender_mode
They only affect the broker-facing presentation and execution limits. They do not rename the real MCP tool.
Output normalization
The broker can truncate large outputs using
max_output_chars.
Current behavior:
- preserve JSON structure when possible
- truncate long strings first
- compact long lists if needed
- return an explicit wrapper when truncation happened
Internal MCP support
Current transport support:
- MCP
stdioonly
Required MCP methods:
initializetools/listtools/call
The broker also sends notifications/initialized after
initialization.
CLI
python -m pyMCPBroker 0.0.0.0:8100 /config.jsonOptional shared secret:
python -m pyMCPBroker 0.0.0.0:8100 /config.json mysecretAccepted options:
--reload--ignore-broken-tool--log-level--dump-tree
Repository editor config
The repository may include a .vscode/ directory with
recommended Python extensions plus launch/task settings for pytest and
for starting the broker against smoke_config.json. This
editor config is optional and does not affect runtime behavior.