[GH-ISSUE #18732] issue: Global Tool Servers doesn't show full list of functions #34218

Closed
opened 2026-04-25 08:07:31 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @touseefspeaks on GitHub (Oct 30, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/18732

Check Existing Issues

  • I have searched for any existing and/or related issues.
  • I have searched for any existing and/or related discussions.
  • I am using the latest version of Open WebUI.

Installation Method

Docker

Open WebUI Version

v0.6.34 (latest)

Ollama Version (if applicable)

0.12.6

Operating System

Ubuntu 22.04

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

List the tools setup in the MCP streamable http server when enabled in the UI

Actual Behavior

Tools in the mcp server are not listed

Steps to Reproduce

Installed Openweb ui via docker.
Go to the admin section and add the mcp server as shown in screenshots below

Logs & Screenshots

The mcp server is added a the global level, it connects properly

Image

Even enabled in UI in the chat section, tools in the mcp server are not listed

Image

Docker Logs:

2025-10-30 07:17:53.667 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXX.XXXX.com/mcp "HTTP/1.1 200 OK"
2025-10-30 07:17:53.668 | INFO | mcp.client.streamable_http:_maybe_extract_session_id_from_response:134 - Received session ID: be9fb4bf75de49d0832f72bc5f45fbbf
2025-10-30 07:17:53.669 | INFO | mcp.client.streamable_http:_maybe_extract_protocol_version_from_message:146 - Negotiated protocol version: 2025-06-18
2025-10-30 07:17:54.451 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXXXXXX/mcp "HTTP/1.1 202 ACCEPTED"
2025-10-30 07:17:55.458 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXXXXXXXXXXX/mcp "HTTP/1.1 200 OK"
2025-10-30 07:17:56.481 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: DELETE https://XXXX/mcp "HTTP/1.1 200 OK"
2025-10-30 07:17:56.483 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: GET https://XXXXXX/mcp "HTTP/1.1 200 OK"
2025-10-30 07:17:56.489 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.41.167.10:59464 - "POST /api/v1/configs/tool_servers/verify HTTP/1.1" 200
2025-10-30 07:18:01.571 | INFO | open_webui.config:save:212 - Saving 'TOOL_SERVER_CONNECTIONS' to the database

Additional Information

No response

Originally created by @touseefspeaks on GitHub (Oct 30, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/18732 ### Check Existing Issues - [x] I have searched for any existing and/or related issues. - [x] I have searched for any existing and/or related discussions. - [x] I am using the latest version of Open WebUI. ### Installation Method Docker ### Open WebUI Version v0.6.34 (latest) ### Ollama Version (if applicable) 0.12.6 ### Operating System Ubuntu 22.04 ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior List the tools setup in the MCP streamable http server when enabled in the UI ### Actual Behavior Tools in the mcp server are not listed ### Steps to Reproduce Installed Openweb ui via docker. Go to the admin section and add the mcp server as shown in screenshots below ### Logs & Screenshots The mcp server is added a the global level, it connects properly <img width="429" height="410" alt="Image" src="https://github.com/user-attachments/assets/cfa086b4-8c8c-49f0-b6d2-422824e523e5" /> Even enabled in UI in the chat section, tools in the mcp server are not listed <img width="890" height="493" alt="Image" src="https://github.com/user-attachments/assets/babfa143-ad34-436a-bab7-153fdceff852" /> **Docker Logs:** 2025-10-30 07:17:53.667 | INFO **| httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXX.XXXX.com/mcp "HTTP/1.1 200 OK"** 2025-10-30 07:17:53.668 | INFO | mcp.client.streamable_http:_maybe_extract_session_id_from_response:134 - Received session ID: be9fb4bf75de49d0832f72bc5f45fbbf 2025-10-30 07:17:53.669 | INFO | mcp.client.streamable_http:_maybe_extract_protocol_version_from_message:146 - Negotiated protocol version: 2025-06-18 2025-10-30 07:17:54.451 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXXXXXX/mcp "HTTP/1.1 202 ACCEPTED" 2025-10-30 07:17:55.458 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: POST https://XXXXXXXXXXXX/mcp "HTTP/1.1 200 OK" 2025-10-30 07:17:56.481 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: DELETE https://XXXX/mcp "HTTP/1.1 200 OK" 2025-10-30 07:17:56.483 | INFO | httpx._client:_send_single_request:1740 - HTTP Request: GET https://XXXXXX/mcp "HTTP/1.1 200 OK" 2025-10-30 07:17:56.489 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 10.41.167.10:59464 - "POST /api/v1/configs/tool_servers/verify HTTP/1.1" 200 2025-10-30 07:18:01.571 | INFO | open_webui.config:save:212 - Saving 'TOOL_SERVER_CONNECTIONS' to the database ### Additional Information _No response_
GiteaMirror added the bug label 2026-04-25 08:07:31 -05:00
Author
Owner

@silentoplayz commented on GitHub (Oct 30, 2025):

This looks like expected behavior to me, no? What's the issue?

Image Image Image
<!-- gh-comment-id:3467937760 --> @silentoplayz commented on GitHub (Oct 30, 2025): This looks like expected behavior to me, no? What's the issue? <img width="503" height="750" alt="Image" src="https://github.com/user-attachments/assets/d2efa3f8-8878-40a2-a397-0f0e581c6f21" /> <img width="351" height="353" alt="Image" src="https://github.com/user-attachments/assets/6c55ab55-44e8-442c-8a85-acff29c4dc4e" /> <img width="711" height="188" alt="Image" src="https://github.com/user-attachments/assets/1e0b2e13-0ccf-4499-b610-23d85c411e86" />
Author
Owner

@rgaricano commented on GitHub (Oct 30, 2025):

He want that each tool is individually exposed,
that is, add this changes to code (as it's done for OpenAPI tool server implementation):
in backend/open_webui/routers/tools.py

# Replace the existing MCP server loop with this:
for server in request.app.state.config.TOOL_SERVER_CONNECTIONS:
    if server.get("type", "openapi") == "mcp" and server.get("config", {}).get("enable", False):
        server_id = server.get("info", {}).get("id")

        try:
            # Connect to MCP server and fetch tools
            client = MCPClient()
            headers = None

            # Handle authentication (similar to verification endpoint)
            auth_type = server.get("auth_type", "none")
            if auth_type == "bearer":
                headers = {"Authorization": f"Bearer {server.get('key', '')}"}
            elif auth_type == "session":
                headers = {"Authorization": f"Bearer {request.state.token.credentials}"}

            await client.connect(server.get("url", ""), headers=headers)
            tool_specs = await client.list_tool_specs()

            # Create individual tool entries
            for spec in tool_specs:
                tools.append(
                    ToolUserResponse(
                        **{
                            "id": f"server:mcp:{server_id}:{spec['name']}",
                            "user_id": f"server:mcp:{server_id}:{spec['name']}",
                            "name": spec.get("name", "MCP Tool"),
                            "meta": {
                                "description": spec.get("description", ""),
                                "server_id": server_id,
                                "server_name": server.get("info", {}).get("name", "MCP Server"),
                            },
                            "access_control": server.get("config", {}).get("access_control", None),
                            "updated_at": int(time.time()),
                            "created_at": int(time.time()),
                        }
                    )
                )

            await client.disconnect()

        except Exception as e:
            log.error(f"Failed to fetch tools from MCP server {server_id}: {e}")
            # Fallback to showing server as single unit
            tools.append(
                ToolUserResponse(
                    **{
                        "id": f"server:mcp:{server_id}",
                        "user_id": f"server:mcp:{server_id}",
                        "name": server.get("info", {}).get("name", "MCP Tool Server"),
                        "meta": {"description": server.get("info", {}).get("description", "")},
                        "access_control": server.get("config", {}).get("access_control", None),
                        "updated_at": int(time.time()),
                        "created_at": int(time.time()),
                    }
                )
            )

& in backend/open_webui/utils/tools.py:

# Add this condition after the existing server: handling
elif tool_id.startswith("server:mcp:") and ":" in tool_id[11:]:  # Individual MCP tool
    parts = tool_id.split(":")
    if len(parts) >= 4:  # server:mcp:server_id:tool_name
        server_id = parts[2]
        tool_name = ":".join(parts[3:])  # Handle tool names with colons

        # Find the MCP server connection
        mcp_server_connection = None
        for server_connection in request.app.state.config.TOOL_SERVER_CONNECTIONS:
            if (server_connection.get("type", "") == "mcp" 
                and server_connection.get("info", {}).get("id") == server_id):
                mcp_server_connection = server_connection
                break

        if mcp_server_connection:
            # Connect and get the specific tool
            client = MCPClient()
            try:
                # Handle auth similar to middleware
                headers = None
                auth_type = mcp_server_connection.get("auth_type", "")
                if auth_type == "bearer":
                    headers = {"Authorization": f"Bearer {mcp_server_connection.get('key', '')}"}

                await client.connect(mcp_server_connection.get("url", ""), headers=headers)
                tool_specs = await client.list_tool_specs()

                # Find the specific tool spec
                target_spec = None
                for spec in tool_specs:
                    if spec["name"] == tool_name:
                        target_spec = spec
                        break

                if target_spec:
                    def make_tool_function(client, function_name):
                        async def tool_function(**kwargs):
                            return await client.call_tool(function_name, function_args=kwargs)
                        return tool_function

                    tool_function = make_tool_function(client, tool_name)

                    tools_dict[tool_name] = {
                        "tool_id": tool_id,
                        "callable": tool_function,
                        "spec": target_spec,
                        "type": "mcp",
                        "client": client,
                    }

            except Exception as e:
                log.error(f"Failed to connect to MCP tool {tool_id}: {e}")

(I had its opened to work on it ;-)

<!-- gh-comment-id:3467996088 --> @rgaricano commented on GitHub (Oct 30, 2025): He want that each tool is individually exposed, that is, add this changes to code (as it's done for OpenAPI tool server implementation): in [backend/open_webui/routers/tools.py](https://github.com/open-webui/open-webui/blob/dev/backend/open_webui/routers/tools.py#L97) ``` # Replace the existing MCP server loop with this: for server in request.app.state.config.TOOL_SERVER_CONNECTIONS: if server.get("type", "openapi") == "mcp" and server.get("config", {}).get("enable", False): server_id = server.get("info", {}).get("id") try: # Connect to MCP server and fetch tools client = MCPClient() headers = None # Handle authentication (similar to verification endpoint) auth_type = server.get("auth_type", "none") if auth_type == "bearer": headers = {"Authorization": f"Bearer {server.get('key', '')}"} elif auth_type == "session": headers = {"Authorization": f"Bearer {request.state.token.credentials}"} await client.connect(server.get("url", ""), headers=headers) tool_specs = await client.list_tool_specs() # Create individual tool entries for spec in tool_specs: tools.append( ToolUserResponse( **{ "id": f"server:mcp:{server_id}:{spec['name']}", "user_id": f"server:mcp:{server_id}:{spec['name']}", "name": spec.get("name", "MCP Tool"), "meta": { "description": spec.get("description", ""), "server_id": server_id, "server_name": server.get("info", {}).get("name", "MCP Server"), }, "access_control": server.get("config", {}).get("access_control", None), "updated_at": int(time.time()), "created_at": int(time.time()), } ) ) await client.disconnect() except Exception as e: log.error(f"Failed to fetch tools from MCP server {server_id}: {e}") # Fallback to showing server as single unit tools.append( ToolUserResponse( **{ "id": f"server:mcp:{server_id}", "user_id": f"server:mcp:{server_id}", "name": server.get("info", {}).get("name", "MCP Tool Server"), "meta": {"description": server.get("info", {}).get("description", "")}, "access_control": server.get("config", {}).get("access_control", None), "updated_at": int(time.time()), "created_at": int(time.time()), } ) ) ``` & in [backend/open_webui/utils/tools.py](https://github.com/open-webui/open-webui/blob/dev/backend/open_webui/utils/tools.py#L210): ``` # Add this condition after the existing server: handling elif tool_id.startswith("server:mcp:") and ":" in tool_id[11:]: # Individual MCP tool parts = tool_id.split(":") if len(parts) >= 4: # server:mcp:server_id:tool_name server_id = parts[2] tool_name = ":".join(parts[3:]) # Handle tool names with colons # Find the MCP server connection mcp_server_connection = None for server_connection in request.app.state.config.TOOL_SERVER_CONNECTIONS: if (server_connection.get("type", "") == "mcp" and server_connection.get("info", {}).get("id") == server_id): mcp_server_connection = server_connection break if mcp_server_connection: # Connect and get the specific tool client = MCPClient() try: # Handle auth similar to middleware headers = None auth_type = mcp_server_connection.get("auth_type", "") if auth_type == "bearer": headers = {"Authorization": f"Bearer {mcp_server_connection.get('key', '')}"} await client.connect(mcp_server_connection.get("url", ""), headers=headers) tool_specs = await client.list_tool_specs() # Find the specific tool spec target_spec = None for spec in tool_specs: if spec["name"] == tool_name: target_spec = spec break if target_spec: def make_tool_function(client, function_name): async def tool_function(**kwargs): return await client.call_tool(function_name, function_args=kwargs) return tool_function tool_function = make_tool_function(client, tool_name) tools_dict[tool_name] = { "tool_id": tool_id, "callable": tool_function, "spec": target_spec, "type": "mcp", "client": client, } except Exception as e: log.error(f"Failed to connect to MCP tool {tool_id}: {e}") ``` (I had its opened to work on it ;-)
Author
Owner

@rgaricano commented on GitHub (Oct 30, 2025):

This way all tools are individually displayed in the integration menu,
for have its in the integration menu in a MCP Server submenu are necessary this changes:
add let selectedMcpServerId = null; in
292be82754/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte (L49)
change 292be82754/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte (L61-L92)
to add this:

const init = async () => {
    // ... existing code ...

    // Group MCP tools by server
    let mcpServers = {};
    for (const toolId in tools) {
        if (toolId.startsWith('server:mcp:')) {
            const parts = toolId.split(':');
            if (parts.length >= 4) {
                // Individual MCP tool: server:mcp:server_id:tool_name
                const serverId = parts[2];
                const serverName = tools[toolId].meta?.server_name || serverId;

                if (!mcpServers[serverId]) {
                    mcpServers[serverId] = {
                        id: serverId,
                        name: serverName,
                        tools: []
                    };
                }
                mcpServers[serverId].tools.push({
                    id: toolId,
                    ...tools[toolId]
                });
            }
        }
    }
};

& modify the tabs 292be82754/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte (L116-L144)
to:

{#if tab === ''}
    <!-- Main menu -->
    {#if Object.keys(mcpServers).length > 0}
        <button
            class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
            on:click={() => {
                tab = 'mcp-servers';
            }}
        >
            <Wrench />
            <div class="flex items-center w-full justify-between">
                <div class="line-clamp-1">
                    {$i18n.t('MCP Servers')}
                    <span class="ml-0.5 text-gray-500">{Object.keys(mcpServers).length}</span>
                </div>
                <div class="text-gray-500">
                    <ChevronRight />
                </div>
            </div>
        </button>
    {/if}

    <!-- Other tools button for non-MCP tools -->
    {#if Object.keys(tools).filter(id => !id.startsWith('server:mcp:')).length > 0}
        <button
            class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
            on:click={() => {
                tab = 'tools';
            }}
        >
            <Wrench />
            <div class="flex items-center w-full justify-between">
                <div class="line-clamp-1">{$i18n.t('Other Tools')}</div>
                <div class="text-gray-500"><ChevronRight /></div>
            </div>
        </button>
    {/if}

{:else if tab === 'mcp-servers'}
    <!-- MCP Servers list -->
    <div in:fly={{ x: 20, duration: 150 }}>
        <button
            class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
            on:click={() => {
                tab = '';
            }}
        >
            <ChevronLeft />
            <div class="flex items-center w-full justify-between">
                <div>{$i18n.t('MCP Servers')}</div>
            </div>
        </button>

        {#each Object.values(mcpServers) as server}
            <button
                class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
                on:click={() => {
                    selectedMcpServerId = server.id;
                    tab = 'mcp-tools';
                }}
            >
                <div class="flex-1 truncate">
                    <div class="truncate">{server.name}</div>
                    <div class="text-xs text-gray-500">{server.tools.length} tools</div>
                </div>
                <div class="text-gray-500">
                    <ChevronRight />
                </div>
            </button>
        {/each}
    </div>

{:else if tab === 'mcp-tools' && selectedMcpServerId}
    <!-- Individual MCP server tools -->
    <div in:fly={{ x: 20, duration: 150 }}>
        <button
            class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
            on:click={() => {
                tab = 'mcp-servers';
                selectedMcpServerId = null;
            }}
        >
            <ChevronLeft />
            <div class="flex items-center w-full justify-between">
                <div>{mcpServers[selectedMcpServerId].name}</div>
            </div>
        </button>

        {#each mcpServers[selectedMcpServerId].tools as tool}
            <button
                class="relative flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50"
                on:click={async () => {
                    tools[tool.id].enabled = !tools[tool.id].enabled;
                    const state = tools[tool.id].enabled;
                    await tick();

                    if (state) {
                        selectedToolIds = [...selectedToolIds, tool.id];
                    } else {
                        selectedToolIds = selectedToolIds.filter((id) => id !== tool.id);
                    }
                }}
            >
                <div class="flex-1 truncate">
                    <div class="truncate">{tool.name}</div>
                    {#if tool.description}
                        <div class="text-xs text-gray-500 truncate">{tool.description}</div>
                    {/if}
                </div>
                <div class="shrink-0">
                    <Switch state={tools[tool.id].enabled} />
                </div>
            </button>
        {/each}
    </div>
{/if}
<!-- gh-comment-id:3468165335 --> @rgaricano commented on GitHub (Oct 30, 2025): This way all tools are individually displayed in the integration menu, for have its in the integration menu in a MCP Server submenu are necessary this changes: add `let selectedMcpServerId = null;` in https://github.com/open-webui/open-webui/blob/292be82754136cc10fcd2707d78a2edfec6764d0/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte#L49 change https://github.com/open-webui/open-webui/blob/292be82754136cc10fcd2707d78a2edfec6764d0/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte#L61-L92 to add this: ``` const init = async () => { // ... existing code ... // Group MCP tools by server let mcpServers = {}; for (const toolId in tools) { if (toolId.startsWith('server:mcp:')) { const parts = toolId.split(':'); if (parts.length >= 4) { // Individual MCP tool: server:mcp:server_id:tool_name const serverId = parts[2]; const serverName = tools[toolId].meta?.server_name || serverId; if (!mcpServers[serverId]) { mcpServers[serverId] = { id: serverId, name: serverName, tools: [] }; } mcpServers[serverId].tools.push({ id: toolId, ...tools[toolId] }); } } } }; ``` & modify the tabs https://github.com/open-webui/open-webui/blob/292be82754136cc10fcd2707d78a2edfec6764d0/src/lib/components/chat/MessageInput/IntegrationsMenu.svelte#L116-L144 to: ``` {#if tab === ''} <!-- Main menu --> {#if Object.keys(mcpServers).length > 0} <button class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={() => { tab = 'mcp-servers'; }} > <Wrench /> <div class="flex items-center w-full justify-between"> <div class="line-clamp-1"> {$i18n.t('MCP Servers')} <span class="ml-0.5 text-gray-500">{Object.keys(mcpServers).length}</span> </div> <div class="text-gray-500"> <ChevronRight /> </div> </div> </button> {/if} <!-- Other tools button for non-MCP tools --> {#if Object.keys(tools).filter(id => !id.startsWith('server:mcp:')).length > 0} <button class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={() => { tab = 'tools'; }} > <Wrench /> <div class="flex items-center w-full justify-between"> <div class="line-clamp-1">{$i18n.t('Other Tools')}</div> <div class="text-gray-500"><ChevronRight /></div> </div> </button> {/if} {:else if tab === 'mcp-servers'} <!-- MCP Servers list --> <div in:fly={{ x: 20, duration: 150 }}> <button class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={() => { tab = ''; }} > <ChevronLeft /> <div class="flex items-center w-full justify-between"> <div>{$i18n.t('MCP Servers')}</div> </div> </button> {#each Object.values(mcpServers) as server} <button class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={() => { selectedMcpServerId = server.id; tab = 'mcp-tools'; }} > <div class="flex-1 truncate"> <div class="truncate">{server.name}</div> <div class="text-xs text-gray-500">{server.tools.length} tools</div> </div> <div class="text-gray-500"> <ChevronRight /> </div> </button> {/each} </div> {:else if tab === 'mcp-tools' && selectedMcpServerId} <!-- Individual MCP server tools --> <div in:fly={{ x: 20, duration: 150 }}> <button class="flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={() => { tab = 'mcp-servers'; selectedMcpServerId = null; }} > <ChevronLeft /> <div class="flex items-center w-full justify-between"> <div>{mcpServers[selectedMcpServerId].name}</div> </div> </button> {#each mcpServers[selectedMcpServerId].tools as tool} <button class="relative flex w-full justify-between gap-2 items-center px-3 py-1.5 text-sm cursor-pointer rounded-xl hover:bg-gray-50 dark:hover:bg-gray-800/50" on:click={async () => { tools[tool.id].enabled = !tools[tool.id].enabled; const state = tools[tool.id].enabled; await tick(); if (state) { selectedToolIds = [...selectedToolIds, tool.id]; } else { selectedToolIds = selectedToolIds.filter((id) => id !== tool.id); } }} > <div class="flex-1 truncate"> <div class="truncate">{tool.name}</div> {#if tool.description} <div class="text-xs text-gray-500 truncate">{tool.description}</div> {/if} </div> <div class="shrink-0"> <Switch state={tools[tool.id].enabled} /> </div> </button> {/each} </div> {/if} ```
Author
Owner

@tjbck commented on GitHub (Oct 30, 2025):

PLEASE check for existing issues/discussions. Intended behaviour, open to discussions.

<!-- gh-comment-id:3469282539 --> @tjbck commented on GitHub (Oct 30, 2025): PLEASE check for existing issues/discussions. Intended behaviour, open to discussions.
Author
Owner

@touseefspeaks commented on GitHub (Oct 31, 2025):

@tjbck.. Could you please confirm whether the changes outlined above by @rgaricano will be implemented?
This would make usage more intuitive.

<!-- gh-comment-id:3471361696 --> @touseefspeaks commented on GitHub (Oct 31, 2025): @tjbck.. Could you please confirm whether the changes outlined above by @rgaricano will be implemented? This would make usage more intuitive.
Author
Owner

@rgaricano commented on GitHub (Oct 31, 2025):

He already said:

Intended behaviour, open to discussions.

(There are other circunstances to valorate, as possible "errors" if enabling/disabling individual tools of the same server, loads,...)

<!-- gh-comment-id:3472515863 --> @rgaricano commented on GitHub (Oct 31, 2025): He already said: > Intended behaviour, open to discussions. (There are other circunstances to valorate, as possible "errors" if enabling/disabling individual tools of the same server, loads,...)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#34218