Skip to content

refactor(ui): migrate mcp-servers, tag-management, tool-policies to shadcn - #34469

Merged
yuneng-berri merged 4 commits into
litellm_internal_stagingfrom
litellm_/blissful-torvalds-5a5be3
Jul 24, 2026
Merged

refactor(ui): migrate mcp-servers, tag-management, tool-policies to shadcn#34469
yuneng-berri merged 4 commits into
litellm_internal_stagingfrom
litellm_/blissful-torvalds-5a5be3

Conversation

@yuneng-berri

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • mcp-servers, tag-management and tool-policies still render antd and Tremor
  • Three separate PRs for three small pages is wasteful review overhead

How it solves it:

  • Moves the 18 files these routes exclusively own onto shadcn primitives
  • Markup only; no behaviour, no data flow and no copy changed
  • One PR, because the three routes' file sets are disjoint

Relevant issues

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

Screenshots are in the local visual-gate baselines; drag them into this description:

  • before: /private/tmp/claude-501/-Users-yunengjiang-development-litellm--claude-worktrees-verify-veria-fixes-855b22/5c1d7cd1-1675-4378-b4f5-06aedca51f82/scratchpad/before/{mcp-servers,tag-management,tool-policies}-before.png
  • after: /private/tmp/claude-501/-Users-yunengjiang-development-litellm--claude-worktrees-verify-veria-fixes-855b22/5c1d7cd1-1675-4378-b4f5-06aedca51f82/scratchpad/after/{mcp-servers,tag-management,tool-policies}-after.png

Visual blast-radius check, run against a live proxy with a seeded postgres and the dashboard dev server, photographing all 35 dashboard routes at 1280x720:

  • mcp-servers and tag-management moved, and were deliberately re-baselined
  • tool-policies is byte-identical before and after, which is correct: its three files are a tooltip, a policy dropdown and a drill-in detail view, none of which render on the page's default state
  • the other 32 routes are pixel-identical, so nothing shared moved

Because the gate's fixture has no MCP servers, it only photographs empty states. The card grid, server detail and tools viewer were checked separately against a live stack with three real MCP servers created through POST /v1/mcp/server, driven at a deliberately short 1280x600 viewport to catch clipping the fixed-height snapshot cannot see. Confirmed there: the card grid with health, transport, auth, visibility and access-group badges; the overflow menu with Test Connection and Delete; the delete confirmation showing name, id and URL; the server detail tabs and overview cards; and the tools viewer. main.scrollHeight exceeded clientHeight and scrolled to the bottom on every view, with no horizontal overflow

Reviewer click-through on a local proxy:

  1. Open http://localhost:4000/ui/?page=mcp-servers and confirm the Team, Access Group and Sort dropdowns read "All Servers", "All Access Groups" and "Recently created" rather than raw values
  2. Add a server, then confirm its card shows the health, transport, auth and Public/Internal badges, and that the overflow menu offers Test Connection and Delete
  3. Click Delete and confirm the dialog lists name, id and URL, and that Cancel leaves the server in place
  4. Open the server, walk Overview / MCP Tools / Settings, and confirm the Settings rows and badges render
  5. Open http://localhost:4000/ui/?page=tag-management and confirm the create button and the refresh control
  6. Open http://localhost:4000/ui/?page=tool-policies, open a tool, and confirm the input and output policy dropdowns show their current policy and save a change
  7. Shrink the window to roughly 600px tall on each page and confirm content scrolls rather than clipping

Type

🧹 Refactoring

Changes

The scope was picked mechanically from each route's real import closure, not by reading, so the three sets are disjoint and nothing shared is touched

mcp-servers (14 files)

MCPLogoSelector, MCPNetworkSettings, MCPServerCard, OpenAPIQuickPicker, TruePassthroughWarning, mcp_connection_status, mcp_discovery, mcp_server_cost_config, mcp_server_cost_display, mcp_server_view, mcp_servers, mcp_tool_configuration, mcp_tools, and MCPSemanticFilterTestPanel

tag-management (1 file)

tag-management/_components/index.tsx

tool-policies (3 files)

ToolDetail, ToolPolicies/PolicySelect, ToolPolicies/ToolPoliciesTableColumns

Not touched, and why:

  • SHARED, reached by more than one route, so a page PR must not change them: notifications_manager and message_manager (53 pages each), DeleteResourceModal (23), numerical_input (14), team_dropdown (13), ModelSelector (11), McpCrudPermissionPanel (10), the Fallbacks and router-settings components (11 each), the whole view_logs tree (3 each), and the rest of the analyzer's SHARED bucket. These belong to the shared-component track
  • DEFERRED, contains an antd Form, blocked until refactor(proxy): type the PATCH /team/{team_id} request body #34195: 17 files under mcp-servers (create_mcp_server, mcp_server_edit, mcp_connect, EnvVarsSection, OAuthFormFields, StdioConfiguration, MCPToolsetsTab, ToolTestPanel, UserEnvVarsModal and the rest), plus CreateTagModal and tag_info on tag-management
  • TABLE: none; all three routes are table-free, so nothing went to the shared DataTable flow

