Skip to content
This page is a translation of the authoritative Chinese source and may lag behind.View the original

Proxying external tools with MCP

The MCP (Model Context Protocol) gateway aggregates external tool servers into a single entry point: callers use one gateway access key to call multiple tools, and it supports tool ACLs and context budgets per key group. This chapter walks you through adding an external MCP server (a filesystem MCP example) and calling it from Claude Desktop via the gateway's /mcp endpoint to see the tools proxied.

What you'll build

  • An external MCP server connected to the gateway (e.g. filesystem MCP)
  • A gateway access key that can call the gateway from any MCP client
  • Call tools via the gateway from Claude Desktop and see the tool list + call results

Prerequisites

  • The gateway is running (http://localhost:7890) and you can log in to the Console

  • ENCRYPTION_KEY is set — the access key saved below is encrypted before being stored; if it's not set, saving reports encryption_key not set in config. See Docker single node → Prerequisites

  • A running external MCP server using streamable HTTP or SSE transport (the example below uses http://localhost:8000/mcp).

    The gateway does not support stdio / command / args / env / OAuth style MCP servers — only streamable HTTP / SSE / REST-bridge transports. The official @modelcontextprotocol/server-* packages are mostly stdio and cannot be connected directly.

    No ready-made HTTP MCP server? Wrap a stdio server into streamable HTTP with a bridge tool. For example, use supergateway to bridge the filesystem server (one command starts it on port 8000 at path /mcp, matching the example below):

    bash
    npx -y supergateway \
      --stdio "npx -y @modelcontextprotocol/server-filesystem /tmp" \
      --outputTransport streamableHttp

    Once started, the endpoint is http://localhost:8000/mcp. It's the same with other HTTP/SSE MCP servers — just replace the endpoint below with its actual address.

1. Add an MCP server

Console → MCP ServersNew:

FieldValueDescription
NamefilesUnique; used as the tool prefix, regex ^[a-z0-9][a-z0-9_-]*$
Descriptionfilesystem MCPFor UI display
Transport (transport)streamable_httpOr sse
Connection type (connection_type)statelessStateless tool server
Endpoint (endpoint)http://localhost:8000/mcpThe upstream tool server URL (for streamable HTTP, fill in the specific path)
Auth header (auth_header)(leave empty if the upstream MCP requires no auth)The upstream Authorization header (e.g. Bearer ...)
Tags (tags)["dev-tools"]Coarse-grained ACL filtering
Priority (priority)00–999, smaller = higher priority; used for context-budget trimming
Idle timeout (idle_timeout_secs)300Default 300
Deferred loading (defer_loading)false (default)Set to true to load the tool schema only on first call
Health check (health_check)(optional) e.g. { "path": "/health", "interval_secs": 60, "timeout_secs": 5 }Probes liveness periodically when configured. path must be an endpoint the upstream actually provides — if the upstream has no /health but you set it, probes keep failing, the server is judged dead, and its tools become invisible. Leave empty if unsure
Concurrency cap (max_concurrency)(as needed)Per-access-key concurrency cap for this server
Rate limit (rate_limit)(as needed)requests_per_second / tokens_per_minute
Enabled

Save. The tool name format is {server_name}.{tool_name}, e.g. files.read_file, files.list_directory.

2. Configure the key group's MCP ACL

Tool permissions are configured in the key group's mcp_tool_acl (not on the MCP server). Console → Access KeysKey Groups → Edit → MCP sub-tab (shown only when at least one MCP server exists):

FieldValue
allowed_tools["files.*"] (allow all tools of the files server)
denied_tools(leave empty)
allowed_tags(leave empty)
json
{
  "name": "default",
  "models": ["*"],
  "mcp_tool_acl": {
    "allowed_tools": ["files.*"],
    "denied_tools": []
  }
}

ACL evaluation order: denied (highest) → allowed_toolsallowed_tags → default. The "default" at the end is allow: when both allowed_tools and allowed_tags are empty, anything not hit by denied_tools is allowed; once any allow list is configured, it switches to whitelist mode, allowing only hits.

3. Issue an access key

Console → Access KeysNew:

FieldValueDescription
Namemy-mcp-keyThe key's identifier, used for management and audit
API keyClick "Generate"Auto-generates a string; the credential clients send when calling
GroupdefaultDetermines which models this key can access
Enabled

4. Call from Claude Desktop

Claude Desktop's MCP configuration (macOS path ~/Library/Application Support/Claude/claude_desktop_config.json):

json
{
  "mcpServers": {
    "gatellm": {
      "url": "http://localhost:7890/mcp",
      "headers": {
        "Authorization": "Bearer <your access key>"
      }
    }
  }
}

Restart Claude Desktop and ask Claude in the chat to "list the /tmp directory"; Claude will automatically call the files.list_directory tool, and the gateway proxies the request to the upstream MCP server.

5. Or use the Python mcp SDK

python
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client(
        "http://localhost:7890/mcp",
        headers={"Authorization": "Bearer <your access key>"}
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print([t.name for t in tools.tools])
            result = await session.call_tool("files.list_directory", {"path": "/tmp"})
            print(result)

asyncio.run(main())

JSON-RPC methods

The gateway's /mcp endpoint supports:

MethodDescription
initializeHandshake, exchange capabilities
tools/listList available tools (filtered by that key group's MCP ACL), including the built-in search_tools meta-tool
tools/callCall a tool, named as {server_name}.{tool_name}
tools/searchBM25 keyword search over tools (for locating when there are many tools)

FAQ

Q: Claude Desktop doesn't show the tool list? Check: ① whether the MCP server is enabled; ② whether defer_loading is on (the schema loads only on first call, so you need to trigger a tools/list); ③ whether the key group's mcp_tool_acl filtered it out; ④ whether the upstream MCP server is actually alive; ⑤ if health_check is configured, whether path is a real upstream endpoint — if you set a path the upstream doesn't have, probes keep failing, the server is judged dead, and its tools become invisible (leave health_check empty if unsure).

Q: Tool calls often time out? Adjust that server's max_concurrency (concurrency cap) and rate_limit, or check the upstream MCP server's own response speed. Each MCP server has independent circuit-breaker protection — consecutive failures trip the breaker and pause forwarding to that server (not "temporarily open"), and it's automatically allowed again after health recovers.

Q: What does the . prefix in a tool name (e.g. files.read_file) mean? It's the two-part {server_name}.{tool_name} naming, avoiding collisions between same-named tools of different servers.

Q: How do I make a key group unable to use MCP at all? In the key group's MCP sub-tab, leave allowed_tools empty and allowed_tags empty, or don't check any tools.

Q: If an MCP server goes down, does it affect other tools? No. Each server has independent connection management and circuit-breaker protection. When one server is unavailable, its tools are excluded from the list and other servers keep working.

Next: Onboard an external MCP server for the full operations (add/list/detail/delete); MCP configuration for tool ACL, context budget, REST bridge, and other field details; Endpoints · auth · protocol interop for the full endpoint list.