Model Context Protocol (MCP)
Open WebUI natively supports MCP (Model Context Protocol) starting in v0.6.31. This page shows how to enable it quickly, harden it for production, and troubleshoot common snags.
Requires Open WebUI v0.6.31+.
You MUST set the WEBUI_SECRET_KEY environment variable in your Docker setup. Without it, OAuth-connected MCP tools (like Notion) will break every time you restart or recreate the container (Error: Error decrypting tokens), forcing you to re-authenticate everything.
๐ Quick startโ
- Open โ๏ธ Admin Settings โ External Tools.
- Click + (Add Server).
- Set Type to MCP (Streamable HTTP).
- Enter your Server URL and Auth details (OAuth 2.1, if required).
- Save. If prompted, restart Open WebUI.
You can now call tools exposed by your MCP server from Open WebUI.
If you are adding an MCP server, make sure Type is set to MCP (Streamable HTTP), not OpenAPI.
Entering MCP-style configuration (with mcpServers in JSON) into an OpenAPI connection will cause the UI to crash or display an infinite loading screen. If you encounter this:
- Disable the problematic tool connection via Admin Settings
- Re-add it with the correct Type set to MCP
๐งญ When to use MCP vs OpenAPIโ
For most deployments, OpenAPI remains the preferred integration path.
Choose OpenAPI if you want:
- Enterprise readiness: deep SSO, API gateways, audit, quotas, typed SDKs.
- Operational resilience: standard HTTP verbs, idempotency, caching, rich error codes.
- Observability: first-class tracing and policy integration.
Choose MCP (Streamable HTTP) if you need:
- A common tool protocol already used by your MCP servers/clients.
- Streamed protocol communication over HTTP (Note: This refers to MCP's transport-level streaming, not Open WebUI's UI event system which is only available for native Python tools).
You donโt have to pick one: many teams expose OpenAPI internally and wrap MCP at the edge for specific clients.
Browser-based, multi-user deployments increase the surface area (CORS/CSRF, per-user isolation, reconnects). Review your orgโs auth, proxy, and rate-limiting policies before exposing MCP externally.
โ๏ธ Configuration Best Practicesโ
Authentication Modesโ
- None: Use this for local MCP servers or internal networks where no token is required.
- โ ๏ธ Important: Default to "None" unless your server strictly requires a token. Selecting "Bearer" without providing a key sends an empty Authorization header (
Authorization: Bearer), which causes many servers to reject the connection immediately.
- โ ๏ธ Important: Default to "None" unless your server strictly requires a token. Selecting "Bearer" without providing a key sends an empty Authorization header (
- Bearer: Use this only if your MCP server requires a specific API token. You must populate the "Key" field.
- OAuth 2.1: Uses Dynamic Client Registration (DCR). Best when your MCP server supports registering OAuth clients automatically.
- OAuth 2.1 (Static): Uses a pre-created client ID/client secret. Best when your provider does not support DCR, or when your security team requires manually managed credentials.
- Start with OAuth 2.1 if your server supports DCR.
- Use OAuth 2.1 (Static) when you already have credentials from your IdP and want Open WebUI to use those directly.
OAuth 2.1 (Static) Setupโ
Use this when you already have a client ID/client secret from your identity provider.
- Open Admin Settings โ External Tools.
- Click + (Add Server).
- Set Type to MCP (Streamable HTTP).
- Enter your MCP server URL.
- In Auth, select OAuth 2.1 (Static).
- Enter Client ID and Client Secret.
- (Optional) Enter an OAuth Server URL if your identity provider lives on a different host than the MCP resource server. When empty, Open WebUI fetches the OAuth discovery document from the MCP URL; when set, discovery and the static-credentials registration both run against this URL instead. Useful for setups where the MCP server proxies a corporate IdP at a separate origin.
- Click Register Client.
- Click Save.
After saving:
- Open a chat.
- Click + โ Integrations โ Tools.
- Enable your MCP tool.
- Complete the OAuth consent/authorization flow in the browser redirect.
Register Client is required for both oauth_2.1 and oauth_2.1_static. With static auth, Open WebUI uses your provided credentials and server metadata discovery (no dynamic client registration).
If the MCP server publishes a resource field in its RFC 9728 Protected Resource Metadata document (/.well-known/oauth-protected-resource), Open WebUI captures it during discovery and forwards it as the resource parameter on the authorization redirect, on the token exchange, and on every refresh-token call. This sets the aud claim correctly on issued tokens and is required by identity providers that validate audiences strictly per RFC 8707.
No configuration is needed on the Open WebUI side โ the resource indicator is discovered automatically. If your IdP rejects MCP tool calls with invalid_audience or similar errors, confirm that your MCP server's protected-resource metadata document advertises the correct resource URL.
Do not set OAuth 2.1 MCP tools as default/pre-enabled tools on a model. The OAuth 2.1 authorization flow requires an interactive browser redirect (user consent, callback) that cannot happen transparently during a chat completion request.
If an OAuth 2.1 tool is set as a default and the user hasn't previously authenticated (or their refresh token has expired), the tool call will fail with "Failed to connect to MCP server" because the backend cannot initiate the browser-based auth flow mid-request.
Workaround: Users should manually enable OAuth 2.1 tools per-chat via the โ button in the chat input area. This triggers the auth flow before the tool is ever invoked. Token refresh works automatically once the initial authentication is complete.
Connection URLsโ
If you are running Open WebUI in Docker and your MCP server is on the host machine:
- Use
http://host.docker.internal:<port>(e.g.,http://host.docker.internal:3000/sse) instead oflocalhost.
Custom Headersโ
Both MCP and OpenAPI tool-server connections accept a free-form Headers field (JSON object) that is merged into every outbound request. Header values support a small set of template tokens, expanded server-side at request time so you can route a single connection to per-user, per-chat, or per-message backend logic without provisioning separate connections:
| Token | Replaced with |
|---|---|
{{USER_ID}} | The calling user's ID. |
{{USER_NAME}} | The calling user's display name. |
{{CHAT_ID}} | The current chat ID (empty in non-chat contexts like the Verify Connection button). |
{{MESSAGE_ID}} | The current message ID (empty in non-chat contexts). |
Unknown tokens are passed through as literal text. Non-string header values are coerced to strings before substitution. The same tokens are honored on custom headers attached to OpenAI-compatible model connections in Admin Settings โ Connections โ OpenAI, so you can use the feature for tenant routing or audit-trail propagation across both surfaces.
Function Name Filter Listโ
This field restricts which tools are exposed to the LLM.
- Default: Leave empty to expose all tools (in most cases).
- Workaround: If you encounter connection errors with an empty list, try adding a single comma (
,) to this field. This forces the system to treat it as a valid (but empty) filter, potentially bypassing some parsing issues.
Troubleshootingโ
"Failed to connect to MCP server"โ
Symptom: The chat shows "Failed to connect to MCP server" when using a tool, even if the Verify Connection button in settings says "Connected".
Solutions:
- Check Authentication: Ensure you haven't selected
Bearerwithout a key. Switch toNoneif no token is needed. - Filter List Bug: If the "Function Name Filter List" is empty, try adding a comma (
,) to it. - OAuth 2.1 Default Tool: If the failing tool uses OAuth 2.1 and is set as a default tool on the model, this is a known limitation. Remove it from the model's default tools and have users enable it manually per-chat.
Infinite loading screen after adding External Toolโ
Symptom:
After adding an External Tool connection, the frontend gets stuck on a loading spinner. The browser console shows an error like Cannot convert undefined or null to object at Object.entries.
Cause:
You likely configured an MCP server using the OpenAPI connection type, or entered MCP-style JSON (containing mcpServers) into an OpenAPI connection.
Solution:
- Open Admin Settings โ External Tools (the sidebar still loads)
- Disable or delete the problematic tool connection
- Refresh the page (Ctrl+F5)
- Re-add the connection with the correct Type set to MCP (Streamable HTTP)
โ FAQโ
Do you support stdio or SSE transports?
Native MCP support in Open WebUI is Streamable HTTP only. This design choice reflects our architecture: Open WebUI is a web-based, multi-tenant environment, not a local desktop process.
Browsers operate within strict sandboxed and event-driven HTTP constraints, making long-lived stdio or SSE connections difficult to maintain securely across users and sessions.
If you need to bridge those other MCP transports, check out mcpo โ an open-source proxy that translates stdio or SSE-based MCP servers into OpenAPI-compatible endpoints. It effectively lets you run traditional MCP tools inside Open WebUI without modifying their transport layer.
Is MCP considered stable here?
Supported and improving. The broader ecosystem is still evolving; expect occasional breaking changes.
Can I mix OpenAPI and MCP tools?
Yes. Many deployments do both.