Commit graph

35926 commits

Author SHA1 Message Date
yuneng-jiang
456e326c95 fix(ui): reduce MCP table columns and add explicit column widths
Removed low-value columns (Alias, Auth Type, Updated) to reduce
horizontal overflow. Added explicit size hints to remaining columns.
DataTable now applies column sizes to header and body cells.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:11:22 -07:00
yuneng-jiang
a022956724 fix: propagate team_id through MCPServer registry and list responses
Added team_id to the MCPServer model class, build_mcp_server_from_table,
and _build_mcp_server_table so team_id flows from DB → registry →
list endpoint responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:08:00 -07:00
yuneng-jiang
478ec3d392 fix(ui): remove early loading return, let DataTable handle loading state
The early return on missing auth params blocked the entire page from
rendering. The hooks already guard on accessToken being available, and
DataTable shows its own loading state via isLoading prop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:04:30 -07:00
yuneng-jiang
baa1fa4151 feat(ui): add Team (Owner) column to MCP servers table
Shows the owning team alias resolved from team_id. Global servers
(team_id=null) display "Global". Header includes info icon explaining
that only servers from teams with mcp:read permission are visible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:03:25 -07:00
yuneng-jiang
79ca00bbec fix(ui): show helpful empty state for internal users without MCP access
The list endpoint returns an empty list (not 403) when a user has no
MCP servers available. For internal users, show a message suggesting
they may need mcp:read permission or team MCP server assignments.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:59:44 -07:00
yuneng-jiang
017d87b7ab fix(ui): show helpful error when user lacks MCP read permission
Replace "Missing required authentication parameters" with a loading
state. When the MCP servers fetch fails (e.g. 403), show a clear
error message with steps on how to get mcp:read permission.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:58:38 -07:00
yuneng-jiang
535c368f3b fix: proxy admin delete now cleans up ObjectPermissionTable
When a proxy admin deleted an MCP server, team_id was None so
remove_mcp_server_from_team was skipped, leaving stale server IDs
in the team's ObjectPermissionTable. Now fetches the server's
team_id before deletion to ensure cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:50:12 -07:00
yuneng-jiang
e4611faf58 fix: invalidate ObjectPermissionTable cache alongside team cache
_invalidate_team_cache only cleared the team object cache but not the
ObjectPermissionTable cache. After add_mcp_server_to_team, the team
was re-fetched from DB but its object_permission was served from stale
cache, causing newly created servers to not appear in the list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:46:33 -07:00
yuneng-jiang
bb019c8920 fix: ownership transfer DB writes and registry reload ordering
Move team_id clear-to-null and ObjectPermissionTable sync before
registry reload so the cache reflects the new ownership state.
Also update the response object when clearing team_id to null.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:36:50 -07:00
yuneng-jiang
bdab813f21 test: add MCP server team ownership tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:28:24 -07:00
yuneng-jiang
5151a835a3 chore: remove unused get_objectpermissions_for_mcp_server import 2026-03-21 12:24:48 -07:00
yuneng-jiang
f51078761a types(ui): add team_id to MCPServer interface 2026-03-21 12:24:41 -07:00
yuneng-jiang
4dd2089eee feat: update endpoint uses server.team_id for auth, supports ownership transfer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:24:00 -07:00
yuneng-jiang
c99257ddd4 feat: delete endpoint uses server.team_id for ownership auth
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:20:43 -07:00
yuneng-jiang
9ff49bc75b feat: set team_id ownership on MCP server creation, registration, and approval
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:18:01 -07:00
yuneng-jiang
cc17c370de types: add team_id to MCPServerTable and UpdateMCPServerRequest models 2026-03-21 12:15:09 -07:00
yuneng-jiang
c893324a5b schema: add team_id column to LiteLLM_MCPServerTable for ownership tracking 2026-03-21 12:14:49 -07:00
yuneng-jiang
334c455150 db: persist team_id on MCP server create and update 2026-03-21 12:14:43 -07:00
yuneng-jiang
31bc13eb17 Merge branch 'main' into litellm_yj_march_20_2026 2026-03-21 10:27:05 -07:00
yuneng-jiang
185db1941f
Merge pull request #24075 from BerriAI/litellm_search-tool-permissions-f5e4
[Feature] Search Tools: Add access control via object permissions
2026-03-21 10:23:08 -07:00
yuneng-jiang
9051bf1e63 chore: remove migration file (will be created via standard process)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:07:15 -07:00
yuneng-jiang
2c4be6f5c7 fix: nullable schema, remove dead code, add return type annotation
- Make search_tools String[]? (nullable) in all 3 schema.prisma files
  so Prisma preserves NULL from DB instead of coercing to []
- Remove get_permitted_search_tool_names (dead code — never called
  from any production path) and its tests
- Add -> bool return type annotation to _can_object_call_search_tools

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:02:47 -07:00
yuneng-jiang
9019207111 fix: revert out-of-scope changes, fix remaining review feedback
- Revert MCP management endpoint changes: team-scoped CRUD depends on
  check_member_permission, add_mcp_server_to_team, remove_mcp_server_from_team
  which exist only in the base branch, not main. Importing them crashes
  all MCP endpoints on main.
