Summary
When a project declares MCP servers in its config, praisonai run wires at most one of them: only the first enabled local (stdio) server is used, additional local servers are dropped with a warning, and remote/URL servers are ignored entirely. A project that configures, say, a Postgres MCP server plus a remote HTTP MCP server gets only the first stdio one on the primary CLI path — the rest of its declared capabilities are invisible to the agent. Configured MCP servers should all be available to the run.
Current behaviour
In src/praisonai/praisonai/cli/commands/run.py:
_mcp_server_to_command(server) returns None for any server with type == "remote" or a url ("Only local (stdio) servers map to the command-string CLI path"), so remote MCP servers are silently unsupported on the run path.
_resolve_mcp_from_config(...) iterates enabled servers but keeps only the first (if selected is None: selected = result) and emits a warning: "Multiple enabled local MCP servers found … only '' will be used via the run command path." (run.py ~lines 150–168).
The root cause is that the run path threads MCP through a single --mcp command-string, which structurally cannot represent multiple servers or remote transports — even though the SDK itself supports multiple and remote MCP servers.
Desired behaviour
praisonai run makes all enabled MCP servers from project config available to the agent — multiple local stdio servers and remote/URL servers (with headers/auth) — not just the first stdio one.
- The "only the first will be used" warning is removed once aggregation works.
Layer placement
- Primary layer: wrapper
- Why not core: the core SDK already supports multiple and remote MCP servers; the bottleneck is the wrapper's single-
--mcp-string run path.
- Why not wrapper: n/a — this is the wrapper gap.
- Why not tools: MCP server orchestration is CLI/config wiring, not a single agent-callable tool.
- Why not plugins: it is core run-command configuration, not an optional lifecycle hook.
- Secondary touch (optional): none required if the run path passes a structured server list straight to the existing core MCP client.
- 3-way surface (CLI + YAML + Python): yes — CLI (
praisonai run), YAML (mcp.servers map with local + remote entries), Python (Agent MCP configuration).
Proposed approach
- Replace the single-server
_resolve_mcp_from_config collapse with collection of all enabled servers (local and remote).
- Pass a structured list of server configs into the agent's MCP setup instead of a single command string, so the existing core MCP client handles stdio and remote (URL + headers/OAuth) transports.
- Allow
--mcp to be supplied multiple times for ad-hoc additions, merged with config-declared servers.
- Remove the "only the first will be used" warning once aggregation lands.
Resolution sketch
# run.py (sketch) — collect all, not just the first
servers = [s for name, s in cfg.mcp.servers.items() if s.get("enabled", True)]
# stdio + remote both retained; hand the structured list to the core MCP client
agent_mcp = build_mcp_clients(servers) # local stdio AND url/remote transports
This removes _mcp_server_to_command's remote return None path and the single-selected collapse in _resolve_mcp_from_config.
Severity
Medium-High — multi-server and remote MCP setups are increasingly common in production; today they fail silently on the primary CLI path, which is a correctness/discoverability problem, not just a convenience gap.
Validation
- Remote servers dropped:
src/praisonai/praisonai/cli/commands/run.py — _mcp_server_to_command returns None when server.get("type") == "remote" or server.get("url").
- Extra local servers dropped with a warning:
run.py _resolve_mcp_from_config (if selected is None: selected = result; "only '' will be used") ~lines 150–168.
- Real agentic test: a project config with two enabled local MCP servers (and one remote) should let
praisonai run "use both MCP toolsets" call tools from every configured server, not just the first.
Summary
When a project declares MCP servers in its config,
praisonai runwires at most one of them: only the first enabled local (stdio) server is used, additional local servers are dropped with a warning, and remote/URL servers are ignored entirely. A project that configures, say, a Postgres MCP server plus a remote HTTP MCP server gets only the first stdio one on the primary CLI path — the rest of its declared capabilities are invisible to the agent. Configured MCP servers should all be available to the run.Current behaviour
In
src/praisonai/praisonai/cli/commands/run.py:_mcp_server_to_command(server)returnsNonefor any server withtype == "remote"or aurl("Only local (stdio) servers map to the command-string CLI path"), so remote MCP servers are silently unsupported on the run path._resolve_mcp_from_config(...)iterates enabled servers but keeps only the first (if selected is None: selected = result) and emits a warning: "Multiple enabled local MCP servers found … only '' will be used via the run command path." (run.py ~lines 150–168).The root cause is that the run path threads MCP through a single
--mcpcommand-string, which structurally cannot represent multiple servers or remote transports — even though the SDK itself supports multiple and remote MCP servers.Desired behaviour
praisonai runmakes all enabled MCP servers from project config available to the agent — multiple local stdio servers and remote/URL servers (with headers/auth) — not just the first stdio one.Layer placement
--mcp-string run path.praisonai run), YAML (mcp.serversmap with local + remote entries), Python (Agent MCP configuration).Proposed approach
_resolve_mcp_from_configcollapse with collection of all enabled servers (local and remote).--mcpto be supplied multiple times for ad-hoc additions, merged with config-declared servers.Resolution sketch
This removes
_mcp_server_to_command's remotereturn Nonepath and the single-selectedcollapse in_resolve_mcp_from_config.Severity
Medium-High — multi-server and remote MCP setups are increasingly common in production; today they fail silently on the primary CLI path, which is a correctness/discoverability problem, not just a convenience gap.
Validation
src/praisonai/praisonai/cli/commands/run.py—_mcp_server_to_commandreturnsNonewhenserver.get("type") == "remote" or server.get("url").run.py_resolve_mcp_from_config(if selected is None: selected = result; "only '' will be used") ~lines 150–168.praisonai run "use both MCP toolsets"call tools from every configured server, not just the first.