Skip to main content
Glama
Jemplayer82

mcp-aggregator

by Jemplayer82
README.md
<p align="center"><img src="assets/fathom-header-banner.svg" alt="Fathom Works — mcp-aggregator" width="100%"></p>

# `$ mcp-aggregator`

**Gives your AI assistants one address that reaches all of your tools, instead of a dozen.** You list your tool servers once, and any assistant that connects here can use every one of them.

**In plain terms:** An MCP server is a plug-in that lets an AI assistant use a tool, such as search or smart-home control. If you run many of them, each new assistant needs a dozen settings copied in by hand. This project bundles them behind a single URL and a single password (token).

*A [Fathom Works](https://github.com/Jemplayer82) project.*

![protocol](https://img.shields.io/badge/protocol-MCP-6cd5e6?style=flat-square&labelColor=030d14)
![transport](https://img.shields.io/badge/transport-streamableHttp-6cd5e6?style=flat-square&labelColor=030d14)
![dependencies](https://img.shields.io/badge/dependencies-1-2ecc71?style=flat-square&labelColor=030d14)
![image](https://img.shields.io/badge/image-ghcr.io-6cd5e6?style=flat-square&labelColor=030d14&logo=docker&logoColor=6cd5e6)
![license](https://img.shields.io/badge/license-AGPL--3.0-6cd5e6?style=flat-square&labelColor=030d14)

- Every tool name gets its backend as a prefix, so nothing collides. Tool `list_vms` on backend `proxmox` shows up as `proxmox__list_vms`.
- One backend being down, slow, or misconfigured never breaks the others.
- Tool lists refresh on an interval, so backends can add or remove tools without a restart.
- A REST side-channel (`/api/servers`, `/api/servers/:id/tools`) exposes live health and per-backend tool lists for anything that wants to build on top of this, such as a catalog page or a dashboard.

> [!IMPORTANT]
> This is the source of truth for "what MCP servers exist." Anything that wants a live catalog — a store UI, a dashboard — should read `/api/servers` from here, not the other way around.

## `[ quick start ]`

Download the project, copy the example settings, and start it with Docker.

```bash
$ git clone https://github.com/jemplayer82/mcp-aggregator && cd mcp-aggregator
$ cp config.example.json config.json     # edit with your real backend URLs
$ cp .env.example .env                    # fill in tokens for backends that need them
$ docker compose up -d
$ docker compose logs mcp-aggregator      # shows the auto-generated aggregator token
```

Check that it is running.

```bash
$ curl -sf http://localhost:3117/healthz
# → {"ok":true}
```

Point any MCP client at `http://your-host:3117/mcp` with the printed bearer token, and it has every enabled backend's tools.

## `[ usage ]`

- **Connect an assistant:** give it the `/mcp` URL above and the aggregator token.
- **Check on your backends:** request `/api/servers` to see which are connected, how many tools each has, and the last error.
- **See one backend's tools:** request `/api/servers/:id/tools` for its raw, unprefixed tool list.
- **Pause a backend:** set `"enabled": false` on its entry in `config.json`.

All endpoints except `/healthz` need `Authorization: Bearer <AGGREGATOR_MCP_TOKEN>`.

| endpoint | method | what |
|---|---|---|
| `/healthz` | GET | liveness, unauthenticated |
| `/mcp` | GET/POST | the aggregated MCP server — streamable-HTTP, stateless per request |
| `/api/servers` | GET | JSON status of every configured backend: connected, tool count, last error |
| `/api/servers/:id/tools` | GET | raw (unnamespaced) tool list for one backend |

## `[ configuration ]`

Your backends are listed in `config.json`. Each entry takes these fields (full table and example in [docs/configuration.md](docs/configuration.md)).

| field | required | what it does |
|---|---|---|
| `id` | yes | short name; lowercase letters, numbers, hyphens, no underscores |
| `name` | no | display name, defaults to `id` |
| `url` | yes | the backend's MCP address, ending in `/mcp` |
| `enabled` | no | `false` keeps the entry without connecting |
| `authEnv` | no | name of the env var holding the backend's token (the token lives in `.env`) |

`config.json` and `.env` are gitignored. Only `config.example.json` and `.env.example` are tracked.

## `[ docs ]`

- [docs/configuration.md](docs/configuration.md) — every `config.json` field, with an example.
- [docs/deployment.md](docs/deployment.md) — running more than one instance, known backend issues, and how this differs from mcp-switchboard.
- [CONTRIBUTING.md](./CONTRIBUTING.md) — how to contribute.

## `[ license ]`

[GNU Affero General Public License v3.0](./LICENSE).

<img src="assets/fathom-footer-banner.svg" alt="Fathom Works — sound the depths before you set a course" width="100%">

Maintenance

ActivityMaintained
ResponsivenessNo issues