MCP Apps Conformance — results

Generated 2026-07-27 17:19 · hosts: chatgpt, claude, cursor, goose, mistral, playground · How it works ↗ · Architecture ↗
Single run per host, some manual verdicts operator-assisted. Grouped by RFC-2119 clause — a FAIL under SHOULD/MAY means the optional behavior isn't supported, not a spec violation.
PASSFAIL / TIMEOUTnot run hover a cell for the message / driver action · click a test's spec link for the exact line
Test
chatgpt
2026-07-22 15:39 UTC
claude
2026-07-22 15:39 UTC
cursor
2026-07-27 15:12 UTC
goose
2026-07-27 14:34 UTC
mistral
2026-07-27 07:59 UTC
alpic-playground
2026-07-24 14:19 UTC
MUST
lifecycle/initialize-capabilitiesPASSPASSPASSPASSPASSPASS
lifecycle/tool-inputPASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.PASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.PASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.PASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.PASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.PASSCaptured via the ontoolinput callback (registered before connect). TIMEOUT means the host never sent it for the launching tool.
lifecycle/tool-input-partial-stopPASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).PASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).PASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).PASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).PASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).PASSOnly catches a violation if the host actually streams partials; our launcher tool has no streamable args, so this usually passes vacuously (0 partials observed).
lifecycle/tool-resultPASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.PASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.PASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.PASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.PASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.PASSCaptured via ontoolresult. Some hosts may not replay tool-result for the tool that launched the view — TIMEOUT flags that.
tools/proxy-callPASSThe server also sees this call directly, so it can be corroborated server-side.PASSThe server also sees this call directly, so it can be corroborated server-side.PASSThe server also sees this call directly, so it can be corroborated server-side.PASSThe server also sees this call directly, so it can be corroborated server-side.PASSThe server also sees this call directly, so it can be corroborated server-side.PASSThe server also sees this call directly, so it can be corroborated server-side.
visibility/app-tool-call-guardFAILhost must reject an app's tools/call for a tool lacking "app" visibility
Covers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.
FAILhost must reject an app's tools/call for a tool lacking "app" visibility
Covers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.
PASSCovers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.FAILhost must reject an app's tools/call for a tool lacking "app" visibility
Covers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.
PASSCovers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.PASSCovers the app→tool direction only. The complementary `visibility/app-tool-hidden` (tool absent from the *agent's* list) needs the agent vantage and isn't measurable here.
display/return-resulting-modePASSRequests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.PASSRequests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.FAIL[ { "code": "invalid_union", "errors": [ [ { "code": "invalid_value", "values": [ "inline" ], "path": [], "message": "Invalid input: expected \"inline\"" } ], [ { "code": "invalid_value", "values": [ "fullscreen" ], "path": [], "message": "Invalid input: expected \"fullscreen\"" } ], [ { "code": "invalid_value", "values": [ "pip" ], "path": [], "message": "Invalid input: expected \"pip\"" } ] ], "path": [ "mode" ], "message": "Invalid input" } ]
Requests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.
PASSRequests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.PASSRequests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.PASSRequests the current mode ('inline') to avoid a disruptive change, but a host may still re-render as a side effect.
dimensions/listen-size-changedPASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.PASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.PASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.PASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.PASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.PASSFlexible mode only (returns vacuously if the host pins a fixed height). Relies on autoResize reporting the taller content and the view's window.innerHeight reflecting the resize; the host may clamp to maxHeight.
security/sandbox-distinct-originPASSHost ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.PASSHost ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.PASSHost ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.PASSHost ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.PASSHost ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.FAILreading window.top.location (the host) must throw — host and sandbox must have different origins
Host ≠ Sandbox. The View runs same-origin inside the Sandbox, so this checks window.top (the host), not window.parent (the sandbox). Opened top-level (no host), window.top === self and this FAILs — correct, it's not in a host.
security/sandbox-permissionsPASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.PASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.PASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.PASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.PASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.PASSInferred: scripts executing ⇒ allow-scripts; non-opaque window.origin ⇒ allow-same-origin.
security/csp-construct-from-domainsPASSReads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.PASSReads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.PASSReads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.FAILcould not read the applied CSP (no <meta> tag and no securitypolicyviolation fired)
Reads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.
PASSReads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.PASSReads the applied CSP via a <meta> tag or the securitypolicyviolation event's originalPolicy. ⚠️ if the host delivers CSP only by HTTP header and no violation fires (or originalPolicy is redacted), it can't be read.
security/csp-allow-declaredPASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.PASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.PASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.PASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.PASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.PASSThe runner declares connectDomains: ["https://modelcontextprotocol.io/"]. ⚠️ a network failure also reads as "not allowed", so the origin must be reachable.
security/iframe-sandboxedPASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.PASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.PASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.PASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.PASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.PASSOperator-read: the sandboxed View's content is cross-origin, but the <iframe> element (and its sandbox attribute) lives in the host document and is readable. Asserts the host uses at least one sandboxed iframe.
security/sandbox-proxy-requiredPASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.PASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.PASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.PASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.PASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.PASSPaired with sandbox-distinct-origin (Host != Sandbox): window.parent (the sandbox) != window.top (the host) proves an intermediate proxy frame. Opened top-level, window.top === self and this FAILs — correct, it's not in a host.
MUST NOT
display/no-undeclared-modeFAILhost must not switch the view to a mode it didn't declare (pip)
We declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.
PASSWe declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.PASSWe declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.PASSWe declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.PASSWe declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.PASSWe declare only inline/fullscreen in appCapabilities, then request the undeclared 'pip'.
security/csp-no-looseningPASSBacked by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.PASSBacked by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.PASSBacked by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.FAILthe host must not allow the undeclared origin https://example.com/ (no loosening beyond declared domains)
Backed by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.
PASSBacked by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.PASSBacked by csp-allow-declared as the positive control: the declared origin works, so blocking this one is genuinely the CSP, not a blanket fetch failure.
visibility/app-tool-hiddenPASS`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.PASS`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.FAILhost does not advertise ui/message
`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.
FAILhost does not advertise ui/message
`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.
FAILhidden tool name `conformance_probe` surfaced in the conversation
`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.
PASS`conformance_probe` is app-only (visibility ["app"]) so it must not be in the model-facing tools/list. Uses the desktop-host tool-list affordance if available, else the agent's own (truthful) enumeration.
SHOULD
context/initialize-hostcontextPASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.PASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.PASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.PASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.PASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.PASSSHOULD, not MUST — a host may legitimately omit hostContext, which would FAIL here. We assert presence; a richer version would only validate shape when present.
context/light-darkFAILhost provides style variables but none use light-dark()
SHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.
PASSSHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.FAILhost provided no style variables to check for light-dark()
SHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.
PASSSHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.FAILhost provides style variables but none use light-dark()
SHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.
PASSSHOULD, and only observable when the host passes style variables. Non-color variables (radii, shadows) legitimately don't use light-dark(), so this is a signal, not a hard fail.
display/unavailable-returns-currentFAILhost should return the current display mode for an unavailable request: expected "inline", got "pip"
SHOULD — assumes the current mode is stable between reading hostContext and the request.
PASSSHOULD — assumes the current mode is stable between reading hostContext and the request.FAILhost returned a malformed result with no valid mode for an unavailable request: [ { "code": "invalid_union", "errors": [ [ { "code": "invalid_value", "values": [ "inline" ], "path": [], "message": "Invalid input: expected \"inline\"" } ], [ { "code": "invalid_value", "values": [ "fullscreen" ], "path": [], "message": "Invalid input: expected \"fullscreen\"" } ], [ { "code": "invalid_value", "values": [ "pip" ], "path": [], "message": "Invalid input: expected \"pip\"" } ] ], "path": [ "mode" ], "message": "Invalid input" } ]
SHOULD — assumes the current mode is stable between reading hostContext and the request.
PASSSHOULD — assumes the current mode is stable between reading hostContext and the request.PASSSHOULD — assumes the current mode is stable between reading hostContext and the request.PASSSHOULD — assumes the current mode is stable between reading hostContext and the request.
capabilities/server-passthroughFAILMCP error -32000: Internal Server Error
Exercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.
PASSExercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.FAILMCP error -32000: Unsupported method: resources/list
Exercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.
FAILhost does not advertise serverResources — resource passthrough not supported
Exercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.
PASSExercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.PASSExercises resources/list passthrough (distinct from tools/proxy-call's tools/call). Gated on the host advertising serverResources.
links/open-externalPASSHost-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).PASSHost-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).SKIPhost does not support checkLinkOpen
Host-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).
FAILhost did not open the link
Host-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).
PASSHost-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).PASSHost-vantage: the sandboxed view can't see the host open a tab, so the Runner triggers ui/open-link and verifies a tab opened (accepting a consent dialog if shown; some hosts open with none).
messages/add-to-conversationPASSHost-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).PASSHost-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).FAILhost does not advertise ui/message
Host-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).
FAILhost does not advertise ui/message
Host-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).
PASSHost-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).PASSHost-vantage: the view can't read the host's conversation, so the Runner confirms the marker appeared (some hosts draft into the composer — commitDraftedMessage sends it).
model-context/provide-future-turnsPASSMulti-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.FAILthe model did not receive the seeded context on the next turn
Multi-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.
FAILhost does not advertise ui/update-model-context
Multi-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.
FAILhost does not advertise ui/update-model-context
Multi-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.
PASSMulti-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.PASSMulti-turn, host-vantage: seeds ui/update-model-context then asks the agent to recall it; confirms the host fed the context to the model on the following turn.
sampling/create-messageFAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
FAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
FAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
FAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
FAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
FAILhost does not advertise the sampling capability
Draft. Capability-gated. The host has full discretion (model selection, rate limiting, user approval); the Runner triggers the call, may approve it, and confirms the reply.
download-file/confirmFAILhost does not advertise the downloadFile capability
Draft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.
PASSDraft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.FAILhost does not advertise the downloadFile capability
Draft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.
FAILhost does not advertise the downloadFile capability
Draft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.
FAILhost does not advertise the downloadFile capability
Draft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.
FAILhost does not advertise the downloadFile capability
Draft. Host-vantage: the download and its confirmation dialog occur outside the sandboxed iframe, so the Runner confirms.
security/csp-audit-logFAILno CSP configuration found in the host console (SHOULD log for security review)
Operator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.
PASSOperator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.FAILno CSP configuration found in the host console (SHOULD log for security review)
Operator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.
FAILno CSP configuration found in the host console (SHOULD log for security review)
Operator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.
FAILno CSP configuration found in the host console (SHOULD log for security review)
Operator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.
PASSOperator-observable only: scans the browser console for a logged CSP; a host that logs server-side (not the console) reads as a fail here.
model-context/last-winsPASSSends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.FAILthe agent did not receive the last model-context update
Sends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.
FAILhost does not advertise ui/update-model-context
Sends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.
FAILhost does not advertise ui/update-model-context
Sends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.
PASSSends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.PASSSends two updates before the next user message; the reply should carry the fresh code, not the stale one. Weak if the agent doesn't echo the code verbatim.
MAY
context/theme-variablesPASSOptional (MAY). Signal only — inspect the exact values in the Inspector panel.PASSOptional (MAY). Signal only — inspect the exact values in the Inspector panel.FAILhost provided no style variables
Optional (MAY). Signal only — inspect the exact values in the Inspector panel.
PASSOptional (MAY). Signal only — inspect the exact values in the Inspector panel.PASSOptional (MAY). Signal only — inspect the exact values in the Inspector panel.PASSOptional (MAY). Signal only — inspect the exact values in the Inspector panel.
context/theme-fontsFAILhost provided no custom fonts
Optional (MAY). Signal only — inspect the font CSS in the Inspector panel.
PASSOptional (MAY). Signal only — inspect the font CSS in the Inspector panel.FAILhost provided no custom fonts
Optional (MAY). Signal only — inspect the font CSS in the Inspector panel.
PASSOptional (MAY). Signal only — inspect the font CSS in the Inspector panel.FAILhost provided no custom fonts
Optional (MAY). Signal only — inspect the font CSS in the Inspector panel.
PASSOptional (MAY). Signal only — inspect the font CSS in the Inspector panel.
context/context-changedPASSThe Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).PASSThe Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).SKIPhost did not emit context-changed (may be pinned, not on System)
The Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).
PASSThe Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).PASSThe Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).PASSThe Runner toggles the host theme and the view resolves on the hostcontextchanged notification. SKIP if the host doesn't emit it (e.g. theme pinned, not following the OS).
capabilities/content-modalities
in-view · draft · L663
PASSDraft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.PASSDraft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.FAILhost declares no content-block modalities (message: not declared · updateModelContext: not declared)
Draft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.
FAILhost declares no content-block modalities (message: not declared · updateModelContext: not declared)
Draft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.
PASSDraft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.PASSDraft (specification/draft). Signal only — reports the SupportedContentBlockModalities the host advertises.
app-tools/call
in-view · draft · L1243
FAILthe agent did not call the app-registered tool conformance_ping
Draft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.
FAILthe agent did not call the app-registered tool conformance_ping
Draft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.
FAILthe agent did not call the app-registered tool conformance_ping
Draft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.
FAILthe agent did not call the app-registered tool conformance_ping
Draft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.
FAILthe agent did not call the app-registered tool conformance_ping
Draft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.
PASSDraft (App-Provided Tools). Requires the host to expose app-registered tools to the agent; the Runner asks the agent to call it and the harness detects the callback.

Not yet implemented

TestClauseVantageSpec
security/sandbox-proxy-readyMUSThost2026-01-26 · L476
security/sandbox-resource-readyMUSThost2026-01-26 · L477
security/sandbox-csp-enforcedMUSThost2026-01-26 · L478
security/sandbox-message-forwardingMUSThost2026-01-26 · L485
security/csp-default-denyMUSTin-view2026-01-26 · L483
lifecycle/tool-cancelledMUSTin-view2026-01-26 · L1169
lifecycle/teardown-notifyMUSTin-view2026-01-26 · L1171
resources/read-referencedMUSTserver2026-01-26 · L391
resources/meta-both-locationsMUSTin-viewdraft · L270
resources/meta-precedenceMUSTin-viewdraft · L270
capabilities/mimetypes-requiredREQUIREDserver2026-01-26 · L1522
security/external-domain-warningSHOULDhost2026-01-26 · L1757
lifecycle/teardown-awaitSHOULDin-view2026-01-26 · L1202
download-file/sanitizeSHOULDhostdraft · L1131
sampling/host-discretionSHOULDhostdraft · L534
security/sandbox-no-self-requestsSHOULD NOThost2026-01-26 · L486
security/permissions-allow-attrMAYhost2026-01-26 · L484
security/global-allowlistMAYhost2026-01-26 · L1758
resources/prefetchMAYserver2026-01-26 · L392
display/decline-undeclaredMAYin-view2026-01-26 · L789
model-context/overwrite-defer-dedupe-displayMAYhost2026-01-26 · L1098
download-file/rejectMAYhostdraft · L1130
app-tools/listMAYin-viewdraft · L1286

value


recording