- Revert ObjectPermissionTable default changes for pre-existing fields
  (mcp_servers, mcp_access_groups, vector_stores, agents, agent_access_groups)
  back to [] to avoid backwards-incompatible behavior change. Only
  search_tools (new field) uses None default.
- Restore vector store access check: [] = allow all (existing behavior)
- Restore vector store test assertion
- Revert common_utils.py inline import changes (infrastructure not in scope)
- Add ValueError fallback to get_search_tool_access_error_type_for_object
  for unrecognized object_type values

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 09:42:49 -07:00
yuneng-jiang
d1a0b94919 fix: address greptile feedback on search_tools RBAC
- Migration: remove DEFAULT ARRAY[]::TEXT[] so existing rows get NULL
  (NULL = all access) instead of [] (no access)
- Schema: remove @default([]) for search_tools in all 3 schema.prisma files
- Use cached get_object_permission instead of raw DB queries in
  search_tool_access_check and _get_allowed_search_tool_names
- Reject requests with missing search_tool_name (400) instead of
  silently bypassing access control
- Fix vector store test: [] now correctly denies access (not allows)
- Update search_tool_access_check tests to mock get_object_permission

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 09:28:08 -07:00
yuneng-jiang
071e590f80
Merge pull request #24274 from BerriAI/litellm_mcp_team_member_ui
[Feature] UI - MCP: Team member permissions drawer and CRUD access
2026-03-21 09:06:10 -07:00
yuneng-jiang
bca07dca61 fix: change ObjectPermissionTable defaults from [] to None, add team-scoped MCP RBAC
- Change all ObjectPermissionTable array field defaults from [] to None
  (None = all access / no restriction, [] = no access)
- Update vector store access check: [] now denies access instead of allowing all
- Add team-scoped MCP server management (create/update/delete) with
  granular permissions (mcp:create, mcp:update, mcp:delete)
- Auto-assign created servers to team's ObjectPermissionTable
- Auto-remove deleted servers from team's ObjectPermissionTable
- Fix unreachable special MCP server name guard in add_mcp_server
- Fix server_id validation ordering in edit_mcp_server
- Fix description typo on PUT /server endpoint
- Move inline imports to module level in common_utils.py (CLAUDE.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:37:20 -07:00
yuneng-jiang
5905100cdc address greptile review feedback (greploop iteration 3)
- Fix double error handling in getTeamPermissionsCall: return empty data
  on HTTP error instead of calling handleError + throwing, preventing
  duplicate error notifications

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:35:54 -07:00
yuneng-jiang
290706a708 address greptile review feedback (greploop iteration 3)
- Fix double error handling in getTeamPermissionsCall: return empty data
  on HTTP error instead of calling handleError + throwing, preventing
  duplicate error notifications

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:35:36 -07:00
yuneng-jiang
24be81094b address greptile review feedback (greploop iteration 2)
- Fix unknown permissions duplication: seed selected state with only known
  permissions so existingUnknown and selected are disjoint on save
- Disable Add MCP Server button for non-admins without a team selected,
  show tooltip explaining they need to select a team first

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:28:27 -07:00
yuneng-jiang
42fe911e1c address greptile review feedback (greploop iteration 1)
- Separate save failure from refresh failure: close drawer after successful
  save even if teamInfoCall refresh fails
- Preserve unknown permissions not in availablePermissions when saving,
  preventing silent drops of permissions from newer backend versions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:21:39 -07:00
yuneng-jiang
4f98b4ea3c address greptile review feedback
- Type onUpdate as () => Promise<void> and await it before closing drawer
- Replace accessToken! assertion with explicit null guard
- Gate fetchAvailableTeamMemberPermissions behind canEditTeam check
- Pass team_id for admins too when a team is selected in the filter

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:59:42 -07:00
yuneng-jiang
18fae5377e [Feature] UI - MCP: Team member permissions drawer and CRUD access
Add UI support for the MCP team management permissions introduced in PR #24266.

- Add MemberPermissionsDrawer component (Ant Design Drawer) for managing
  per-member MCP permissions (mcp:read, mcp:create, mcp:update, mcp:delete)
- Add permissions button to team member table actions column
- Fetch available permissions from GET /team/available_permissions
- Pass extra_permissions in team member update API calls
- Allow all users to create MCP servers directly (backend enforces permissions)
- Pass team_id when non-admin users create MCP servers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:52:55 -07:00
yuneng-jiang
db8050bb60
Merge pull request #24259 from BerriAI/litellm_ui_refactor_policy_versions_hook
[Refactor] UI - Policies: Extract usePolicyVersions Hook
2026-03-20 23:45:31 -07:00
yuneng-jiang
492c0cd3ba address greptile review feedback (greploop iteration 3)
- Move callbacks outside try/catch so only mutation errors are caught,
  not errors from onVersionCreated/onVersionStatusUpdated callbacks
- Replace policyName! non-null assertion with DISABLED_POLICY_KEY
  sentinel to avoid undefined in cache keys when query is disabled

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:39:01 -07:00
yuneng-jiang
41d12ed106 address greptile review feedback (greploop iteration 2)
- Add PolicyVersionsData type for select output; specify TData generic
  so consumers get Policy[] (not Policy[] | undefined) for versions
- Remove empty-string queryKey fallback — use policyName! since
  enabled:false prevents fetch when policyName is null
- Add cache invalidation tests for both mutation hooks
- Add explanatory comment for ?? [] fallback in component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:33:50 -07:00
yuneng-jiang
80e55804af [Fix] UI - Policies: Type accuracy and mutation guard for usePolicyVersions
- Make PolicyVersionsResponse.versions optional (Policy[] | undefined)
  to match real API shape — select fallback handles normalization
- Add policyName guard to useUpdatePolicyVersionStatus mutationFn
  to fail loudly instead of silently skipping cache invalidation
- Add test for null policyName in updateStatus mutation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:27:02 -07:00
yuneng-jiang
00f852cec4
Merge pull request #24266 from BerriAI/litellm_/eager-chaum
[Feature] MCP team management + per-member granular permissions
2026-03-20 23:19:54 -07:00
yuneng-jiang
8aa1ebfb07 [Fix] UI - Policies: Fix unhandled promise rejections and isPending semantics
- Wrap mutateAsync calls in try/catch to swallow re-thrown errors
  (notifications already handled by onError in mutation hooks)
- Use isLoading instead of isPending for version loading state —
  isPending is true when query is disabled with no cache, isLoading
  is only true during active fetches (matches original behavior)
- Add isLoading assertions to disabled-state tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:04:25 -07:00
yuneng-jiang
b78e3bad85 address greptile review feedback (greploop iteration 4)
- Move extra_permissions validation before budget upsert to prevent
  partial DB writes on validation failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:54:25 -07:00
yuneng-jiang
7c9664147f address greptile review feedback (greploop iteration 3)
- Revert PUT /v1/mcp/server status code to 202 (backwards-compatible)
- Strengthen Member.extra_permissions validator to check VALID_PERMISSIONS
- Invalidate team cache after add/remove_mcp_server_to_team

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:43:01 -07:00
yuneng-jiang
5acb52b40a address greptile review feedback (greploop iteration 2)
- Handle ValueError on team-link failure as 400 (orphaned server fix)
- Wrap delete's remove_from_team in try/except (prevent 500 after
  successful delete)
