Scope MCP app resource reads to their originating call (#39187)

## Why

App widgets need to read resources using the app and account context of the
tool call that produced them, including after a thread is restored.

## What changed

- Add an optional `originCallId` to `mcpServer/resource/read` requests and
  return it on successful scoped reads.
- Track bounded provenance for successful app tool calls in thread history and
  use the current tool binding, account link, and app policy when reading the
  associated widget resource.
- Reject missing, mismatched, failed, or ambiguous origins, while keeping
  app-only tools available for widget reads without exposing them to the model.

## Testing

Add app-server coverage for scoped widget reads across both history modes,
ephemeral and persistent threads, server restarts, app-only visibility, and
invalid origin cases.

GitOrigin-RevId: 11eaefc066b2a3b639599e4cbdef680233d150a2
This commit is contained in:
jif authored and copyberry committed 2026-08-18 11:51:21 +00:00
1 parent 711a5f8b3a
commit 880f1135ea
26 files changed
+779 -22

No files matched your search

+1
View File
@@ -2129,6 +2129,7 @@ impl Session {
}
async fn send_event_raw_with_persistence(&self, event: Event, persist: bool) {
self.services.mcp_runtime.observe_event(&event.msg);
// Persist the event into rollout storage; the store applies its persistence policy.
if persist {
let rollout_items = vec![RolloutItem::EventMsg(event.msg.clone())];