Because mcp-servers keeps its 17 deferred form files and still imports shared components, that page continues to load antd after this PR. tag-management and tool-policies are built almost entirely from shared components (34 and 26 reaching those pages), so they own very little and their rendering barely moves

Two commits, deliberately: the first rewrites the markup-coupled assertions onto role and text queries and adds characterisation tests for the nine route-owned components that had none, all proven green against the antd components; the second is the migration and edits no test. A test that was written against the old markup and still passes against the new markup without being touched is the actual evidence here

Also prunes the six no-restricted-imports antd suppressions these files no longer need, so the baseline ratchets down

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

… before the shadcn migration

Rewrite the two markup-coupled assertions off antd class selectors and onto
role/text queries, and add characterisation tests for the nine route-owned
components that had none. Both rewritten tests and all nine new ones are green
against the current antd and Tremor components, so the migration that follows
can be judged by tests it never touched.
…o shadcn

Replaces antd and Tremor with shadcn primitives across the 18 files these three
routes exclusively own. Markup only: no behaviour, data flow or copy changed, and
no shared or form-bearing component is touched, so the blast radius stops at
these pages.

The 12 tests covering these components are unchanged from the previous commit and
still pass, which is the evidence that the rewrite preserved behaviour. Also
prunes the six antd no-restricted-imports suppressions these files no longer
need.
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR migrates route-owned MCP server, tag management, and tool policy UI components from Ant Design and Tremor to shadcn primitives

  • Adds characterization and accessibility-focused component tests
  • Replaces the previously click-only suggested CIDR badge with a keyboard-accessible button
  • Removes obsolete Ant Design lint suppressions

Confidence Score: 5/5

The PR appears safe to merge because the previously reported accessibility failure is fully addressed and no related blocking failure remains

No blocking failure remains

Important Files Changed

Filename Overview
ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPNetworkSettings.tsx Migrates the network settings controls to shadcn and fully addresses the prior keyboard-accessibility thread by using a native button
ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/MCPNetworkSettings.test.tsx Adds regression coverage confirming that the suggested CIDR control is focusable and activates with the keyboard
ui/litellm-dashboard/src/app/(dashboard)/mcp-servers/_components/mcp_servers.tsx Migrates the MCP server listing and filtering interface to shadcn primitives
ui/litellm-dashboard/src/app/(dashboard)/tag-management/_components/index.tsx Migrates the tag management page-owned interface to shadcn primitives
ui/litellm-dashboard/src/components/ToolPolicies/PolicySelect.tsx Migrates the tool policy selector while retaining its existing selection behavior

Reviews (2): Last reviewed commit: "fix(ui): make the suggested MCP network ..." | Re-trigger Greptile

The suggested CIDR chip was a click-only span both before and after the shadcn
migration, so keyboard users could not reach or activate it. Render it as a
Button, which brings focus and Enter/Space activation with it, and cover the
keyboard path with a test that fails against the old span.
@yuneng-berri

Copy link
Copy Markdown
Contributor Author

@greptile

@devin-ai-integration

Copy link
Copy Markdown
Contributor

QA — live runtime verification

Built this PR's dashboard, served it from a live proxy on localhost:4000 (Postgres, dev_config.yaml), logged in as admin, seeded 3 MCP servers, and discovered a real get_weather tool by making a live Anthropic tool_calls completion through the proxy. Walked all three migrated routes in the UI. Everything works and I saw no functional regressions; CI is fully green.

One non-blocking note: the only bot comment (Greptile P2) is that the suggested-CIDR badge in MCPNetworkSettings is click-only / keyboard-inaccessible. That's a pre-existing accessibility nit, not a functional break.

Results

  • mcp-servers grid renders count "3"; filter dropdowns show labels All Servers / All Access Groups / Recently created (not raw values)
  • all 3 cards show health/transport/auth/visibility badges (HTTP, SSE, api_key, none, bearer_token, Public)
  • overflow menu has Test Connection + Delete; delete dialog lists name/ID/URL and Cancel is a no-op
  • server detail exposes Overview / MCP Tools / Settings tabs; Settings renders the full config form
  • tag-management renders create + refresh + table; create opens the modal
  • tool-policies Input Policy dropdown lists exactly untrusted/trusted/blocked; changing untrusted -> trusted persists after reload and in the DB (LiteLLM_ToolTable.input_policy = trusted)
  • ToolDetail drill-in opens with policy sections, block-for-team, recent logs
  • (regression) at ~600px viewport content scrolls without clipping

MCP Servers grid + badges

mcp-servers

Delete confirmation dialog (name / ID / URL)

delete dialog

Server detail — Settings tab

settings

Tag Management — create modal

tag modal

Tool Policies — dropdown change persisted (trusted)

tool policies

Tool detail drill-in

tool detail

QA performed by Devin: https://app.devin.ai/sessions/2e2a2f341b3c40dd8a26bfe8846f5049

@yuneng-berri
yuneng-berri merged commit 5e98e8f into litellm_internal_staging Jul 24, 2026
75 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_/blissful-torvalds-5a5be3 branch July 24, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants