MCP Proxy
A self-hosted proxy that enables per-user credential injection for upstream MCP servers, allowing users to securely connect services like GitHub and Confluence via one-time links without exposing credentials to the LLM.
README
MCP Proxy
A self-hosted proxy that gives each user their own credentials for upstream MCP (Model Context Protocol) servers. Users connect services like GitHub and Confluence by visiting a one-time secure link, the LLM never sees the credentials.
How it works
OpenWebUI → MCP Proxy → Upstream MCP servers → GitHub / Confluence / ...
(per-user (user's own
credential credentials
injection) forwarded)
The proxy sits between OpenWebUI and upstream MCP servers. When the LLM calls a tool, the proxy intercepts the request, looks up the calling user's stored credential, and forwards the call to the upstream server with that credential attached. Each user's keys are stored encrypted with two independent layers (AES-256-GCM with a master key + a per-user key derived from the JWT secret), so a single compromised secret is not enough to decrypt stored credentials.
For a full explanation see docs/how-it-works.md.
Quick start
Prerequisites
- Docker and Docker Compose
- A running OpenWebUI instance
- A running Redis instance
There are two compose files depending on your setup:
| File | Use when |
|---|---|
docker-compose.yaml |
You already run GitHub MCP and Confluence MCP separately, just deploys the proxy |
dev-stack-proxy/docker-compose.yaml |
Full local stack, deploys proxy + GitHub MCP + Confluence MCP together |
1. Configure environment
cp .env.example .env
Edit .env and fill in all values. Required:
| Variable | Description |
|---|---|
WEBUI_SECRET_KEY |
Must match your OpenWebUI WEBUI_SECRET_KEY |
MASTER_ENCRYPTION_KEY |
Base64-encoded 32-byte AES key - see instruction below |
REDIS_URL_PROXY |
Redis connection string, e.g. redis://localhost:6379/2 |
PROXY_BASE_URL |
Public-facing URL of this proxy, no trailing slash |
MCP_SERVERS |
JSON map of service name to upstream MCP URL, e.g. {"github":"http://github-mcp:8082/mcp","confluence":"http://confluence-mcp:8000/mcp"} |
Generate a master encryption key:
python -c "import os,base64; print(base64.b64encode(os.urandom(32)).decode())"
2. Start the proxy
docker compose up -d
Or with the full dev stack (includes GitHub MCP and Confluence MCP):
docker compose -f dev-stack-proxy/docker-compose.yaml up -d
3. Register in OpenWebUI
Settings → Connections → MCP Servers → Add:
TYPE: MCP Streamable HTTP
URL: http://localhost:8000/mcp
AUTH: Session (Will forward user JWT(cookie) to the proxy so it knows who its talking to)
If OpenWebUI runs in Docker on the same host, use http://host.docker.internal:8000/mcp or the container name.
Connecting services
Users connect services through the chat interface - no admin action needed per user.
GitHub
- In chat: "Connect my GitHub account"
- Open the one-time link the assistant provides
- Paste a GitHub PAT (Personal Access Token) with
reposcope - Return to chat
For GitHub Enterprise, set GITHUB_HOST in .env to your enterprise hostname.
Confluence
- In chat: "Connect my Confluence account"
- Open the one-time link
- Enter your Atlassian email and an API token (generate at
https://id.atlassian.com/manage-profile/security/api-tokens) - Return to chat
Requires CONFLUENCE_URL and ATLASSIAN_OAUTH_CLOUD_ID in .env. See docs/atlassian-oauth-setup.md.
Once connected, the LLM can search pages, read content, create and update pages, and more - full tool execution works end-to-end using Basic auth with the user's API token.
Adding any other MCP server
Add the service to MCP_SERVERS in .env and a container entry to docker-compose.yaml. Tool discovery is automatic - no code changes needed for services that use standard Bearer auth.
See docs/configuration.md for auth header scheme configuration.
Available tools (exposed to the LLM)
| Tool | Description |
|---|---|
get_auth_url |
Generate a one-time link to connect a service |
list_available_tools |
List all tools from authenticated upstream services |
call_tool |
Call a tool on an upstream service |
list_authenticated_services |
Show which services the user has connected |
revoke_service |
Remove a stored credential |
Multiple credentials per service
Users can store multiple credentials for the same service using aliases, useful for different GitHub organisations or scoped tokens:
"Connect my GitHub account for org my org"
→ get_auth_url('github', alias='my org')
"Connect my GitHub personal account"
→ get_auth_url('github', alias='')
The LLM uses the alias when calling tools:
call_tool('list_repositories', {}, alias='my org')
Security
- Credentials are encrypted at rest with two independent AES-256-GCM layers
- Outer layer:
MASTER_ENCRYPTION_KEY - Inner layer: HKDF-derived from
WEBUI_SECRET_KEY+user_id - Auth links are one-time use with a 5-minute TTL
- User identity is verified on every request via JWT signed with
WEBUI_SECRET_KEY - Credentials expire after a user-selected TTL (30 / 90 / 180 / 365 days)
Documentation
| File | Contents |
|---|---|
| docs/how-it-works.md | Conceptual and technical explanation |
| docs/architecture.md | Request flow, component design, design decisions |
| docs/getting-started.md | Operator setup guide |
| docs/configuration.md | All environment variables |
| docs/tools-reference.md | LLM-facing tools reference |
| docs/atlassian-oauth-setup.md | Confluence Cloud setup |
Project structure
MCP_Proxy/
├── main.py # FastMCP app, tool definitions, routing
├── auth.py # JWT verification
├── auth_flow.py # One-time auth URL and credential form
├── credentials.py # Encrypted credential storage (Redis)
├── registry.py # Upstream MCP server discovery and tool dispatch
├── Dockerfile
├── docker-compose.yaml # Proxy only - bring your own upstream MCP servers
├── .env.example
├── dev-stack-proxy/
│ ├── docker-compose.yaml # Full stack - proxy + GitHub MCP + Confluence MCP
│ └── .env.example
└── docs/
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。