[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-73882":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":42,"readmeContent":43,"aiSummary":44,"trendingCount":16,"starSnapshotCount":16,"syncStatus":45,"lastSyncTime":46,"discoverSource":47},73882,"metamcp","metatool-ai\u002Fmetamcp","metatool-ai","MCP Aggregator, Orchestrator, Middleware, Gateway in one docker","https:\u002F\u002Fdocs.metamcp.com",null,"TypeScript",2400,355,22,86,0,18,37,85,54,29.65,"MIT License",false,"main",true,[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"mcp","mcp-gateway","mcp-host","mcp-middleware","mcp-server","mcp-servers","mcp-to-openapi","mcp-tools","model-context-protocol","model-context-protocol-server","model-context-protocol-servers","open-webui","openapi","self-hosted","vibe-coding","2026-06-12 02:03:19","# 🚀 MetaMCP (MCP Aggregator, Orchestrator, Middleware, Gateway in one docker) \u003C!-- omit in toc -->\n\n\u003Cdiv align=\"center\">\n\n\u003Cdiv align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FmNsyat7mFX\" style=\"text-decoration: none;\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-MetaMCP-5865F2?style=flat-square&logo=discord&logoColor=white\" alt=\"Discord\" style=\"max-width: 100%;\">\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fdocs.metamcp.com\" style=\"text-decoration: none;\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDocumentation-docs.metamcp.com-blue?style=flat-square&logo=book\" alt=\"Documentation\" style=\"max-width: 100%;\">\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT\" style=\"text-decoration: none;\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg?style=flat-square\" alt=\"MIT License\" style=\"max-width: 100%;\">\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmetatool-ai\u002Fmetamcp\u002Fpkgs\u002Fcontainer\u002Fmetamcp\" style=\"text-decoration: none;\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FGHCR-available-green.svg?style=flat-square&logo=github\" alt=\"GHCR\" style=\"max-width: 100%;\">\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fdeepwiki.com\u002Fmetatool-ai\u002Fmetamcp\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDeepWiki-metatool--ai%2Fmetamcp-blue.svg?style=flat-square&logo=data:image\u002Fpng;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK\u002FAIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06\u002Fuv1saEDv4O3n3dV60RfP947Mm9\u002FSQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH\u002F\u002FPB8mnKqScAhsD0kYP3j\u002FYt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY\u002F56ebRWeraTjMt\u002F00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB\u002FimwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h\u002FU4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5\u002FXFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb\u002FvA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26\u002FHfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr\u002FFGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r\u002FcKaoqr+27\u002FXcrS5UwSMbQAAAABJRU5ErkJggg==\" alt=\"DeepWiki: MetaMCP\">\u003C\u002Fa>\n\u003C\u002Fdiv>\n\n\u003C\u002Fdiv>\n\n> **📢 Update:** *[From the author: apologize for some recent maintainence delay, but will at least keep merging PRs, more background [here](recent-updates.md)]*\n\n**MetaMCP** is 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 into **ANY** MCP clients.\n\n![MetaMCP Diagram](metamcp.svg)\n\n---\n\nFor more details, consider visiting our documentation site: https:\u002F\u002Fdocs.metamcp.com\n\nEnglish | [中文](.\u002FREADME_cn.md)\n## 📋 Table of Contents \u003C!-- omit in toc -->\n\n- [🎯 Use Cases](#-use-cases)\n- [📖 Concepts](#-concepts)\n  - [🖥️ **MCP Server**](#️-mcp-server)\n    - [🔐 **Environment Variables \\& Secrets (STDIO MCP Servers)**](#-environment-variables--secrets-stdio-mcp-servers)\n  - [🏷️ **MetaMCP Namespace**](#️-metamcp-namespace)\n  - [🌐 **MetaMCP Endpoint**](#-metamcp-endpoint)\n  - [⚙️ **Middleware**](#️-middleware)\n  - [🔍 **Inspector**](#-inspector)\n  - [✏️ **Tool Overrides \\& Annotations**](#️-tool-overrides--annotations)\n- [🚀 Quick Start](#-quick-start)\n  - [🐳 Run with Docker Compose (Recommended)](#-run-with-docker-compose-recommended)\n  - [📦 Build development environment with Dev Containers (VSCode\u002FCursor)](#-build-development-environment-with-dev-containers-vscodecursor)\n  - [💻 Local Development](#-local-development)\n- [🔌 MCP Protocol Compatibility](#-mcp-protocol-compatibility)\n- [🔗 Connect to MetaMCP](#-connect-to-metamcp)\n  - [📝 E.g., Cursor via mcp.json](#-eg-cursor-via-mcpjson)\n  - [🖥️ Connecting Claude Desktop and Other STDIO-only Clients](#️-connecting-claude-desktop-and-other-stdio-only-clients)\n  - [🔧 API Key Auth Troubleshooting](#-api-key-auth-troubleshooting)\n- [❄️ Cold Start Problem and Custom Dockerfile](#️-cold-start-problem-and-custom-dockerfile)\n- [🧾 Log Levels](#-log-levels)\n- [🔐 Authentication](#-authentication)\n- [🚦 Traffic Management](#-traffic-management)\n  - [🚧 **MCP Rate Limit**](#-mcp-rate-limit)\n- [🔗 OpenID Connect (OIDC) Provider Support](#-openid-connect-oidc-provider-support)\n  - [🛠️ **Configuration**](#️-configuration)\n  - [🏢 **Supported Providers**](#-supported-providers)\n  - [🔒 **Security Features**](#-security-features)\n  - [📱 **Usage**](#-usage)\n- [⚙️ Registration Controls](#️-registration-controls)\n  - [🎛️ **Available Controls**](#️-available-controls)\n  - [🏢 **Enterprise Use Cases**](#-enterprise-use-cases)\n  - [🛠️ **Configuration**](#️-configuration-1)\n- [🌐 Custom Deployment and SSE conf for Nginx](#-custom-deployment-and-sse-conf-for-nginx)\n- [🏗️ Architecture](#️-architecture)\n  - [📊 Sequence Diagram](#-sequence-diagram)\n- [🗺️ Roadmap](#️-roadmap)\n- [🌐 i18n](#-i18n)\n- [🤝 Contributing](#-contributing)\n- [📄 License](#-license)\n- [🙏 Credits](#-credits)\n\n## 🎯 Use Cases\n- 🏷️ **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.\n-  🎯 **Pick tools you only need when remixing MCP servers.** Apply other **pluggable middleware** around observability, security, etc. (coming soon)\n-  🔍 **Use as enhanced MCP inspector** with saved server configs, and inspect your MetaMCP endpoints in house to see if it works or not.\n-  🔍 **Use as Elasticsearch for MCP tool selection** (coming soon)\n\nGenerally developers can use MetaMCP as **infrastructure** to host dynamically composed MCP servers through a unified endpoint, and build agents on top of it.\n\nQuick demo video: https:\u002F\u002Fyoutu.be\u002FCf6jVd2saAs\n\n![MetaMCP Screenshot](metamcp_screenshot.png)\n\n## 📖 Concepts\n\n### 🖥️ **MCP Server**\nA MCP server configuration that tells MetaMCP how to start a MCP server.\n\n```json\n\"HackerNews\": {\n  \"type\": \"STDIO\",\n  \"command\": \"uvx\",\n  \"args\": [\"mcp-hn\"]\n}\n```\n\n#### 🔐 **Environment Variables & Secrets (STDIO MCP Servers)**\n\nFor **STDIO MCP servers**, MetaMCP supports three ways to handle environment variables and secrets:\n\n**1. Raw Values** - Direct string values (not recommended for secrets):\n```\nAPI_KEY=your-actual-api-key-here\nDEBUG=true\n```\n\n**2. Environment Variable References** - Use `${ENV_VAR_NAME}` syntax:\n```\nAPI_KEY=${OPENAI_API_KEY}\nDATABASE_URL=${DB_CONNECTION_STRING}\n```\n\n**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.\n\n> **🔒 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.\n\n> **⚙️ Development Note**: For local development with `pnpm run dev:docker`, ensure your environment variables are listed in `turbo.json` under `globalEnv` to be passed to the development processes. This is not required for production Docker deployments.\n\n### 🏷️ **MetaMCP Namespace**\n- Group one or more MCP servers into a namespace\n- Enable\u002Fdisable MCP servers or at tool level\n- Apply middlewares to MCP requests and responses\n- Override tool names\u002Ftitles\u002Fdescriptions per namespace and attach custom MCP annotations (e.g. `{ \"annotations\": { \"readOnlyHint\": false } }`)\n\n### 🌐 **MetaMCP Endpoint**\n- Create endpoints and assign namespace to endpoints\n- Multiple MCP servers in the namespace will be aggregated and emitted as a MetaMCP endpoint\n- Choose between API-Key Auth (in header or query param) or standard OAuth in MCP Spec 2025-06-18\n- Host through **SSE** or **Streamable HTTP** transports in MCP and **OpenAPI** endpoints for clients like [Open WebUI](https:\u002F\u002Fgithub.com\u002Fopen-webui\u002Fopen-webui)\n\n### ⚙️ **Middleware**\n- Intercepts and transforms MCP requests and responses at namespace level\n- **Built-in example**: \"Filter inactive tools\" - optimizes tool context for LLMs\n- **Future ideas**: tool logging, error traces, validation, scanning\n\n### 🔍 **Inspector**\nSimilar to the official MCP inspector, but with **saved server configs** - MetaMCP automatically creates configurations so you can debug MetaMCP endpoints immediately.\n\n### ✏️ **Tool Overrides & Annotations**\n- Open a namespace → **Tools** tab to see every tool coming from connected MCP servers.\n- Each saved tool can be expanded and edited inline: update the display **name\u002Ftitle\u002Fdescription** or provide a JSON blob with namespace-specific annotations (for example `{ \"annotations\": { \"readOnlyHint\": false } }`).\n- Badges in the table (\"Overridden\", \"Annotations\") show which tools currently have custom metadata. Hover them to read a tooltip describing what was overridden.\n- Annotation overrides are merged with whatever the upstream MCP server returns, so you can safely add custom UI hints without losing provider metadata.\n\n## 🚀 Quick Start\n\n### **🐳 Run with Docker Compose (Recommended)**\n\nClone repo, prepare `.env`, and start with docker compose:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fmetatool-ai\u002Fmetamcp.git\ncd metamcp\ncp example.env .env\ndocker compose up -d\n```\n\nIf 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.\n\nNote that the pg volume name may collide with your other pg dockers, which is global, consider rename it in `docker-compose.yml`:\n\n```\nvolumes:\n  metamcp_postgres_data:\n    driver: local\n```\n\n### **📦 Build development environment with Dev Containers (VSCode\u002FCursor)**\n\nYou can use the VSCode\u002FCursor extension to build the development environment in a container.\n\nIt only requires that you have an environment running Docker or a similar alternative (the `docker`\u002F`docker compose` command is required), and no other dependent components need to be installed on your host machine.\n\n1. First, clone the MetaMCP source code, open project in Visual Studio Code.\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fmetatool-ai\u002Fmetamcp.git\ncd metamcp\ncode .\n```\n2. Switch to Dev Containers. Open the VSCode Command Palette, and execute `Dev Containers: Reopen in Container`.\n\nVSCode will open the Dev Containers project in a new window, where it will build the runtime and install the toolchain according to the `Dockerfile` before starting the connection and finally installing the MetaMCP dependencies.\n\u003Cimg width=\"895\" height=\"153\" alt=\"image\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fd3e1420d-43c1-4ed6-9229-b91ea09c142a\" \u002F>\n\n> **note**\n> This 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.\n\nWait 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.\n\u003Cimg width=\"732\" height=\"173\" alt=\"image\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F6e5752f8-7353-4a8f-b489-c13daef6700e\" \u002F>\n\nAfter finished, you can run `pnpm dev` to start the development server.\n\n### **💻 Local Development**\n\nStill recommend running postgres through docker for easy setup:\n\n```bash\npnpm install\npnpm dev\n```\n\n## 🔌 MCP Protocol Compatibility\n\n- ✅ **Tools, Resources, and Prompts** supported\n- ✅ **OAuth-enabled MCP servers** tested for 03-26 version\n\nIf you have questions, feel free to leave **GitHub issues** or **PRs**.\n\n## 🔗 Connect to MetaMCP\n\n### 📝 E.g., Cursor via mcp.json\n\nExample `mcp.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"MetaMCP\": {\n      \"url\": \"http:\u002F\u002Flocalhost:12008\u002Fmetamcp\u002F\u003CYOUR_ENDPOINT_NAME>\u002Fsse\"\n    }\n  }\n}\n```\n\n### 🖥️ Connecting Claude Desktop and Other STDIO-only Clients\n\nSince MetaMCP endpoints are remote only (SSE, Streamable HTTP, OpenAPI), clients that only support stdio servers (like Claude Desktop) need a local proxy to connect.\n\n**Note:** While `mcp-remote` is 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-proxy` is the recommended solution.\n\nHere's a working configuration for Claude Desktop using `mcp-proxy`:\n\nUsing Streamable HTTP\n\n```json\n{\n  \"mcpServers\": {\n    \"MetaMCP\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"mcp-proxy\",\n        \"--transport\",\n        \"streamablehttp\",\n        \"http:\u002F\u002Flocalhost:12008\u002Fmetamcp\u002F\u003CYOUR_ENDPOINT_NAME>\u002Fmcp\"\n      ],\n      \"env\": {\n        \"API_ACCESS_TOKEN\": \"\u003CYOUR_API_KEY_HERE>\"\n      }\n    }\n  }\n}\n```\n\nUsing SSE\n\n```json\n{\n  \"mcpServers\": {\n    \"ehn\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"mcp-proxy\",\n        \"http:\u002F\u002Flocalhost:12008\u002Fmetamcp\u002F\u003CYOUR_ENDPOINT_NAME>\u002Fsse\"\n      ],\n      \"env\": {\n        \"API_ACCESS_TOKEN\": \"\u003CYOUR_API_KEY_HERE>\"\n      }\n    }\n  }\n}\n```\n\n**Important notes:**\n- Replace `\u003CYOUR_ENDPOINT_NAME>` with your actual endpoint name\n- Replace `\u003CYOUR_API_KEY_HERE>` with your MetaMCP API key (format: `sk_mt_...`)\n\nFor more details and alternative approaches, see [issue #76](https:\u002F\u002Fgithub.com\u002Fmetatool-ai\u002Fmetamcp\u002Fissues\u002F76#issuecomment-3046707532).\n\n### 🔧 API Key Auth Troubleshooting\n\n- `?api_key=` param api key auth doesn't work for SSE. It only works for Streamable HTTP and OpenAPI.\n- Best practice is to use the API key in `Authorization: Bearer \u003CAPI_KEY>` header.\n- Try disable auth temporarily when you face connection issues to see if it is an auth issue.\n\n## ❄️ Cold Start Problem and Custom Dockerfile\n\n- MetaMCP pre-allocate idle sessions for each configured MCP servers and MetaMCPs. The default idle session for each is 1 and that can help reduce cold start time.\n- If your MCP requires dependencies other than `uvx` or `npx`, you need to customize the Dockerfile to install dependencies on your own.\n- Check [invalidation.md](invalidation.md) for a seq diagram about how idle session invalidates during updates.\n\n🛠️ **Solution**: Customize the Dockerfile to add dependencies or pre-install packages to reduce cold start time.\n\n## 🧾 Log Levels\n\nMetaMCP’s backend writes logs to files and optionally mirrors selected levels to the console. Control console mirroring with the `LOG_LEVEL` environment variable.\n\n- Files\n  - `app.log`: receives `DEBUG`, `INFO`, and `WARN`\n  - `error.log`: receives `ERROR`\n\n- Console mirroring (`LOG_LEVEL`)\n  - `all`: mirror `DEBUG`, `INFO`, `WARN`, `ERROR` to console\n  - `info`: mirror only `INFO` to console\n  - `errors-only`: mirror `WARN` and `ERROR` to console\n  - `none`: no console output\n\n- Defaults and examples\n  - Default (when unset or invalid): `errors-only`\n  - `.env` example:\n    ```bash\n    LOG_LEVEL='errors-only' # 'all', 'info', 'errors-only', 'none'\n    ```\n  - `docker-compose.dev.yml` uses: `LOG_LEVEL: ${LOG_LEVEL:-all}`\n\n## 🔐 Authentication\n\n- 🛡️ **Better Auth** for frontend & backend (TRPC procedures)\n- 🍪 **Session cookies** enforce secure internal MCP proxy connections\n- 🔑 **API key authentication** for external access via `Authorization: Bearer \u003Capi-key>` header\n- 🪪 **MCP OAuth**: Exposed endpoints have options to use standard OAuth in MCP Spec 2025-06-18, easy to connect.\n- 🏢 **Multi-tenancy**: Designed for organizations to deploy on their own machines. Supports both private and public access scopes. Users can create MCPs, namespaces, endpoints, and API keys for themselves or for everyone. Public API keys cannot access private MetaMCPs.\n- ⚙️ **Separate Registration Controls**: Administrators can independently control UI registration and SSO\u002FOAuth registration through the settings page, allowing for flexible enterprise deployment scenarios.\n\n## 🚦 Traffic Management\n\n### 🚧 MCP Rate Limit\nThe MCP Rate Limit feature allows you to set the maximum requests a MCP tool (a endpoint) will accept in a given time window. There are two different strategies to set limits that you can use separately or together:\n\n * `Endpoint rate-limiting (Rate Limiting)`: applies simultaneously to all clients using the endpoint, sharing a unique counter.\n * `User rate-limiting (Client Rate Limiting)`: sets a counter to each individual user.\n\nBoth types can coexist and they complement each other, and store the counters in-memory. On a cluster, each machine sees and counts only its passing traffic.\n\n### **Endpoint rate-limiting**\nThe endpoint rate limit acts on the number of simultaneous transactions an endpoint can process. This type of limit protects the service for all customers.\nWhen the users connected to an endpoint together exceed the `rate-limiting`, MetaMCP starts to reject connections with a status code `503 Service Unavailable`.\n\n#### **Endpoint rate-limiting options**\n * `Max Rate`: Defines how many requests will you accept from all users together at any given instant. When the gateway starts, the bucket is full. As requests from users come, the remaining tokens in the bucket decrease. At the same time, the rate-limiting refills the bucket at the desired rate until its maximum capacity is reached.\n * `Max Rate Seconds`: Time period in which the maximum rates operate in seconds. For instance, if you set an max rate seconds of 60s and a rate-limiting of 5, you are allowing 5 requests every sixty seconds.\n\n### **User rate-limiting**\nThe client or user rate limit applies one counter to each individual user and endpoint. When a single user connected to an endpoint exceeds their `client-max-rate`, MetaMCP starts rejecting connections with a status code `429 Too Many Requests`\n\n#### **User rate-limiting options**\n * `Client Max Rate`: Number of tokens you add to the Token Bucket for each individual user (user quota) in the time interval you want (Client Max Rate Seconds). The remaining tokens in the bucket are the requests a specific user can do.\n * `Client Max Rate Seconds`: Time period in which the maximum rates operate in seconds. For instance, if you set an every of 60s and a rate of 5, you are allowing 5 requests every sixty seconds.\n * `Client Max Rate Strategy`: Sets the strategy you will use to set client counters. Choose ip when the restrictions apply to the client’s IP address, or set it to header when there is a header that identifies a user uniquely. That header must be defined with the key entry.\n * `Client Max Rate Strategy Key`: It is the header name containing the user identification (e.g., Authorization on tokens, or X-Original-Forwarded-For for IPs).\n\n## 🔗 OpenID Connect (OIDC) Provider Support\n\nMetaMCP supports **OpenID Connect authentication** for enterprise SSO integration. This allows organizations to use their existing identity providers (Auth0, Keycloak, Azure AD, etc.) for authentication.\n\n### 🛠️ **Configuration**\n\nAdd the following environment variables to your `.env` file:\n\n```bash\n# Required\nOIDC_CLIENT_ID=your-oidc-client-id\nOIDC_CLIENT_SECRET=your-oidc-client-secret\nOIDC_DISCOVERY_URL=https:\u002F\u002Fyour-provider.com\u002F.well-known\u002Fopenid-configuration\n\n# Optional customization\nOIDC_PROVIDER_ID=oidc\nOIDC_SCOPES=openid email profile\nOIDC_PKCE=true\n```\n\n### 🏢 **Supported Providers**\n\nMetaMCP has been tested with popular OIDC providers:\n\n- **Auth0**: `https:\u002F\u002Fyour-domain.auth0.com\u002F.well-known\u002Fopenid-configuration`\n- **Keycloak**: `https:\u002F\u002Fyour-keycloak.com\u002Frealms\u002Fyour-realm\u002F.well-known\u002Fopenid-configuration`\n- **Azure AD**: `https:\u002F\u002Flogin.microsoftonline.com\u002Fyour-tenant-id\u002Fv2.0\u002F.well-known\u002Fopenid-configuration`\n- **Google**: `https:\u002F\u002Faccounts.google.com\u002F.well-known\u002Fopenid-configuration`\n- **Okta**: `https:\u002F\u002Fyour-domain.okta.com\u002F.well-known\u002Fopenid-configuration`\n\n### 🔒 **Security Features**\n\n- 🔐 **PKCE (Proof Key for Code Exchange)** enabled by default\n- 🛡️ **Authorization Code Flow** with automatic user creation\n- 🔄 **Auto-discovery** of OIDC endpoints\n- 🍪 **Seamless session management** with existing auth system\n\n### 📱 **Usage**\n\nOnce configured, users will see a **\"Sign in with OIDC\"** button on the login page alongside the email\u002Fpassword form. The authentication flow automatically creates new users on first login.\n\nFor more detailed configuration examples and troubleshooting, see **[CONTRIBUTING.md](CONTRIBUTING.md#openid-connect-oidc-provider-setup)**.\n\n## ⚙️ Registration Controls\n\nMetaMCP provides **separate controls** for different registration methods, allowing administrators to fine-tune user access policies for enterprise deployments.\n\n### 🎛️ **Available Controls**\n\n- **UI Registration**: Controls whether users can create accounts via the registration form\n- **SSO Registration**: Controls whether users can create accounts via SSO\u002FOAuth providers (OIDC, etc.)\n\n### 🏢 **Enterprise Use Cases**\n\nThis separation enables common enterprise scenarios:\n\n- **Block UI registration, allow SSO**: Prevent manual signups while allowing corporate SSO users\n- **Block SSO registration, allow UI**: Allow manual signups while restricting SSO access\n- **Block both**: Completely disable new user registration\n- **Allow both**: Default behavior for open deployments\n\n### 🛠️ **Configuration**\n\nAccess the **Settings** page in the MetaMCP admin interface to configure these controls:\n\n1. Navigate to **Settings** → **Authentication Settings**\n2. Toggle **\"Disable UI Registration\"** to control form-based signups\n3. Toggle **\"Disable SSO Registration\"** to control OAuth\u002FOIDC signups\n\nBoth controls work independently, giving you full flexibility over your registration policy.\n\n## 🌐 Custom Deployment and SSE conf for Nginx\n\nIf you want to deploy it to a online service or a VPS, a instance of at least 2GB-4GB of memory is required. And the larger size, the better performance.\n\nSince MCP leverages SSE for long connection, if you are using reverse proxy like nginx, please refer to an example setup [nginx.conf.example](nginx.conf.example)\n\n## 🏗️ Architecture\n\n- **Frontend**: Next.js\n- **Backend**: Express.js with tRPC, hosting MCPs through TS SDK and internal proxy\n- **Auth**: Better Auth\n- **Structure**: Standalone monorepo with Turborepo and Docker publishing\n\n### 📊 Sequence Diagram\n\n*Note: Prompts and resources follow similar patterns to tools.*\n\n```mermaid\nsequenceDiagram\n    participant MCPClient as MCP Client (e.g., Claude Desktop)\n    participant MetaMCP as MetaMCP Server\n    participant MCPServers as Installed MCP Servers\n\n    MCPClient ->> MetaMCP: Request list tools\n\n    loop For each listed MCP Server\n        MetaMCP ->> MCPServers: Request list_tools\n        MCPServers ->> MetaMCP: Return list of tools\n    end\n\n    MetaMCP ->> MetaMCP: Aggregate tool lists & apply middleware\n    MetaMCP ->> MCPClient: Return aggregated list of tools\n\n    MCPClient ->> MetaMCP: Call tool\n    MetaMCP ->> MCPServers: call_tool to target MCP Server\n    MCPServers ->> MetaMCP: Return tool response\n    MetaMCP ->> MCPClient: Return tool response\n```\n\n## 🗺️ Roadmap\n\n**Potential next steps:**\n\n- [ ] 🔌 Headless Admin API access\n- [ ] 🔍 Dynamically apply search rules on MetaMCP endpoints\n- [ ] 🛠️ More middlewares\n- [ ] 💬 Chat\u002FAgent Playground\n- [ ] 🧪 Testing & Evaluation for MCP tool selection optimization\n- [ ] ⚡ Dynamically generate MCP servers\n\n## 🌐 i18n\n\nSee [README-i18n.md](README-i18n.md)\n\nCurrently en and zh locale are supported, but welcome contributions.\n\n## 🤝 Contributing\n\nWe welcome contributions! See details at **[CONTRIBUTING.md](CONTRIBUTING.md)**\n\n## 📄 License\n\n**MIT**\n\nWould appreciate if you mentioned with back links if your projects use the code.\n\n## 🙏 Credits\n\nSome code inspired by:\n- [MCP Inspector](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Finspector)\n- [MCP Proxy Server](https:\u002F\u002Fgithub.com\u002Fadamwattis\u002Fmcp-proxy-server)\n\nNot directly used the code by took ideas from\n- https:\u002F\u002Fgithub.com\u002Fopen-webui\u002Fopenapi-servers\n- https:\u002F\u002Fgithub.com\u002Fopen-webui\u002Fmcpo\n","MetaMCP 是一个集成了聚合、编排、中间件和网关功能的 Docker 容器，用于统一管理多个 MCP 服务器。它允许用户动态地将多个 MCP 服务器整合为一个统一的 MCP 服务器，并应用各种中间件。该项目采用 TypeScript 编写，具备高度的灵活性与可扩展性，支持自托管部署。适用于需要对多个模型上下文协议（MCP）服务进行集中管理和调度的场景，如开发复杂的 AI 应用或构建多模型协同工作的系统。",2,"2026-06-11 03:47:46","high_star"]