- Revert DELETE status code to 202 (backwards-compatible)
- Add extra_permissions to TeamMemberUpdateResponse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:24:02 -07:00
yuneng-jiang
edd41cf88d address greptile review feedback (greploop iteration 1)
- Wrap add/remove_mcp_server_to_team in DB transactions (race condition fix)
- Consolidate role + extra_permissions into single DB write (atomicity)
- Remove silent try/except on team linking (surface errors to caller)
- Add email fallback to _find_member_in_team (email-only members)
- Add None guard on payload.server_id in update endpoint
- Add field_validator on Member.extra_permissions (resource:action format)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:11:17 -07:00
yuneng-jiang
d7890fb278 [Fix] Standardize MCP endpoint HTTP status codes
- PUT /v1/mcp/server: 202 → 200 (synchronous update returns body)
- DELETE /v1/mcp/server: 202 → 204 (synchronous delete, no body)
- Also fix description typo ("deleting" → "updating") on PUT endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:07:48 -07:00
yuneng-jiang
0ca13cc6a5 [Fix] Invalidate team cache after extra_permissions update
Ensures permission changes take effect immediately instead of waiting
for cache TTL expiry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:04:01 -07:00
yuneng-jiang
4f6b8a2a3e [Fix] Exclude team_id from MCP server DB create payload
team_id is a request-level field for auth scoping, not a DB column.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:01:16 -07:00
yuneng-jiang
f80d7dc2f2 [Fix] Add /team/available_permissions to self_managed_routes
Without this, internal users get 401 when calling the endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:57:35 -07:00
yuneng-jiang
5d688c9f27 [Feature] MCP team management + per-member granular permissions
Allow team admins and permissioned members to manage MCP servers scoped
to their team, laying groundwork for full Permission Strings RBAC.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:53:39 -07:00
yuneng-jiang
d8e4fc4dd0
Merge pull request #24260 from BerriAI/litellm_yj_march_19_2026
[Infra] Merge internal dev branch with main
2026-03-20 17:35:19 -07:00
yuneng-jiang
2ca4fa6189
Merge branch 'main' into litellm_yj_march_19_2026 2026-03-20 17:28:41 -07:00
yuneng-jiang
79aea5ddcf [Refactor] UI - Policies: Extract usePolicyVersions hook from FlowBuilderPage
Replace useEffect + useState fetch pattern for policy version management
with React Query hooks (useQuery + useMutation), following established
codebase conventions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:25:40 -07:00