MetaMCP
About
A self-hostable middleware to manage all your MCPs through a GUI and a local proxy, supporting multiple clients and workspaces.
Details
- Author
- metatool-ai
- Categories
- Developer Tools, Automation, Infrastructure, Productivity
Jump to
πEnvironment Variables & Secrets (STDIO MCP Servers)
ForSTDIO MCP servers, MetaMCP supports three ways to handle environment variables and secrets:
1. Raw Values- Direct string values (not recommended for secrets):
API_KEY=your-actual-api-key-here DEBUG=true
2. Environment Variable References- Use${ENV_VAR_NAME}syntax:
API_KEY=${OPENAI_API_KEY} DATABASE_URL=${DB_CONNECTION_STRING}
3. Auto-matching- If the expected environment variable name in your tool matches the container's environment variable, you can omit it entirely. MetaMCP will automatically pass through matching environment variables.
π Security Note: Environment variable references (${VAR_NAME}) are resolved from the MetaMCP container's environment at runtime. This keeps actual secret values out of your configuration and git repository.
βοΈ Development Note: For local development withpnpm run dev:docker, ensure your environment variables are listed inturbo.jsonunderglobalEnvto be passed to the development processes. This is not required for production Docker deployments.
- Group one or more MCP servers into a namespace
- Enable/disable MCP servers or at tool level
- Apply middlewares to MCP requests and responses
- Override tool names/titles/descriptions per namespace and attach custom MCP annotations (e.g.{ "annotations": { "readOnlyHint": false } })
- Create endpoints and assign namespace to endpoints
- Multiple MCP servers in the namespace will be aggregated and emitted as a MetaMCP endpoint
- Choose between API-Key Auth (in header or query param) or standard OAuth in MCP Spec 2025-06-18
- Host throughSSEorStreamable HTTPtransports in MCP andOpenAPIendpoints for clients like[Open WebUI
- Intercepts and transforms MCP requests and responses at namespace level
- Built-in example: "Filter inactive tools" - optimizes tool context for LLMs
- Future ideas: tool logging, error traces, validation, scanning
Similar to the official MCP inspector, but withsaved server configs- MetaMCP automatically creates configurations so you can debug MetaMCP endpoints immediately.
- Open a namespace βToolstab to see every tool coming from connected MCP servers.
- Each saved tool can be expanded and edited inline: update the displayname/title/descriptionor provide a JSON blob with namespace-specific annotations (for example{ "annotations": { "readOnlyHint": false } }).
- Badges in the table ("Overridden", "Annotations") show which tools currently have custom metadata. Hover them to read a tooltip describing what was overridden.
- Annotation overrides are merged with whatever the upstream MCP server returns, so you can safely add custom UI hints without losing provider metadata.
Clone repo, prepare.env, and start with docker compose:
git clone https://github.com/metatool-ai/metamcp.git cd metamcp cp example.env .env docker compose up -d
If you modify APP_URL env vars, make sure you only access from the APP_URL, because MetaMCP enforces CORS policy on the URL, so no other URL is accessible.
Note that the pg volume name may collide with your other pg dockers, which is global, consider rename it indocker-compose.yml:
volumes: metamcp_postgres_data: driver: local
π¦ Build development environment with Dev Containers (VSCode/Cursor)
You can use the VSCode/Cursor extension to build the development environment in a container.
It only requires that you have an environment running Docker or a similar alternative (thedocker/docker composecommand is required), and no other dependent components need to be installed on your host machine.
- First, clone the MetaMCP source code, open project in Visual Studio Code.
git clone https://github.com/metatool-ai/metamcp.git cd metamcp code .
- Switch to Dev Containers. Open the VSCode Command Palette, and executeDev Containers: Reopen in Container.
VSCode will open the Dev Containers project in a new window, where it will build the runtime and install the toolchain according to theDockerfilebefore starting the connection and finally installing the MetaMCP dependencies.
noteThis process requires a reliable network connection, and it will access Docker Hub, GitHub, and some other sites. You will need to ensure the network connection yourself, otherwise the container build may fail.
Wait some minutes, depending on the internet connection or computer performance, it may take from a few minutes to tens of minutes, you can click on the Progress Bar in the bottom right corner to view a live log where you will be able to check unusual stuck.
After finished, you can runpnpm devto start the development server.
Still recommend running postgres through docker for easy setup:
- β
Tools, Resources, and Promptssupported
- β
OAuth-enabled MCP serverstested for 03-26 version
If you have questions, feel free to leaveGitHub issuesorPRs.
{ "mcpServers": { "MetaMCP": { "url": "http://localhost:12008/metamcp/<YOUR_ENDPOINT_NAME>/sse" } } }
π MetaMCP (MCP Aggregator, Orchestrator, Middleware, Gateway in one docker)
π’ Latest Update:This ai-dev branch will be the forward onging dev branch which contains ai agent changes. Please test before you build the image based on this branch. There has been many PRs thanks to the community but merging and reviewing them has been a growing effort too. I decided to include ai changes. At least so far the core functionality works. There is also a community maintained fork (ty a lot!):https://github.com/Umbrella-IT-Group/metamcp
MetaMCPis a MCP proxy that lets you dynamically aggregate MCP servers into a unified MCP server, and apply middlewares. MetaMCP itself is a MCP server so it can be easily plugged intoANYMCP clients.
For more details, consider visiting our documentation site:https://docs.metamcp.com
- π― Use Cases
- π Concepts
- πEnvironment Variables & Secrets (STDIO MCP Servers)
- π³ Run with Docker Compose (Recommended)
- π¦ Build development environment with Dev Containers (VSCode/Cursor)
- π» Local Development
- π E.g., Cursor via mcp.json
- π₯οΈ Connecting Claude Desktop and Other STDIO-only Clients
- π§ API Key Auth Troubleshooting
- π οΈConfiguration
- π’Supported Providers
- πSecurity Features
- π±Usage
- ποΈAvailable Controls
- π’Enterprise Use Cases
- π οΈConfiguration
- π·οΈGroup MCP servers into namespaces, host them as meta-MCPs, and assign public endpoints(SSE or Streamable HTTP), with auth. One-click to switch a namespace for an endpoint.
- π―Pick tools you only need when remixing MCP servers.Apply otherpluggable middlewarearound observability, security, etc. (coming soon)
- πUse as enhanced MCP inspectorwith saved server configs, and inspect your MetaMCP endpoints in house to see if it works or not.
- πUse as Elasticsearch for MCP tool selection(coming soon)
Generally developers can use MetaMCP asinfrastructureto host dynamically composed MCP servers through a unified endpoint, and build agents on top of it.
Quick demo video:https://youtu.be/Cf6jVd2saAs
A MCP server configuration that tells MetaMCP how to start a MCP server.
"HackerNews": { "type": "STDIO", "command": "uvx", "args": ["mcp-hn"] }
πEnvironment Variables & Secrets (STDIO MCP Servers)
ForSTDIO MCP servers, MetaMCP supports three ways to handle environment variables and secrets:
1. Raw Values- Direct string values (not recommended for secrets):
API_KEY=your-actual-api-key-here DEBUG=true
2. Environment Variable References- Use${ENV_VAR_NAME}syntax:
API_KEY=${OPENAI_API_KEY} DATABASE_URL=${DB_CONNECTION_STRING}
3. Auto-matching- If the expected environment variable name in your tool matches the container's environment variable, you can omit it entirely. MetaMCP will automatically pass through matching environment variables.
π Security Note: Environment variable references (${VAR_NAME}) are resolved from the MetaMCP container's environment at runtime. This keeps actual secret values out of your configuration and git repository.
βοΈ Development Note: For local development withpnpm run dev:docker, ensure your environment variables are listed inturbo.jsonunderglobalEnvto be passed to the development processes. This is not required for production Docker deployments.
- Group one or more MCP servers into a namespace
- Enable/disable MCP servers or at tool level
- Apply middlewares to MCP requests and responses
- Override tool names/titles/descriptions per namespace and attach custom MCP annotations (e.g.{ "annotations": { "readOnlyHint": false } })
- Create endpoints and assign namespace to endpoints
- Multiple MCP servers in the namespace will be aggregated and emitted as a MetaMCP endpoint
- Choose between API-Key Auth (in header or query param) or standard OAuth in MCP Spec 2025-06-18
- Host throughSSEorStreamable HTTPtransports in MCP andOpenAPIendpoints for clients likeOpen WebUI
- Intercepts and transforms MCP requests and responses at namespace level
- Built-in example: "Filter inactive tools" - optimizes tool context for LLMs
- Future ideas: tool logging, error traces, validation, scanning
Similar to the official MCP inspector, but withsaved server configs- MetaMCP automatically creates configurations so you can debug MetaMCP endpoints immediately.
- Open a namespace βToolstab to see every tool coming from connected MCP servers.
- Each saved tool can be expanded and edited inline: update the displayname/title/descriptionor provide a JSON blob with namespace-specific annotations (for example{ "annotations": { "readOnlyHint": false } }).
- Badges in the table ("Overridden", "Annotations") show which tools currently have custom metadata. Hover them to read a tooltip describing what was overridden.
- Annotation overrides are merged with whatever the upstream MCP server returns, so you can safely add custom UI hints without losing provider metadata.
Clone repo, prepare.env, and start with docker compose:
git clone https://github.com/metatool-ai/metamcp.git cd metamcp cp example.env .env docker compose up -d
If you modify APP_URL env vars, make sure you only access from the APP_URL, because MetaMCP enforces CORS policy on the URL, so no other URL is accessible.
Note that the pg volume name may collide with your other pg dockers, which is global, consider rename it indocker-compose.yml:
volumes: metamcp_postgres_data: driver: local
π¦ Build development environment with Dev Containers (VSCode/Cursor)
You can use the VSCode/Cursor extension to build the development environment in a container.
It only requires that you have an environment running Docker or a similar alternative (thedocker/docker composecommand is required), and no other dependent components need to be installed on your host machine.
- First, clone the MetaMCP source code, open project in Visual Studio Code.
git clone https://github.com/metatool-ai/metamcp.git cd metamcp code .
- Switch to Dev Containers. Open the VSCode Command Palette, and executeDev Containers: Reopen in Container.
VSCode will open the Dev Containers project in a new window, where it will build the runtime and install the toolchain according to theDockerfilebefore starting the connection and finally installing the MetaMCP dependencies.
noteThis process requires a reliable network connection, and it will access Docker Hub, GitHub, and some other sites. You will need to ensure the network connection yourself, otherwise the container build may fail.
Wait some minutes, depending on the internet connection or computer performance, it may take from a few minutes to tens of minutes, you can click on the Progress Bar in the bottom right corner to view a live log where you will be able to check unusual stuck.
After finished, you can runpnpm devto start the development server.
Still recommend running postgres through docker for easy setup:
- β
Tools, Resources, and Promptssupported
- β
OAuth-enabled MCP serverstested for 03-26 version
If you have questions, feel free to leaveGitHub issuesorPRs.
{ "mcpServers": { "MetaMCP": { "url": "http://localhost:12008/metamcp/<YOUR_ENDPOINT_NAME>/sse" } } }
π₯οΈ Connecting Claude Desktop and Other STDIO-only Clients
Since MetaMCP endpoints are remote only (SSE, Streamable HTTP, OpenAPI), clients that only support stdio servers (like Claude Desktop) need a local proxy to connect.
Note:Whilemcp-remoteis sometimes suggested for this purpose, it's designed for OAuth-based authentication and doesn't work with MetaMCP's API key authentication. Based on testing,mcp-proxyis the recommended solution.
Here's a working configuration for Claude Desktop usingmcp-proxy:
{ "mcpServers": { "MetaMCP": { "command": "uvx", "args": [ "mcp-proxy", "--transport", "streamablehttp", "http://localhost:12008/metamcp/<YOUR_ENDPOINT_NAME>/mcp" ], "env": { "API_ACCESS_TOKEN": "<YOUR_API_KEY_HERE>" } } } }
{ "mcpServers": { "ehn": { "command": "uvx", "args": [ "mcp-proxy", "http://localhost:12008/metamcp/<YOUR_ENDPOINT_NAME>/sse" ], "env": { "API_ACCESS_TOKEN": "<YOUR_API_KEY_HERE>" } } } }
- Replace<YOUR_ENDPOINT_NAME>with your actual endpoint name
- Replace<YOUR_API_KEY_HERE>with your MetaMCP API key (format:sk_mt_...)
For more details and alternative approaches, see[issue #76.
- ?api_key=param api key auth doesn't work for SSE. It only works for Streamable HTTP and OpenAPI.
- Best practice is to use the API key inAuthorization: Bearer <API_KEY>header.
- Try disable auth temporarily when you face connection issues to see if it is an auth issue.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.


