Commit graph

35923 commits

Author SHA1 Message Date
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
yuneng-jiang
e6e3085845
Merge pull request #24258 from joereyna/fix/anthropic-file-content-test-mock
fix(test): mock get_auth_header instead of get_api_key in anthropic file content test
2026-03-20 16:14:59 -07:00
yuneng-jiang
e678ddea43 Fix unreachable special MCP server name guard in add_mcp_server
The special name check (all_team_servers, all_proxy_servers) was an elif
after the server_id-is-not-None check, making it unreachable since special
names are non-None strings. Split into separate if blocks so the special
name guard runs before the duplicate-ID check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:12:48 -07:00
joereyna
f0e0d98f86 fix(test): mock get_auth_header instead of get_api_key in anthropic file content test 2026-03-20 16:07:09 -07:00