Every time a user loaded Open WebUI, each OAuth MCP server they had not connected yet wrote a warning to the logs ("No OAuth session found for user ..., client_id mcp:<server id>"), so instances with a few such servers filled their logs with it. Not having connected a server yet is a normal state, so the message now logs at debug level and only shows up when debug logging is on. Using an MCP server without connecting it still fails with "Auth required" as before.
When a streamed reply from a Responses API connection stopped early, for example at the token limit or through a content filter, its token counts were lost. The chat showed no usage for that reply and the admin analytics recorded zero tokens for it. Such replies now keep the usage the provider reported, the same as replies that finished normally.
Fixes#33615
With OpenTelemetry metrics on, a request for a URL the server has no API endpoint for was counted under its full address, so every distinct URL became a metric series of its own and the series count kept growing. When the web interface is not served (API-only setups) this happens for any unknown URL, such as bots probing for missing paths. With Starlette 1.3.1, the version pinned for source installs, it also happens for every page load, static file and websocket request, because that version tells the server nothing about which part of the app answered them. These requests are now counted without a URL label, while API requests keep theirs. Admins need to do nothing, as the old series stop growing and age out.
Fixes#33576
Prompts could use the user's name and email but not their role, so role-aware system prompts needed a custom Filter function. Model system prompts, the user's own system prompt, saved prompts used with a slash command and chat requests through the API now replace {{USER_ROLE}} with the role, such as admin or user. Requested in #4765.
When a tool returned an image, for example Open Terminal reading a PNG, a native tool or an MCP screenshot tool, the image was sent to the model even when the model has Vision turned off. A provider serving a text-only model rejects that request, so the reply failed with an error like "At most 0 image(s) may be provided in one prompt", and every later message in the chat failed the same way. With Vision off the model now gets a short "[image]" note in place of each tool image, including images already saved in the chat, so stuck chats work again. The images stay saved, so they reach the model again once Vision is turned on.
Fixes#32720
A ComfyUI workflow that ends in the core Save Animated WEBP or Save Animated PNG node finished on the ComfyUI side, but nothing showed up in the chat, because Open WebUI only picked up images from the Save Image, Save Image (Advanced) and Preview Image nodes. Images from both animated nodes now show up in the chat too, as the original animated file, for image generation and image editing.
Closes#33013
With OpenTelemetry metrics on, every request is counted in the HTTP request and duration metrics, so Kubernetes liveness and readiness probes on `/health` and `/health/db` fill the time series database and dashboards with noise. These metrics now skip any request whose URL matches `OTEL_PYTHON_FASTAPI_EXCLUDED_URLS` (or `OTEL_PYTHON_EXCLUDED_URLS` as a fallback), the standard OpenTelemetry variable that traces already honour. It takes a comma-separated list of regular expressions such as `/health,/_app/immutable/.*`, each matched anywhere in the URL, so `/health` also covers `/health/db`. One pattern now drops the same requests from traces and metrics alike. Nothing changes when the variable is unset.
Closes#31609
When a scheduled automation failed (for example because its model was deleted), the owner could only see it as an error in the run history, so they found out much later when the results stopped showing up. Automation run failed is now one of the automatic events users can pick for their notification targets under Settings > Notifications, and every failed run, scheduled or started by hand, sends the automation name and the error to those targets. In Admin Settings > General > Events, webhooks set to Specific users or groups now receive these failures when the owner is among those users or groups, and webhooks set to System events only stop receiving them.
Closes#33228
When an MCP tool server could not be reached for a tool call (server restarted, connection reset by a proxy or load balancer, a request timing out), the whole chat was cancelled as if the user had pressed stop, and the log only said "Task was cancelled!". Now only that tool call fails, the model gets the connection error as the tool result and the reply finishes, and the underlying connection error is logged. The MCP SDK cancels whatever task opened the session when a single request fails, so each MCP session now runs in its own task instead of the chat's.
Fixes#33268
Remote fetches now ask for an uncompressed response: web pages, documents, remote images, profile pictures from a login provider and webhook deliveries. A response that comes back compressed anyway is refused, except for a webhook reply, which is only logged and is left unread instead.
A page or file whose host echoes a stored `Content-Encoding` regardless of what the client asks for (an S3 or MinIO object uploaded with that metadata) is no longer read, and a profile picture that arrives that way falls back to the default avatar.
When a foreground sub-agent stopped at the tool-call limit, the parent model got only the error, so everything the sub-agent had written before the limit was lost, while a background sub-agent in the same state reported it as partial output. A foreground sub-agent now returns the error followed by its partial output, the same way the background report does. The error in both modes is now the plain message, such as "Tool-call limit reached (30 iterations).", instead of raw internal data around it.
Fixes#33267
When the model handed a photo from the chat to a sub-agent, the call failed with "file_ids not attached or unavailable" and no sub-agent started. Text files and documents worked, only photos were refused. Photos attached in the chat are now accepted and reach the sub-agent as an image, the same way they reach the model in a normal chat. Files that were never attached to the chat are still refused.
Fixes#33241
Since a recent refactor on dev, the prompt and completion token counts of a reply that used tools added up every model call in the loop, even though each later call already re-sends the whole conversation. A reply whose context was 50k tokens showed 90k, the context gauge read over 100% and the next message triggered compaction long before the chat reached the threshold. Prompt and completion tokens show the latest call again, while total tokens and cost still add up across all calls.
Choosing Add Details, More Concise, or typing a suggestion under a reply sent the model your original question followed straight by the bare instruction, with the reply itself missing, so it answered the instruction on its own (for example "OK, I'll keep answers shorter") instead of rewriting that reply. The model now receives the reply it is being asked to change, so it returns a shorter, more detailed or altered version of it. Plain Try Again and temporary chats were not affected.
Fixes#33083
* fix: MCP tools that list their arguments under anyOf are called with no arguments
When an MCP tool described its input as alternatives, for example a page by id or by path and locale, and had no top-level list of fields, every argument the model sent was dropped and the tool was called with nothing, so the server rejected the call. Arguments for MCP tools now reach the server as the model sent them, and the MCP server checks them against its own schema. Other tool types still keep only the arguments their schema lists.
Fixes#32898
* refac: shorten the MCP arguments comment
The comment now only says why MCP tools skip the argument filter.
* fix: MCP tool errors reach the model as a Python list dump instead of the server's message
When an MCP tool server answered a call with an error, the model got a Python dump of the whole result list, with quotes, annotations and meta fields, instead of the error text the server wrote. Line breaks in the message were escaped as well, so a validation error listing the missing argument was hard to read and models tended to retry the same broken call. The model now gets the server's error text as written, the same way successful results already arrive.
Fixes#32918
* refac: drop the fallback text for MCP errors with no message
The error now carries only the text the server sent.
* fix: keep a readable error when an MCP error has no text
MCP error results that only carry images, audio or resources now give the model a short error message instead of an empty one.
The required parameters of OpenAPI tool server tools, Open Terminal included, were sent to the model in a random order that could change every time Open WebUI restarted. The tool list sits at the start of every prompt, so a different order made every prefix cache on the model side miss, and long chats were processed again from scratch after a restart. The required parameters now keep the order the tool server declares, so the tool list stays identical across restarts.
Upgrade the MCP SDK to 2.3.0 and build MCPClient on its Client in
mode='auto', which probes server/discover for the stateless 2026-07-28
protocol and falls back to the initialize handshake for legacy servers.
MCPClient's public surface is unchanged.
MCP_INITIALIZE_TIMEOUT becomes the session's default request timeout, so
it bounds the legacy handshake, tool listing and resource reads; tool
calls keep using AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER.
Relates to #29778
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>