fix(mcp): default available_on_public_internet to true (#22331)

* fix(mcp): default available_on_public_internet to true

MCPs were defaulting to private (available_on_public_internet=false) which
was a breaking change. This reverts the default to public (true) across:
- Pydantic models (AddMCPServerRequest, UpdateMCPServerRequest, LiteLLM_MCPServerTable)
- Prisma schema @default
- mcp_server_manager.py YAML config + DB loading fallbacks
- UI form initialValue and setFieldValue defaults

* fix(ui): add forceRender to Collapse.Panel so toggle defaults render correctly

Ant Design's Collapse.Panel lazy-renders children by default. Without
forceRender, the Form.Item for 'Available on Public Internet' isn't
mounted when the useEffect fires form.setFieldValue, causing the Switch
to visually show OFF even though the intended default is true.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix(mcp): update remaining schema copies and MCPServer type default to true

Missed in previous commit per Greptile review:
- schema.prisma (root)
- litellm-proxy-extras/litellm_proxy_extras/schema.prisma
- litellm/types/mcp_server/mcp_server_manager.py MCPServer class

* ui(mcp): reframe network access as 'Internal network only' restriction

Replace scary 'Available on Public Internet' toggle with 'Internal network only'
opt-in restriction. Toggle OFF (default) = all networks allowed. Toggle ON =
restricted to internal network only. Auth is always required either way.

- MCPPermissionManagement: new label/tooltip/description, invert display via
  getValueProps/getValueFromEvent so underlying available_on_public_internet
  value is unchanged
- mcp_server_view: 'Public' → 'All networks', 'Internal' → 'Internal only' (orange)
- mcp_server_columns: same badge updates

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
This commit is contained in:
Ishaan Jaff
2026-02-27 20:06:07 -08:00
committed by GitHub
co-authored by Cursor Agent Ishaan Jaff
parent bffce842a1
commit eea083fa4b
10 changed files with 80 additions and 22 deletions
@@ -300,7 +300,7 @@ model LiteLLM_MCPServerTable {
token_url String?
registration_url String?
allow_all_keys Boolean @default(false)
available_on_public_internet Boolean @default(false)
available_on_public_internet Boolean @default(true)
}
// Generate Tokens for Proxy
@@ -25157,6 +25157,25 @@
"supports_vision": true,
"tool_use_system_prompt_tokens": 159
},
"openrouter/anthropic/claude-opus-4.6": {
"cache_creation_input_token_cost": 6.25e-06,
"cache_read_input_token_cost": 5e-07,
"input_cost_per_token": 5e-06,
"litellm_provider": "openrouter",
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 2.5e-05,
"supports_assistant_prefill": true,
"supports_computer_use": true,
"supports_function_calling": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_tool_choice": true,
"supports_vision": true,
"tool_use_system_prompt_tokens": 346
},
"openrouter/anthropic/claude-sonnet-4.5": {
"input_cost_per_image": 0.0048,
"cache_creation_input_token_cost": 3.75e-06,
@@ -26169,6 +26188,42 @@
"supports_prompt_caching": true,
"supports_computer_use": false
},
"openrouter/openrouter/auto": {
"input_cost_per_token": 0,
"output_cost_per_token": 0,
"litellm_provider": "openrouter",
"max_input_tokens": 2000000,
"max_tokens": 2000000,
"mode": "chat",
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_vision": true,
"supports_audio_input": true,
"supports_video_input": true
},
"openrouter/openrouter/free": {
"input_cost_per_token": 0,
"output_cost_per_token": 0,
"litellm_provider": "openrouter",
"max_input_tokens": 200000,
"max_tokens": 200000,
"mode": "chat",
"supports_function_calling": true,
"supports_tool_choice": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_vision": true
},
"openrouter/openrouter/bodybuilder": {
"input_cost_per_token": 0,
"output_cost_per_token": 0,
"litellm_provider": "openrouter",
"max_input_tokens": 128000,
"max_tokens": 128000,
"mode": "chat"
},
"ovhcloud/DeepSeek-R1-Distill-Llama-70B": {
"input_cost_per_token": 6.7e-07,
"litellm_provider": "ovhcloud",
@@ -331,7 +331,7 @@ class MCPServerManager:
static_headers=server_config.get("static_headers", None),
allow_all_keys=bool(server_config.get("allow_all_keys", False)),
available_on_public_internet=bool(
server_config.get("available_on_public_internet", False)
server_config.get("available_on_public_internet", True)
),
)
self.config_mcp_servers[server_id] = new_server
@@ -634,7 +634,7 @@ class MCPServerManager:
disallowed_tools=getattr(mcp_server, "disallowed_tools", None),
allow_all_keys=mcp_server.allow_all_keys,
available_on_public_internet=bool(
getattr(mcp_server, "available_on_public_internet", False)
getattr(mcp_server, "available_on_public_internet", True)
),
updated_at=getattr(mcp_server, "updated_at", None),
)
+3 -3
View File
@@ -1093,7 +1093,7 @@ class NewMCPServerRequest(LiteLLMPydanticObjectBase):
token_url: Optional[str] = None
registration_url: Optional[str] = None
allow_all_keys: bool = False
available_on_public_internet: bool = False
available_on_public_internet: bool = True
@model_validator(mode="before")
@classmethod
@@ -1147,7 +1147,7 @@ class UpdateMCPServerRequest(LiteLLMPydanticObjectBase):
token_url: Optional[str] = None
registration_url: Optional[str] = None
allow_all_keys: bool = False
available_on_public_internet: bool = False
available_on_public_internet: bool = True
@model_validator(mode="before")
@classmethod
@@ -1204,7 +1204,7 @@ class LiteLLM_MCPServerTable(LiteLLMPydanticObjectBase):
token_url: Optional[str] = None
registration_url: Optional[str] = None
allow_all_keys: bool = False
available_on_public_internet: bool = False
available_on_public_internet: bool = True
class MakeMCPServersPublicRequest(LiteLLMPydanticObjectBase):
+1 -1
View File
@@ -300,7 +300,7 @@ model LiteLLM_MCPServerTable {
token_url String?
registration_url String?
allow_all_keys Boolean @default(false)
available_on_public_internet Boolean @default(false)
available_on_public_internet Boolean @default(true)
}
// Generate Tokens for Proxy
@@ -52,7 +52,7 @@ class MCPServer(BaseModel):
env: Optional[Dict[str, str]] = None
access_groups: Optional[List[str]] = None
allow_all_keys: bool = False
available_on_public_internet: bool = False
available_on_public_internet: bool = True
updated_at: Optional[datetime] = None
model_config = ConfigDict(arbitrary_types_allowed=True)
+1 -1
View File
@@ -300,7 +300,7 @@ model LiteLLM_MCPServerTable {
token_url String?
registration_url String?
allow_all_keys Boolean @default(false)
available_on_public_internet Boolean @default(false)
available_on_public_internet Boolean @default(true)
}
// Generate Tokens for Proxy
@@ -46,7 +46,7 @@ const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
}
} else {
form.setFieldValue("allow_all_keys", false);
form.setFieldValue("available_on_public_internet", false);
form.setFieldValue("available_on_public_internet", true);
}
}, [mcpServer, form]);
@@ -64,6 +64,7 @@ const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
}
key="permissions"
className="border-0"
forceRender
>
<div className="space-y-6 pt-4">
<div className="flex items-start justify-between gap-4">
@@ -89,17 +90,19 @@ const MCPPermissionManagement: React.FC<MCPPermissionManagementProps> = ({
<div className="flex items-start justify-between gap-4">
<div>
<span className="text-sm font-medium text-gray-700 flex items-center">
Available on Public Internet
<Tooltip title="When enabled, this MCP server is accessible from external/public IPs (e.g., ChatGPT). When disabled, only callers from internal/private networks can access it.">
Internal network only
<Tooltip title="When on, only requests from within your internal network are accepted. Turn off to allow external clients (other clusters, ChatGPT, etc). API key authentication is always required regardless of this setting.">
<InfoCircleOutlined className="ml-2 text-blue-400 hover:text-blue-600 cursor-help" />
</Tooltip>
</span>
<p className="text-sm text-gray-600 mt-1">Enable if this server should be reachable from the public internet.</p>
<p className="text-sm text-gray-600 mt-1">Turn on to restrict access to callers within your internal network only.</p>
</div>
<Form.Item
name="available_on_public_internet"
valuePropName="checked"
initialValue={mcpServer?.available_on_public_internet ?? false}
getValueProps={(value) => ({ checked: !value })}
getValueFromEvent={(checked: boolean) => !checked}
initialValue={true}
className="mb-0"
>
<Switch />
@@ -157,9 +157,9 @@ export const mcpServerColumns = (
cell: ({ row }) => {
const isPublic = row.original.available_on_public_internet;
return isPublic ? (
<span className="px-2 py-0.5 bg-green-50 text-green-700 rounded text-xs font-medium">Public</span>
<span className="px-2 py-0.5 bg-green-50 text-green-700 rounded text-xs font-medium">All networks</span>
) : (
<span className="px-2 py-0.5 bg-gray-100 text-gray-600 rounded text-xs font-medium">Internal</span>
<span className="px-2 py-0.5 bg-orange-50 text-orange-700 rounded text-xs font-medium">Internal only</span>
);
},
},
@@ -251,20 +251,20 @@ export const MCPServerView: React.FC<MCPServerViewProps> = ({
</div>
</div>
<div>
<Text className="font-medium">Available on Public Internet</Text>
<Text className="font-medium">Network Access</Text>
<div className="flex items-center gap-2">
{mcpServer.available_on_public_internet ? (
<span className="px-2 py-1 bg-green-50 text-green-700 rounded-md text-sm">
Public
All networks
</span>
) : (
<span className="px-2 py-1 bg-gray-100 text-gray-600 rounded-md text-sm">
Internal
<span className="px-2 py-1 bg-orange-50 text-orange-700 rounded-md text-sm">
Internal only
</span>
)}
{mcpServer.available_on_public_internet && (
{!mcpServer.available_on_public_internet && (
<Text className="text-xs text-gray-500">
Accessible from external/public IPs
Restricted to internal network
</Text>
)}
</div>