Commit Graph
35116 Commits
Author SHA1 Message Date
Sameer Kankute 36ec80d90c Fix azure model router 2026-03-12 12:40:37 +05:30
Sameer Kankute 5b83aae715 feat(azure_ai): show actual model used in Azure Model Router response
- Azure Model Router transform_response: let parent extract actual model from raw response
- common_request_processing: skip model override for Azure Model Router requests
- proxy_server: skip streaming chunk model restamp for Azure Model Router
- Add _is_azure_model_router_request helper
- Add tests for non-streaming and streaming

Made-with: Cursor
2026-03-12 11:41:19 +05:30
Joe ReynaandGitHub c4aa15b4e2 Merge pull request #23418 from joereyna/fix/gemini-passthrough-stale-model-name
fix: update stale gemini-1.5-flash model name in passthrough logging handler test
2026-03-11 22:55:19 -07:00
Ishaan JaffGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
19db79db17 fix(mcp): OAuth2 chat connect - tools fetch, auth, and status fixes (#23406)
* fix(mcp): OAuth2 chat connect - tools fetch, auth flow, and status fixes

- schema.prisma: add missing MCP table fields (approval_status, submitted_by, submitted_at, reviewed_at, review_notes) to prevent destructive migrations
- rest_endpoints.py: inject user OAuth token via extra_headers for OAuth2 servers so tools list is populated; add server name->UUID resolution so MCPConnectPicker name lookups work
- mcp_registry.json: fix Atlassian defaults (transport: http, url: .../v1/mcp)
- ChatPage.tsx: read mcpOauthReturn param to init sidebarView="apps" on OAuth return, clean up param after mount
- MCPAppsPanel.tsx: auto-add OAuth2 servers to selectedServers when credential detected; onConnect also enables server for chat; disconnect removes from selectedServers
- mcp_servers.tsx: sort servers by created_at DESC
- useUserMcpOAuthFlow.tsx: append mcpOauthReturn=apps to return URL so Apps panel is mounted on return

* address greptile review feedback (greploop iteration 1)

* fix(mcp): inject stored OAuth2 token when fetching tools via /responses API

When a user has connected an OAuth2 MCP server (e.g. Atlassian) and then
uses the /responses endpoint with that server, tool listing was failing
because the stored per-user OAuth token was never injected.

Two fixes:
1. server.py: add _get_user_oauth_extra_headers_from_db() helper; call it
   in _get_tools_from_mcp_servers when oauth2_headers is None for an OAuth2
   server, falling back to the user's stored token in LiteLLM_MCPUserCredentials
2. litellm_proxy_mcp_handler.py: also intercept MCP tools whose server_url
   matches */mcp/<server_name> (e.g. http://localhost:4000/mcp/atlassian_test)
   by rewriting them to litellm_proxy/mcp/<server_name> so they go through
   the internal handler (and get the OAuth token injected) instead of being
   forwarded to OpenAI raw where localhost is unreachable

* address greptile review feedback (greploop iteration 2)

* test(mcp): add unit test for OAuth2 token injection in _get_tools_from_mcp_servers

Verifies that when _get_tools_from_mcp_servers is called for an OAuth2 MCP
server without oauth2_headers in the request, the implementation:
- calls _prefetch_oauth_creds_for_user once (not per-server) to avoid N+1 queries
- passes the stored token as extra_headers={"Authorization": "Bearer ..."} to
  _get_tools_from_server so the upstream OAuth2 MCP server authenticates correctly

* address greptile review feedback (greploop iteration 3)

* address greptile review feedback (greploop iteration 4)

* address greptile review feedback (greploop iteration 5)

* redesign credentials table to use Tremor table layout matching Keys page

* fix: /server/oauth authorize 422 - make client_id optional, fall back to real DB server

* fix: mcp_token client_id optional, resolve from server record

* fix: look up real server by UUID (get_mcp_server_by_id) before falling back to name

* Update litellm/responses/mcp/litellm_proxy_mcp_handler.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: address greptile feedback - client_id guards, dict spread, helper refactor, tests

- mcp_management_endpoints: raise 400 when resolved_client_id is empty in
  mcp_authorize and mcp_token instead of forwarding "" to upstream
- litellm_proxy_mcp_handler: use {**tool, "server_url": ...} spread instead
  of dict(tool) + mutation for shallow copy safety
- rest_endpoints: extract _oauth2_server_ids set comprehension to a named
  _get_oauth2_server_ids() helper for clarity; add Set to typing imports
- test_rest_endpoints: add tests for name→UUID resolution path,
  access-denied when resolved UUID not in allowed list, and OAuth2 user
  token injection for single-server requests; fix fake_get_tools signature
  to accept extra_headers kwarg

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-11 22:07:02 -07:00
2b7b7d3086 fix(snowflake): transform string tool_choice to object format (#23318)
Snowflake's Cortex LLM API (like Anthropic) requires tool_choice as an
object with a "type" field, not as a bare string. Passing tool_choice="auto"
(or "required"/"none") results in error 390142 "invalid payload".

This fix transforms OpenAI string tool_choice values to the Snowflake
object format:
- "auto"     -> {"type": "auto"}
- "required" -> {"type": "any"}  (Snowflake/Anthropic convention)
- "none"     -> {"type": "none"}

The dict-to-dict transformation for specific function tool choices
({"type": "function", "function": {"name": "..."}} -> {"type": "tool",
"name": [...]}) remains unchanged.

Fixes #23284

Co-authored-by: gambletan <tan@echooo.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
2026-03-11 21:29:59 -07:00
Ishaan JaffandGitHub b0aa71ed9b feat(ui): group MCP tools by CRUD risk category in allowlist panels (#23403)
* feat(ui): group MCP tools by CRUD risk category in tool permission panels

Adds a CRUD-classification layer to the MCP tool allowlist UI so admins
can allow/block an entire risk category (Read / Create / Update / Delete)
with a single toggle instead of managing a flat list of individual tools.

- New `mcpToolCrudClassification.ts` utility: regex-based classifier that
  buckets tool names/descriptions into read/create/update/delete/unknown
- New `McpCrudPermissionPanel` component: collapsible sections per CRUD
  group, group-level Switch toggle, individual tool checkboxes, risk badges
  (green Safe / yellow Medium / red High Risk)
- `mcp_tool_configuration.tsx`: adds "Risk Groups / Flat List" radio toggle;
  defaults to the CRUD-grouped view, flat list is still accessible
- `MCPToolPermissions.tsx` (key/team assignment): replaces flat checkboxes
  with the CRUD panel; adds per-server view toggle; delete tools are blocked
  by default for newly-added servers (safer default for key/team scoping)

No backend or schema changes — uses existing `allowed_tools` and
`mcp_tool_permissions` fields.

* fix(mcp): OAuth2 chat connect - tools fetch, auth flow, and status fixes

- schema.prisma: add missing MCP table fields (approval_status, submitted_by, submitted_at, reviewed_at, review_notes) to prevent destructive migrations
- rest_endpoints.py: inject user OAuth token via extra_headers for OAuth2 servers so tools list is populated; add server name->UUID resolution so MCPConnectPicker name lookups work
- mcp_registry.json: fix Atlassian defaults (transport: http, url: .../v1/mcp)
- ChatPage.tsx: read mcpOauthReturn param to init sidebarView="apps" on OAuth return, clean up param after mount
- MCPAppsPanel.tsx: auto-add OAuth2 servers to selectedServers when credential detected; onConnect also enables server for chat; disconnect removes from selectedServers
- mcp_servers.tsx: sort servers by created_at DESC
- useUserMcpOAuthFlow.tsx: append mcpOauthReturn=apps to return URL so Apps panel is mounted on return

* fix(mcp-crud-ui): address greptile review feedback

- use Checkbox (not Switch) for group toggle so indeterminate works
- add toolPermissionsRef to avoid stale closure race on concurrent server fetches
- remove unused blockDeleteByDefault prop from McpCrudPermissionPanel
- classify tools by name first; fall back to description only when name yields no match
- add Risk Groups / Flat List toggle to mcp_tool_configuration.tsx

* fix(mcp-crud-ui): address greptile 3/5 review

- remove non-functional XIcon remove-server button (no onRemoveServer prop wired)
- fix stale closure in MCPAppsPanel auto-enable effect: use serversRef/selectedServersRef
- remove utility re-export from McpCrudPermissionPanel (classifyToolOp, groupToolsByCrud)
- remove redundant selectedTools.length === 0 guard (always true when !toolPermissions[id])

* fix(mcp-crud-ui): address greptile 3/5 review round 2

- check READ_RE before DELETE_RE in classifyToolOp so tools like
  get_removed_entries are not silently blocked by delete-by-default
- expand undefined (allow-all) to full tool name list instead of
  collapsing to [] (allow-none) in MCPToolPermissions and mcp_tool_configuration
- log OAuth credential fetch failures instead of silently swallowing them

* fix: cursor-pointer on read-only rows, stable sort, simplify handleCrudPanelChange

* fix: sanitize user_id/server_id in log to prevent log injection

* fix: add OAuth headers to call_tool_rest_api, fix stale accessToken closure, fix group toggle on filtered subset

* fix: batch OAuth creds query, hide empty CRUD groups on search, onChange stability

* fix: double-add race, conditional bulk query, narrow DELETE_RE, hoist search input

* fix(mcp): clear oauthConnected on deselect; null guard on allowedTools prop

* fix(mcp): remove user-provided values from debug log to fix log-injection lint

* fix(mcp): fix allowedTools undefined semantics; remove unused import and color field
2026-03-11 21:15:25 -07:00
yuneng-jiangandGitHub 626d120873 Merge pull request #23425 from BerriAI/cursor/litellm-ci-stability-4513
[Infra] CI/CD Fixes
2026-03-11 21:08:16 -07:00
Sameer KankuteandGitHub 53e8e3ec24 Merge pull request #23426 from BerriAI/revert-20795-chore/remove-deprecated-models
Revert "chore: cleanup deprecated models from pricing JSON"
2026-03-12 09:28:45 +05:30
Sameer KankuteandGitHub 49d653c3aa Revert "chore: cleanup deprecated models from pricing JSON" 2026-03-12 09:27:40 +05:30
yuneng-jiangandGitHub ce80e16755 Merge pull request #23419 from BerriAI/litellm_audit_log_admin_viewer
[Feature] Allow Admin Viewers to Access Audit Logs
2026-03-11 20:40:48 -07:00
Cursor Agentandyuneng-jiang d5fc63f63f fix(ci): fix deprecated model refs and schema validation in unit tests
- Replace gemini-pro with gemini-3-pro-preview in test_cost_discount_vertex_ai
  (gemini-pro removed from cost map)
- Replace github/claude-3-5-sonnet-latest with github/claude-3-7-sonnet-20250219
  in test_supports_function_calling_github_anthropic_alias (model removed)
- Add supports_multimodal, uses_embed_content, input/output_cost_per_token_above_256k_tokens
  to JSON schema in test_utils.py (new properties added to model cost map)

Co-authored-by: yuneng-jiang <yuneng-jiang@users.noreply.github.com>
2026-03-12 03:28:24 +00:00
ryan-crabbeandGitHub a976fccd76 Merge pull request #23422 from BerriAI/litellm_guardrail-info-helpers-tests
tests: add ui unit tests for guardrail_info_helpers
2026-03-11 20:17:45 -07:00
Cursor Agentandyuneng-jiang aacc7b18f8 fix(ci): add missing provider docs, fix deprecated model refs in cost tests
- Add black_forest_labs and charity_engine to provider_endpoints_support.json
  (fixes check_code_and_doc_quality job)
- Replace o1-mini with o1 in test_reasoning_tokens_no_price_set (model removed
  from cost map)
- Replace gemini-2.5-pro-exp-03-25 with gemini-2.5-pro in
  test_generic_cost_per_token_above_200k_tokens (model removed from cost map)
- Fix test_get_cost_for_anthropic_web_search to use claude-3-7-sonnet-20250219
  with custom_llm_provider='anthropic' so web search cost is computed correctly

Co-authored-by: yuneng-jiang <yuneng-jiang@users.noreply.github.com>
2026-03-12 03:11:29 +00:00
yuneng-jiangandClaude Opus 4.6 76cff9ae0e Allow proxy_admin_viewer to access audit log endpoints
Add /audit and /audit/{id} to admin_viewer_routes so read-only admins
can view audit logs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:07:51 -07:00
Ryan Crabbe 8c4603641e test(ui): add unit tests for guardrail_info_helpers
Cover populateGuardrailProviders, getGuardrailProviders,
shouldRender* config checks, and getGuardrailLogoAndName.
2026-03-11 20:07:30 -07:00
joereyna 5c20617a21 fix: mock completion_cost in routing test and restore helper consistency
- Mock litellm.completion_cost in test_pass_through_success_handler_gemini_routing
  to decouple it from model_prices_and_context_window.json; prevents the same
  breakage if gemini-2.0-flash is ever removed from the pricing map
- Revert _create_passthrough_logging_payload URL back to gemini-1.5-flash to
  eliminate inconsistency with the other tests that use gemini-1.5-flash explicitly
2026-03-11 20:05:40 -07:00
yuneng-jiangandGitHub 5d7bfe6260 Merge pull request #23407 from BerriAI/cursor/litellm-ci-stability-4513
LiteLLM CI stability
2026-03-11 20:03:07 -07:00
ryan-crabbeandGitHub 6229e73dfc Merge pull request #23415 from BerriAI/litellm_style-created-by-not-uuid
style: make virtual keys tables' created by not a UUID
2026-03-11 19:53:39 -07:00
Joe ReynaandGitHub 483a605f6e fix: add custom_body param to URL-based endpoint_func in create_pass_through_route (#23412) 2026-03-11 19:46:50 -07:00
Joe ReynaandGitHub 36819ffb6f fix: null AWS SigV4 fields on MagicMock in TestTemporaryMCPSessionEndpoints (#23408)
* fix(test): null AWS SigV4 fields on MagicMock in test_inherit_credentials_from_existing_server

* fix(test): null AWS SigV4 fields on MagicMock in test_add_session_mcp_server_caches_and_redacts_credentials
2026-03-11 19:46:08 -07:00
Ryan Crabbe dfda7c10fc fix: set created_by on mock keys in test_list_keys_with_expand_user 2026-03-11 19:45:04 -07:00
joereyna 59778f3ce7 fix: update stale gemini-1.5-flash model name to gemini-2.0-flash in passthrough logging handler test 2026-03-11 19:30:41 -07:00
ryan-crabbeandGitHub 2a879ef6f3 Merge pull request #23181 from BerriAI/feat_agg_token_totals
Feat add token totals
2026-03-11 19:30:30 -07:00
ryan-crabbeandGitHub 2e3c1c41a7 Merge pull request #23371 from BerriAI/litellm_fix-refetch-mcp-after-add
fix: refetching mcp after creating
2026-03-11 19:27:00 -07:00
Shivam RawatandGitHub 74a9dbd8ac Merge pull request #23413 from BerriAI/docs_policyy_builder
v1.82.0 promote to stable
2026-03-11 19:19:15 -07:00
Ryan Crabbe 4973311070 test: add tests for created_by_user expansion in key list 2026-03-11 19:16:09 -07:00
shivam 0c7c0a93ed v1.82.0 promote to stable 2026-03-11 19:15:21 -07:00
Ryan Crabbe d4fa990176 feat(ui): show user email/alias instead of UUID in Virtual Keys "Created By" column
Expand the existing expand=user lookup on /key/list to also resolve
created_by user IDs, and display the result in the Created By column
with alias > email > UUID fallback and a popover showing all three.
2026-03-11 19:12:14 -07:00
Shivam RawatandGitHub 50e68dc387 Merge pull request #23410 from BerriAI/docs_policyy_builder
Docs policyy builder
2026-03-11 19:03:55 -07:00
Shivam RawatandGitHub 4e7003afef Fix 404 when fetching config-based MCP servers by ID (#22711)
* fixed mcp api

* added non-admin test

* resolved greptile comemnt

* fix: add IP filtering to get_mcp_server_by_id path in fetch_mcp_server

Apply _is_server_accessible_from_ip check after get_mcp_server_by_id lookup
to prevent external callers from accessing MCP servers configured with
available_on_public_internet=False when they know the server_id.

Made-with: Cursor
2026-03-11 18:30:30 -07:00
Cursor Agentandyuneng-jiang 49dc391a46 fix(ci): remove unused is_expired variable (ruff F841) and handle ModelDeprecated in image gen test
- Remove dead code: is_expired was assigned but never used in
  mcp_management_endpoints.py (the raw expires_at timestamp is passed
  directly to the client per existing comment)
- Handle Azure DALL-E 3 ModelDeprecated (HTTP 410) error gracefully in
  base_image_generation_test.py so CI doesn't fail on deprecated model
  deployments

Co-authored-by: yuneng-jiang <yuneng-jiang@users.noreply.github.com>
2026-03-12 01:27:42 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
85f66ea9c7 chore: regenerate poetry.lock to match pyproject.toml (#23405)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 01:09:56 +00:00
yuneng-jiangandGitHub 2731337ba3 Merge pull request #23404 from BerriAI/litellm_proxy_extras_mar11_2
chore: bump proxy extras
2026-03-11 18:08:57 -07:00
yuneng-jiang 299ee16780 adding build 2026-03-11 18:08:20 -07:00
yuneng-jiang e1674bd34f bump: version 0.4.53 → 0.4.54 2026-03-11 18:07:58 -07:00
yuneng-jiangandGitHub d39355d36f Merge pull request #23402 from BerriAI/litellm_proxy_extras_mar11
Revert "fix: add missing indexes for top CPU-consuming queries (#23147)"
2026-03-11 18:00:47 -07:00
yuneng-jiang 64ed29db57 Revert "fix: add missing indexes for top CPU-consuming queries (#23147)"
This reverts commit 323b473835.
2026-03-11 17:40:59 -07:00
yuneng-jiangandGitHub 56557bfae1 Merge pull request #23400 from BerriAI/litellm_/elated-hoover
[Fix] Replace deprecated models in tests
2026-03-11 17:25:37 -07:00
Ryan Crabbe 62343b477c fix: use Grid layout for token cards and guard against NaN in paginated aggregation 2026-03-11 17:20:38 -07:00
yuneng-jiangandClaude Opus 4.6 82de82f1b6 Fix test_completion_cost_prompt_caching gemini parametrization
gemini/gemini-2.5-flash lacks cache_creation_input_token_cost in the
model cost map, causing a TypeError when the test multiplies
cache_creation_input_tokens by None. Use claude-haiku-4-5 instead,
which has the required prompt caching cost fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:12:15 -07:00
yuneng-jiangandClaude Opus 4.6 c9f7075690 Replace additional deprecated models across test files
- tests/local_testing/test_completion_cost.py:
  - claude-3-5-sonnet-20240620 -> claude-sonnet-4-6
  - gemini/gemini-1.5-flash-001 -> gemini/gemini-2.5-flash

- tests/test_litellm/test_utils.py:
  - claude-3-5-sonnet-20240620 -> claude-sonnet-4-6 (VertexAI config test, proxy tests)
  - gemini-1.5-pro -> gemini-2.5-pro (pre_process_non_default_params)
  - gemini/gemini-1.5-pro -> gemini/gemini-2.5-pro (proxy tests)

- tests/litellm_utils_tests/test_utils.py:
  - claude-3-opus-20240229 -> claude-sonnet-4-6 (trimming, vision tests)
  - gemini-pro -> gemini-2.5-pro (function calling test)
  - gemini-pro-vision -> gemini-2.5-flash (vision test)
  - gemini-1.5-pro -> gemini-2.5-pro (response schema test)
  - gemini/gemini-1.5-flash -> gemini/gemini-2.5-flash (function calling test)
  - gemini-1.5-pro -> gemini-2.5-pro (vision gemini test)
  - gpt-4-vision-preview -> gpt-4o (vision test)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:03:54 -07:00
ryan-crabbeandGitHub fdfb65c204 Merge pull request #23395 from BerriAI/litellm_fix-default-user-perms-respected-through-SCIM
fix: fix default user perms respected through SCIM
2026-03-11 16:57:29 -07:00
Ryan Crabbe 7e1c860ffe fix: make token breakdown cards click-to-expand on Total Tokens card 2026-03-11 16:52:25 -07:00
yuneng-jiangandClaude Opus 4.6 9379cb1038 [Fix] Replace deprecated models in function calling tests
Replace deprecated model references in test_proxy_function_calling_support_consistency:
- claude-3-5-sonnet-20240620 -> claude-sonnet-4-6
- gemini-pro -> gemini-2.5-pro
- gemini/gemini-1.5-pro -> gemini/gemini-2.5-pro
- gemini/gemini-1.5-flash -> gemini/gemini-2.5-flash

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:46:56 -07:00
yuneng-jiangandGitHub c239d33925 Merge pull request #23393 from BerriAI/litellm_ui_component_tests
[Test] Add Unit Tests for 5 UI Components
2026-03-11 16:44:15 -07:00
ryan-crabbeandGitHub e4e5436bc2 Merge pull request #23399 from BerriAI/revert-23174-feat_adding_timezone_to_usage_page
Revert "feat: adding a timezone picker to the usage page"
2026-03-11 16:34:14 -07:00
yuneng-jiangandGitHub 8617ca6e12 Merge pull request #23390 from BerriAI/litellm_/reverent-kalam
[Fix] Update test_bad_database_url CI check for new error message
2026-03-11 16:33:45 -07:00
ryan-crabbeandGitHub c2c102c6e2 Revert "feat: adding a timezone picker to the usage page" 2026-03-11 16:33:03 -07:00
yuneng-jiangandClaude Opus 4.6 28989a11e7 [Fix] Update test_bad_database_url to match new startup error message
PR #23257 changed proxy startup to exit early with "Database setup
failed after multiple retries" instead of letting uvicorn emit
"Application startup failed. Exiting." Update the CI grep check
to accept either error message for robustness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:25:35 -07:00
Ishaan JaffandGitHub f5e5d17e4a fix(mcp): fix OpenAPI OAuth flow — transport mapping, error messages, and discovery bypass (#23315)
* fix(mcp): fix OpenAPI OAuth flow — transport mapping, error messages, and discovery bypass

Three bugs fixed to make the end-to-end OAuth flow work for OpenAPI MCP servers:

1. **Transport mapping in getTemporaryPayload**: `TRANSPORT.OPENAPI` is a UI-only concept;
   the backend only accepts `"http"`, `"sse"`, or `"stdio"`. The pre-OAuth temp-session
   call was sending `transport: "openapi"` and getting a 422. Fixed by mapping to `"http"`.

2. **deriveErrorMessage handles FastAPI 422 arrays**: FastAPI validation errors return
   `detail` as an array of `{loc, msg, type}` objects. The shared error extractor was
   returning the array directly, causing `Error: [object Object]`. Fixed to map each
   item to its `.msg` field.

3. **Skip OAuth discovery when authorization_url already provided**: `build_mcp_server_from_table`
   was unconditionally calling `_descovery_metadata(server_url)` for OAuth servers. For
   OpenAPI servers the url is the spec JSON file, not the API base — this caused a timeout
   fetching e.g. the GitHub spec (2 MB). Fixed by skipping discovery when `authorization_url`
   is already set.

Also: collapsible auth section in MCP server form, "Create OAuth App →" link next to
Client ID when a docs URL is available (e.g. GitHub OAuth App creation page), and
`extractErrorMessage` helper in `useMcpOAuthFlow` for cleaner error display.

* refactor(mcp): extract needs_discovery flag and reduceStaticHeaders helper

* feat(mcp): user OAuth connect flow — OAuthConnectModal, MCPCredentialsTab, useUserMcpOAuthFlow

Adds the user-facing MCP OAuth2 PKCE connect flow:

- OAuthConnectModal: modal that launches the PKCE flow for a user to connect to an MCP server
- MCPCredentialsTab: credentials management tab in the MCP apps panel
- useUserMcpOAuthFlow: hook that handles the full PKCE auth code exchange for user-level connections
- MCPAppsPanel: wires up the new credentials tab and connect modal
- ChatPage: further cleanup after responses-API revert
- db.py / mcp_management_endpoints.py / _types.py: backend support for storing user MCP credentials

* fix(mcp): make client_id optional in /authorize — use server's stored client_id when not provided

* address greptile review feedback

* fix(mcp): narrow bare except to RecordNotFoundError in BYOK credential delete

* refactor(mcp): move inline imports to module level in db.py

* docs(claude): add MCP OAuth, transport mapping, and browser storage patterns

* fix(security): remove accessToken from sessionStorage in OAuth flow state

The LiteLLM API key was being serialised into sessionStorage as part of
StoredFlowState. After the OAuth redirect the component re-mounts with the
same accessToken prop, so it never needed to be stored. Read it from props
in resumeOAuthFlow instead.

* fix(ui): remove duplicate extractErrorMessage, sessionStorage-only in admin OAuth hook, call delete API on disconnect

* fix(ui): guard resumeOAuthFlow against wrong hook instance consuming OAuth result

* fix(ui): separate OAuth result keys per flow, sessionStorage-only, surface revoke errors

* fix(ui): remove dead OAuthConnectModal, revert tsconfig jsx mode to preserve

* fix(mcp): guard BYOK overwrite in oauth credential store, raise clear error when client_id absent

* fix: forward OAuth error params in callback, fix BYOK guard exception handling in db.py
2026-03-11 16:16:08 -07:00