Commit graph

707 commits

Author SHA1 Message Date
yucheng
485f4522e4 fix(mcp): scope the Agent 365 connect challenge to single-server routes and drop stale listed tools on invalidation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 03:52:06 +00:00
yucheng
b1c3573390 Merge branch 'litellm_internal_staging' into litellm_agent365_mcp_guardrail
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 03:31:49 +00:00
joshua-berri
70cf348aa5
Merge pull request #40791 from BerriAI/litellm_fix_mcp_root_discovery_6634
fix(mcp): use gateway authentication for root discovery
2026-09-11 20:23:10 -07:00
joshua-berri
e86adf98ac
Merge pull request #40808 from BerriAI/litellm_fix_mcp_oauth_issuer_7078
fix(mcp): match per-server OAuth metadata issuers
2026-09-11 20:23:00 -07:00
Joshua Valluru
9d31de2f20 fix(mcp): bound discovery cache result bytes 2026-09-11 18:08:27 -07:00
Joshua Valluru
05d2c316f5 refactor(mcp): reuse in-memory discovery storage 2026-09-11 17:53:51 -07:00
Joshua Valluru
0690520080 test(mcp): isolate static-prefix discovery UI assets 2026-09-11 17:26:35 -07:00
Joshua Valluru
f66239a50f test(mcp): cover static-prefix issuer discovery 2026-09-11 17:13:47 -07:00
Joshua Valluru
da61fa3564 fix(mcp): preserve existing relay discovery identifiers 2026-09-11 17:11:42 -07:00
Joshua Valluru
17863fa5cf fix(mcp): match per-server OAuth metadata issuers 2026-09-11 17:05:35 -07:00
yucheng
8af770ca83 fix(mcp): point the Agent 365 sign-in challenge at the metadata for the route the client used
The connect-time 401 always named /.well-known/oauth-protected-resource/mcp/{server}, so a client on the
/{server}/mcp URL fetched a document whose resource was a different URL and RFC 9728 strict clients
(newer Claude Code) stopped before opening the browser. Reuse get_passthrough_resource_metadata_url so
the challenge is absolute and matches the inbound path, on both the connect challenge and OBO preflight

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 22:35:05 +00:00
Joshua Valluru
87e2e7afac fix(mcp): preserve request prefixes in BYOK discovery 2026-09-11 15:25:03 -07:00
Joshua Valluru
731f79fa31 fix(mcp): preserve BYOK discovery and isolate session authorization 2026-09-11 15:17:02 -07:00
Joshua Valluru
ceb1f04988 fix(mcp): bind discovery caching to credentials and active callers 2026-09-11 14:49:00 -07:00
Joshua Valluru
6d5c2d85ef fix(mcp): use gateway authentication for root discovery 2026-09-11 14:44:13 -07:00
Joshua Valluru
cc559cbb06 test(mcp): verify discovery prefixing without mocked results 2026-09-11 14:22:26 -07:00
Joshua Valluru
c038aaf622 fix(mcp): cache upstream discovery lists 2026-09-11 14:20:03 -07:00
devin-ai-integration[bot]
e073cd3aeb
fix(mcp): write failure spend log for guardrail-blocked /mcp-rest/tools/call (#40555)
* fix(mcp): write failure spend log for guardrail-blocked /mcp-rest/tools/call

call_tool_rest_api only translated exceptions to HTTP responses, so a pre_mcp_call
guardrail block never reached failure_handler / async_failure_handler /
post_call_failure_hook and no LiteLLM_SpendLogs failure row was written. Extract
the failure logging from call_mcp_tool into _fire_mcp_tool_call_failure_logging
and run it in the REST route for anything raised between
common_processing_pre_call_logic and execute_mcp_tool

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(mcp): keep the original REST tool error when failure logging raises

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(mcp): log virtual mcp_tool_call failures and keep REST success latency scoped to tool execution

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 12:54:03 -07:00
joshua-berri
6882f057b4
Merge pull request #40440 from BerriAI/litellm_mcp_upstream_error_log_detail
fix(mcp): log upstream request method, body and response on tool-list and OAuth2 token failures
2026-09-11 11:24:42 -07:00
joshua-berri
3f81ba3d30
Merge pull request #40679 from BerriAI/litellm_fix_mcp_oauth_registration_7498
fix(mcp): explain refused OAuth registration and bound discovery retries
2026-09-11 10:51:31 -07:00
devin-ai-integration[bot]
3df127b439
fix(proxy): give user-key objects their own in-memory cache partition (#40713)
Key objects share the 200-entry UserApiKeyCache in-memory store with teams,
end users, tags and memberships, so churn in those objects evicts hot keys
and forces a LiteLLM_VerificationToken lookup on the next request. Route
bare hashed-token keys to a dedicated InMemoryCache inside UserApiKeyCache
while keeping Redis, TTL, serialization and invalidation shared

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 09:52:09 -07:00
Joshua Valluru
3883a891f0 fix(mcp): redact compact credential field names 2026-09-11 08:10:19 -07:00
Joshua Valluru
5c190e69bf fix(mcp): preserve timeout fallback on Python 3.10 2026-09-11 08:00:39 -07:00
Joshua Valluru
e8c411fb43 test(mcp): cover deeply nested credential inspection limits 2026-09-11 07:32:38 -07:00
Joshua Valluru
5b13dfcc59 fix(mcp): omit credential-bearing paths from failure logs 2026-09-11 07:27:10 -07:00
Joshua Valluru
0ee9e1e448 fix(mcp): redact reflected credentials and avoid import cycles 2026-09-11 07:20:48 -07:00
Joshua Valluru
40f01e2fa5 chore: merge current staging into MCP OAuth fix 2026-09-11 07:07:07 -07:00
Joshua Valluru
8d5a675878 fix(mcp): expire temporary OAuth discovery results 2026-09-11 07:02:11 -07:00
Joshua Valluru
eec7c1e7f8 chore: merge current staging for MCP diagnostic compatibility 2026-09-11 07:01:06 -07:00
Joshua Valluru
3fc483d424 fix(mcp): capture bounded error diagnostics without exposing credentials 2026-09-11 06:58:40 -07:00
yucheng
de2f6b2f85 fix(mcp): challenge Agent 365 gated connects that carry only a LiteLLM key in Authorization
Some checks failed
LiteLLM Rust / rust-lint (push) Waiting to run
LiteLLM Rust / rust-test (push) Waiting to run
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
A LiteLLM virtual key in the Authorization header admits the caller but is not an Entra assertion the guardrail can exchange, so the connect-time RFC 9728 challenge now fires unless the bearer is a compact JWS. The guardrail parses the inbound bearer with the same predicate

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 09:02:28 +00:00
yucheng
dfbca29e5e Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_agent365_mcp_guardrail 2026-09-11 07:55:30 +00:00
yucheng
df739bdd9e fix(mcp): hand pre-call hooks the metadata of the registered tool that actually runs
Building the guardrail's tool metadata from the local registry entry that
dispatch resolved, instead of re-deriving it from the tool name, keeps an
OpenAPI operation whose name starts with its own server prefix from being
reported with the shorter operation's description and schema. The registry
branch in get_listed_tool is gone with it, and the test doubles for the
local registry now carry a string description and dict schema like the real
entries do

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 07:54:36 +00:00
joshua-berri
9a715df212
Merge pull request #40665 from BerriAI/litellm_fix_openapi_mcp_health_4896
fix(mcp): check OpenAPI specifications without native MCP handshakes
2026-09-10 22:02:45 -07:00
yucheng
6c865d1413 fix(mcp): resolve OpenAPI tool metadata from the local registry before any tools/list
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 04:34:56 +00:00
Joshua Valluru
f04fb748c5 fix(mcp): explain refused OAuth registration and bound discovery retries 2026-09-10 21:02:46 -07:00
yucheng
0f7105f25e fix(mcp): hand listed tool metadata to pre-call hooks on the local registry path
OpenAPI-generated and legacy local-registry tools dispatch through execute_mcp_tool's
local branch, which called pre_call_tool_check without the cached MCPTool. Agent 365
therefore received bare {"name"} payloads for those tools while managed-server tools
carried description and inputSchema. Both local call sites now pass get_listed_tool

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 03:43:33 +00:00
Joshua Valluru
ca03c889c9 fix(mcp): avoid caching cancelled OpenAPI health probes 2026-09-10 20:26:53 -07:00
yucheng
886220375f fix(guardrails): agent 365 sign-in for scopeless servers and gateway credential errors
Scopeless Agent 365 gated servers now advertise api://<client_id>/access_as_user instead of
staying silent, so a client can still sign in. Entra rejecting the gateway's own credentials
(invalid_client, unauthorized_client, invalid_scope, invalid_resource) follows unreachable_fallback
rather than telling the caller to sign in again with a 401

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 03:15:59 +00:00
Joshua Valluru
da1dfcdb24 refactor(mcp): reuse the shared HTTP handler for bounded probes 2026-09-10 19:59:07 -07:00
yucheng
803f8a69f0 test(mcp): assert the no-challenge outcome and register openapi tools through the registry api
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 02:56:34 +00:00
yucheng
02233a2df3 refactor(mcp): build agent 365 protected resource metadata immutably to satisfy the type discipline gate
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 02:49:13 +00:00
Joshua Valluru
576c1bc5d6 fix(mcp): bound and coalesce OpenAPI health probes 2026-09-10 19:45:44 -07:00
Joshua Valluru
fc95d22367 fix(mcp): accept VS Code OAuth registration callbacks 2026-09-10 19:28:40 -07:00
yucheng
d5b8effa99 fix(mcp): skip prefix lookup when a server has no listed tools
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 02:27:19 +00:00
Joshua Valluru
8c82c325ac fix(mcp): check OpenAPI specifications without native MCP handshakes 2026-09-10 19:18:19 -07:00
yucheng
e9c654869f Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_agent365_mcp_guardrail 2026-09-11 02:14:35 +00:00
yucheng
faa430c6c1 feat(mcp): challenge Agent 365 gated MCP servers with the Entra RFC 9728 metadata
When an Agent 365 guardrail applies to an MCP server that advertises scopes and no bearer arrives,
reuse the MCP OBO raise_token_exchange_challenge so the 401 and WWW-Authenticate header leave at the
transport layer. The protected-resource metadata for that server names the guardrail's Entra v2
issuer and the server's scopes, so Claude Code and other MCP clients run browser SSO and attach the
bearer themselves instead of the user pasting a token into the client config.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 02:08:09 +00:00
yucheng
35a1d017dc feat(guardrails): send MCP tool metadata to Agent 365 and treat unevaluated Defender verdicts as unavailable
Carry the listed tool's description and inputSchema from MCPServerManager through the pre-call and
during-call hook request objects into the Agent 365 evaluate payload, omitting them when the tool was
never listed. An allowed verdict whose defender.status is not Evaluated (Skipped, FailedOpen, missing)
now follows the unreachable_fallback policy instead of counting as a scanned allow. The conversationId
prefers the proxy-owned litellm_call_id over caller-controlled mcp-session-id headers.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-11 02:08:01 +00:00
joshua-berri
4d067b56af
Merge pull request #38724 from BerriAI/litellm_mcp_oauth_identity_binding
fix(mcp): bind per-user OAuth credentials to the authenticated LiteLLM caller
2026-09-10 14:44:11 -07:00