diff --git a/docs/my-website/docs/mcp.md b/docs/my-website/docs/mcp.md index 8c11b8fd654..b25c58d3f93 100644 --- a/docs/my-website/docs/mcp.md +++ b/docs/my-website/docs/mcp.md @@ -198,6 +198,7 @@ mcp_servers: - `http` - Streamable HTTP transport - `stdio` - Standard Input/Output transport - **Command**: The command to execute for stdio transport (required for stdio) +- **allow_all_keys**: Set to `true` to make the server available to every LiteLLM API key, even if the key/team doesn't list the server in its MCP permissions. - **Args**: Array of arguments to pass to the command (optional for stdio) - **Env**: Environment variables to set for the stdio process (optional for stdio) - **Description**: Optional description for the server diff --git a/docs/my-website/docs/mcp_control.md b/docs/my-website/docs/mcp_control.md index c8c3d8e10f3..2a3a7bc5a05 100644 --- a/docs/my-website/docs/mcp_control.md +++ b/docs/my-website/docs/mcp_control.md @@ -13,6 +13,7 @@ LiteLLM provides fine-grained permission management for MCP servers, allowing yo - **Restrict MCP access by entity**: Control which keys, teams, or organizations can access specific MCP servers - **Tool-level filtering**: Automatically filter available tools based on entity permissions - **Centralized control**: Manage all MCP permissions from the LiteLLM Admin UI or API +- **One-click public MCPs**: Mark specific servers as available to every LiteLLM API key when you don't need per-key restrictions This ensures that only authorized entities can discover and use MCP tools, providing an additional security layer for your MCP infrastructure. @@ -95,6 +96,48 @@ mcp_servers: - If you specify both `allowed_tools` and `disallowed_tools`, the allowed list takes priority - Tool names are case-sensitive +## Public MCP Servers (allow_all_keys) + +Some MCP servers are meant to be shared broadly—think internal knowledge bases, calendar integrations, or other low-risk utilities where every team should be able to connect without requesting access. Instead of adding those servers to every key, team, or organization, enable the new `allow_all_keys` toggle. + + + + +1. Open **MCP Servers → Add / Edit** in the Admin UI. +2. Expand **Permission Management / Access Control**. +3. Toggle **Allow All LiteLLM Keys** on. + +Allow all LiteLLM keys toggle in MCP UI + +The toggle makes the server “public” without touching existing access groups. + + + + +Set `allow_all_keys: true` to mark the server as public: + +```yaml title="Make an MCP server public" showLineNumbers +mcp_servers: + deepwiki: + url: https://mcp.deepwiki.com/mcp + allow_all_keys: true +``` + + + + +### When to use it + +- You have shared MCP utilities where fine-grained ACLs would only add busywork. +- You want a “default enabled” experience for internal users, while still being able to layer tool-level restrictions. +- You’re onboarding new teams and want the safest MCPs available out of the box. + +Once enabled, LiteLLM automatically includes the server for every key during tool discovery/calls—no extra virtual-key or team configuration is required. + --- ## Allow/Disallow MCP Tool Parameters diff --git a/docs/my-website/img/mcp_oauth.png b/docs/my-website/img/mcp_oauth.png new file mode 100644 index 00000000000..e504ccc86bb Binary files /dev/null and b/docs/my-website/img/mcp_oauth.png differ diff --git a/ui/litellm-dashboard/src/components/mcp_tools/MCPPermissionManagement.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/MCPPermissionManagement.test.tsx new file mode 100644 index 00000000000..3784680062c --- /dev/null +++ b/ui/litellm-dashboard/src/components/mcp_tools/MCPPermissionManagement.test.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, it, expect } from "vitest"; +import { Form } from "antd"; + +import MCPPermissionManagement from "./MCPPermissionManagement"; + +const defaultProps = { + availableAccessGroups: [], + mcpServer: null, + searchValue: "", + setSearchValue: () => {}, + getAccessGroupOptions: () => [], +}; + +describe("MCPPermissionManagement", () => { +const expandPanel = async () => { + const user = userEvent.setup(); + const headerButton = screen.getByRole("button", { + name: /permission management/i, + }); + await user.click(headerButton); + return user; +}; + +const renderWithForm = (props = {}) => { + const Wrapper: React.FC = ({ children }) => { + const [form] = Form.useForm(); + return ( +
+ {children} +
+ ); + }; + + return render( + + + , + ); +}; + + it("should default allow_all_keys switch to unchecked for new servers", async () => { + renderWithForm(); + await expandPanel(); + const toggle = screen.getByRole("switch"); + expect(toggle).toHaveAttribute("aria-checked", "false"); + }); + + it("should reflect allow_all_keys when editing an existing server", async () => { + renderWithForm({ + mcpServer: { + server_id: "server-1", + url: "https://example.com", + created_at: "2024-01-01T00:00:00Z", + created_by: "user", + updated_at: "2024-01-01T00:00:00Z", + updated_by: "user", + allow_all_keys: true, + }, + }); + + const user = await expandPanel(); + const toggle = screen.getByRole("switch"); + expect(toggle).toHaveAttribute("aria-checked", "true"); + + await user.click(toggle); + expect(toggle).toHaveAttribute("aria-checked", "false"); + }); +});