byteforge-aegis-mcp
A read-only MCP server that exposes ByteForge Aegis admin API tools to query production configuration (sites, users, health) without any mutation risk.
README
byteforge-aegis-mcp
A read-only MCP server over the ByteForge Aegis admin API, deployed as a container behind nginx with Gatekeeper auth.
Why
Agents working on Aegis and on tenant integrations repeatedly need to answer
"what is actually configured in production?" — is the webhook URL set, is
allow_self_registration on, which sites exist, does this user exist. Before
this server that question was answered with hand-rolled curls carrying the
master API key, or not answered at all — a tenant provisioning request was
once signed off partly on assertion, because the site config could not be
read back.
Read-only by construction
Every tool maps to a GET. The Aegis client this wraps also exposes
create_site, update_site, delete_site, delete_user and friends — none
are reachable here, and none should be added. The value of this server is
that it can be handed to an agent with no possibility of changing production
state. A mutating server, if ever wanted, belongs in a separate and
separately-authorized deployment.
Tools
| Tool | What it answers |
|---|---|
aegis_health |
Which build is live (status, service, version) |
aegis_list_sites |
Every tenant on the instance, with secrets |
aegis_get_site |
One site's full config, by UUID or domain |
aegis_list_users |
All users on a site |
aegis_find_user |
One user on a site, by email (case-insensitive) |
aegis_get_site and aegis_list_users accept a domain as well as a UUID.
The admin API addresses sites by UUID only (utils/identifiers.py
resolve_site rejects non-UUIDs), so a domain is resolved through the public
by-domain lookup first — callers almost always know the domain, not the
UUID.
Secrets in responses
Site reads include tenant_api_key, webhook_secret and mailgun_api_key
in full. This was a deliberate choice by @jmazzahacks over returning presence
booleans. The consequence: anything read here lands in the calling agent's
transcript, so responses should not be pasted into tickets or other shared
surfaces. AEGIS_MASTER_API_KEY spans every site on the instance.
Configuration
| Variable | Purpose |
|---|---|
AEGIS_API_URL |
Aegis instance to read (e.g. https://aegis.example.com) |
AEGIS_MASTER_API_KEY |
Master key. Spans every site |
MCP_TRANSPORT |
stdio for local dev, streamable-http in Docker |
FASTMCP_HOST / FASTMCP_PORT |
Bind address. FastMCP reads these specifically |
See example.env.
Local development
uv venv --python 3.13 .venv
source .venv/bin/activate
uv pip install -r requirements.txt
AEGIS_API_URL=https://aegis.example.com \
AEGIS_MASTER_API_KEY=... \
MCP_TRANSPORT=stdio \
python aegis_mcp_server.py
The venv lives in .venv/ rather than at the repo root as the sibling Aegis
repos do — uv venv refuses to create one in a non-empty directory.
To exercise it over the wire the way it is deployed:
MCP_TRANSPORT=streamable-http FASTMCP_HOST=127.0.0.1 FASTMCP_PORT=8931 \
AEGIS_API_URL=... AEGIS_MASTER_API_KEY=... python aegis_mcp_server.py &
curl -s -X POST http://127.0.0.1:8931/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
A tools/list that succeeds without a preceding initialize is the
signal that stateless mode is on.
Build and publish
./build-publish.sh # or --no-cache
Publishes ghcr.io/jmazzahacks/byteforge-aegis-mcp:<n> and :latest, then
advances VERSION. VERSION is gitignored and owned entirely by the script —
never edit it by hand.
Unlike byteforge-aegis, this image does not bake VERSION into itself,
so the script's write-after-build ordering is correct here. If a version
endpoint is ever added, the write must move to before docker build or
every image will report one version behind.
Deployment
Runs behind an mcp.<domain> umbrella vhost with Gatekeeper
auth_request auth. See nginx-mcp-aegis.conf for the location block. The
container publishes no host port — nginx reaches it by container name on the
shared docker network, which matters because the master key makes direct
exposure unacceptable.
Transport
streamable-http with stateless_http=True. Not SSE: when Claude Code's
long-lived SSE GET dies it reconnects without re-running initialize, the
server sees tools/call first, and the resulting -32602 wedges the client
until a manual /mcp reload. Stateless streamable-http has no per-session
state to lose, so that failure is structurally impossible.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.