Gateway MCP Servers

Declare downstream MCP servers once; every gateway agent that lists the name gets a shared, pooled client

Next

Declare downstream MCP servers once at the gateway and every agent that lists the server name gets the same pooled, shared client — not N connections per server.

Diagram

🤖 support

🔌 pooled MCP client

🤖 triage

🤖 billing

🛠️ github MCP server

Quick Start

  1. One stdio server, two agents
    yaml
    # gateway.yaml
    mcp_servers:
      github:
        command: npx
        args: ["-y", "@modelcontextprotocol/server-github"]
    
    agents:
      support:
        instructions: "Help users file GitHub issues."
        model: gpt-4o-mini
        tools: [github]
      triage:
        instructions: "Label and route incoming issues."
        model: gpt-4o-mini
        tools: [github]

    One npx process serves both agents.

  2. Mix stdio and HTTP servers
    yaml
    mcp_servers:
      github:
        command: npx
        args: ["-y", "@modelcontextprotocol/server-github"]
      search:
        url: https://mcp.example.com/sse
        headers:
          Authorization: Bearer ${SEARCH_MCP_TOKEN}
    
    agents:
      support:
        instructions: "Answer questions using GitHub and web search."
        tools: [github, search]
  3. String shorthand for a local binary
    yaml
    mcp_servers:
      files: /usr/local/bin/filesystem-mcp
    
    agents:
      librarian:
        instructions: "Find and summarise local documents."
        tools: [files]

Start the gateway with your config:

bash
praisonai gateway start --config gateway.yaml

How It Works

Diagram
AgentMCP clientMCP poolWebSocketGatewaygateway.yamlAgentMCP clientMCP poolWebSocketGatewaygateway.yamlalt[first time]mcp_servers: { github: {…} }get pooled client(“github”, spec)MCP(command, **opts).with_tool_prefix(“github”)clientshared clientAgent(tools=[…, shared client])

Every agent that lists the server name walks the same path and lands on the same client.


Configuration

Each key under mcp_servers: is the server’s name (also its tool-name prefix), and the value is its spec.

ShapeRequiredOptionalNotes
stdio mappingcommandargs, env, any other praisonaiagents.MCP keywordLaunches a stdio MCP server.
HTTP mappingurlheaders, any other praisonaiagents.MCP keywordOpens an HTTP/SSE MCP connection.
String shorthandthe whole value—Treated as {"command": "<string>"}.

Referencing a server from an agent

List the server name in an agent’s tools: to attach the pooled client.

yaml
agents:
  support:
    tools: [github, internet_search]   # MCP server + built-in tool

Names that are not in mcp_servers: fall through to the normal tool resolver, so built-in tools work alongside MCP servers.

Tool-name namespacing

Tools from a server named github are exposed as github_<tool>, so two servers that each offer a search tool never shadow each other.


Hot Reload

The pool keys each client by name and spec, so a reload only reconnects what changed.

Change in gateway.yamlWhat happens
Spec unchangedPooled client reused — no reconnect.
Spec changedNew client opened; the old one is shut down on prune.
Entry removedClient is shut down on the next reload prune.
Entry addedClient opened off the event loop, so serving is not blocked by the startup handshake.

Failure Modes

  • Bad spec (no command and no url) — logged, skipped, gateway continues.
  • Server fails to start — logged, skipped, gateway continues; the agent still registers without that server’s tools.
  • stdio server dies mid-session — the core praisonaiagents.MCP client restarts it on the next call.
  • Gateway stops — every pooled client is shut down.

Security

MCP tools from mcp_servers: run through the agent’s normal tool path, so existing tool policy and approval checks still apply.


Configuration Options


Best Practices

Declare each server once

Put every downstream server under mcp_servers: and reference it by name — never repeat the spec per agent.

Keep server names short and lowercase

The name becomes the tool prefix (github_create_issue), so short names keep tool names readable.

Keep secrets in environment variables

Use ${TOKEN} in env and headers instead of pasting credentials into the YAML.

Watch the logs on boot

A failing server does not stop the gateway — look for Failed to start MCP server warnings.


Related