Skip to main content
Glama
steelshot
by steelshot

mcp-aggregator

Builds a container image that presents any number of MCP servers to a local client as a single Streamable HTTP endpoint, collapsed behind the two tools that mcp-compress-router exposes: get_tool_schema and invoke_tool.

Agent clients cap the number of registered tools — 128 for GitHub Copilot CLI — and every registered tool consumes context. Routing servers through the compressor keeps them all reachable at a fixed cost of two tools.

Architecture

flowchart LR
	client["MCP client"]

	subgraph container["container"]
		sg["supergateway<br/>PID 1"]
		router["mcp-compress-router"]
		sg -->|stdio| router
	end

	gh["github<br/>http"]
	fs["filesystem<br/>stdio"]
	int["internal<br/>streamable-http"]
	client -->|" Streamable HTTP<br/>127.0.0.1:${PORT}/mcp "| sg
	router --> gh
	router --> fs
	router --> int
NOTE

Configuration is baked into the image at build time as build secrets, so a running container needs no host configuration beyond a state volume.

Related MCP server: MCP Proxy Server

Requirements

  • Node.js >= 24 with npm on the build host

  • Podman, or Docker as configured by build.engine

Versions

Field

Installed by

Contents

dependencies

the image, npm ci --omit=dev

supergateway, the router, and every downstream stdio server

devDependencies

the build host only

ajv and liquidjs, used by build.js

TIP

RECOMMENDED: Pin dependency versions exactly; take advantage of .npmrc which sets save-exact=true

Configuration

build.json is git-ignored and validated against build.schema.json on every run.

Key

Purpose

build.engine

podman or docker

build.name / build.tag

Image coordinates, overridable with the IMAGE_NAME environment variable

build.port

Streamable HTTP port, inside the container and on the host binding. Optional, default 20000

build.podman.generate_quadlet_unit

Emit a <name>.container systemd unit alongside the image

build.podman.description

Unit Description=. Optional, default Local MCP aggregate

build.podman.volumes

Extra Volume= entries. Optional

build.podman.environment

Extra Environment= entries as NAME=value. Optional

mcp.servers

Downstream servers, written verbatim into the router's mcp.json under mcpServers

mcp.oauth

Server names requiring an interactive login on the build host

A server is stdio and requires command, or http / streamable-http and requires url. Unknown fields pass through to mcp.json untouched, so router features absent from the schema still work. Recognized extras include compressionLevel, allowedTools and disabledTools (picomatch globs), and enabled.

IMPORTANT

Do not usenpx for stdio servers, which contacts the registry on every invocation even for an installed package, but instead define it as a dependency and let the Container build prefetch it for you.

{
	"$schema": "build.schema.json",
	"build": {
		"engine": "podman",
		"name": "mcp-aggregator",
		"tag": "latest",
		"podman": {
			"generate_quadlet_unit": true,
			"description": "MCP aggregate",
			"volumes": [
				"/srv/data:/data:ro"
			],
			"environment": [
				"TZ=Europe/Vilnius"
			]
		}
	},
	"mcp": {
		"servers": {
			"github": {
				"type": "http",
				"url": "https://api.githubcopilot.com/mcp/",
				"headers": {
					"Authorization": "Bearer ${GITHUB_MCP_PAT}"
				}
			},
			"filesystem": {
				"type": "stdio",
				"command": "mcp-server-filesystem",
				"args": [
					"/data"
				],
				"disabledTools": [
					"*write*",
					"*delete*"
				]
			},
			"internal": {
				"type": "streamable-http",
				"url": "${INTERNAL_MCP_URL}",
				"oauth": {
					"clientId": "${INTERNAL_CLIENT_ID}",
					"scope": "read"
				}
			}
		},
		"oauth": [
			"internal"
		]
	}
}

Placeholders

${VAR} and ${VAR:-default} in mcp.servers resolve against the environment, falling back to .env in the repository root. An unset placeholder without a default aborts the build.

Building

npm install
npm run build
flowchart TD
	bj["build.json"] --> val["validate against<br/>build.schema.json"]
	val --> exp["resolve placeholders<br/>from environment and .env"]
	exp --> mj["mcp.json<br/>temp file"]
	cache["credentials.json<br/>repository root"] --> gate{"tokens missing for<br/>any mcp.oauth server?"}
	gate -->|yes| login["interactive login<br/>on build host"]
	login --> cj["credentials.json<br/>temp file"]
	gate -->|no| cj
	mj --> rev["CONFIG_REVISION<br/>digest of both files"]
	cj --> rev
	rev --> eng["engine build<br/>with both files as secrets"]
	eng --> img["image"]
	eng --> unit["name.container unit"]

OAuth

Login runs on the build host, because the authorization-code flow needs a browser. Tokens are cached in credentials.json at the repository root; --login re-authorizes every server in mcp.oauth:

npm run login

Deploying

With generate_quadlet_unit enabled, a build renders quadlet.container.liquid to mcp-aggregator.container with LiquidJS:

mkdir -p ~/.config/containers/systemd
cp mcp-aggregator.container ~/.config/containers/systemd/
systemctl --user daemon-reload
systemctl --user start mcp-aggregator
IMPORTANT

supergateway exposes no health endpoint over Streamable HTTP, so the unit restarts the container when the process exits but cannot detect one that is running but unresponsive.

Connecting a client

http://127.0.0.1:20000/mcp
NOTE

The port followsbuild.port.

Licence

MIT © Džiugas Eiva

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Proxy that aggregates multiple MCP servers and presents them as a unified interface, allowing clients to access resources from multiple servers transparently.
    5
  • A
    license
    Not graded
    quality
    A
    maintenance
    Aggregates multiple MCP servers into a single HTTP endpoint with tool namespacing, dashboard, and REST API for management.
    30
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Aggregates multiple upstream MCP servers (stdio, streamable-http, sse, websocket) behind a single streamable-HTTP endpoint with declarative configuration, namespacing, filtering, and auto-reload.
    MIT

View all related MCP servers

Related MCP Connectors

  • AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.

  • Hosted Crawleo MCP (remote streamable HTTP endpoint).

  • Free remote MCP server for fetching public web pages through a rotating proxy pool.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steelshot/mcp-aggregator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server