@ai-sdk/mcp 2.0.12 → 2.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 2.0.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 48e7e78: Harden MCP Apps handling of server-supplied resource metadata and the host/iframe bridge:
8
+
9
+ - Runtime-validate `_meta.ui` and drop malformed or non-string fields.
10
+ - Gate iframe permissions deny-by-default via a new `sandbox.allowedPermissions` allowlist.
11
+ - Derive a concrete `postMessage` target origin and validate inbound message origins.
12
+ - Validate inbound bridge params: limit `resources/read` to `ui://` resources and allow only `https`/`http`/`mailto` in `ui/open-link`.
13
+ - Add `fingerprintMCPAppResource` / `detectMCPAppResourceDrift` for pinning and comparing app resources.
14
+
15
+ ## 2.0.13
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [31c7be8]
20
+ - @ai-sdk/provider-utils@5.0.10
21
+
3
22
  ## 2.0.12
4
23
 
5
24
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -762,4 +762,19 @@ declare function readMCPAppResource({ client, uri, options, }: {
762
762
  options?: RequestOptions;
763
763
  }): Promise<MCPAppResource>;
764
764
 
765
- export { type CallToolResult, type CompleteRequestParams, type CompleteResult, type Configuration, type ElicitResult, ElicitResultSchema, type ElicitationRequest, ElicitationRequestSchema, type InitializeResult, type JSONRPCError, type JSONRPCMessage, type JSONRPCNotification, type JSONRPCRequest, type JSONRPCResponse, type ListToolsResult, type MCPAppResource, type MCPAppResourceCSP, type MCPAppResourceMeta, type MCPClient, type ClientCapabilities as MCPClientCapabilities, type MCPClientConfig, type MCPTransport, MCP_APP_MIME_TYPE, type McpProviderMetadata, type OAuthAuthorizationServerInformation, type OAuthClientInformation, type OAuthClientMetadata, type OAuthClientProvider, type OAuthTokens, UnauthorizedError, auth, createMCPClient, type MCPClient as experimental_MCPClient, type ClientCapabilities as experimental_MCPClientCapabilities, type MCPClientConfig as experimental_MCPClientConfig, createMCPClient as experimental_createMCPClient, mcpAppClientCapabilities, readMCPAppResource, splitMCPAppTools, validateJSONRPCMessage };
765
+ /**
766
+ * Stable SHA-256 digest (base64url) over an MCP App resource's `html`, `csp`,
767
+ * and `permissions`.
768
+ *
769
+ * Capture a baseline on first load and compare later reads with
770
+ * {@link detectMCPAppResourceDrift} to detect a changed resource. Baseline
771
+ * storage and the response are the host's concern, mirroring `fingerprintTools`.
772
+ */
773
+ declare function fingerprintMCPAppResource(resource: MCPAppResource): Promise<string>;
774
+ /**
775
+ * Compares two fingerprints from {@link fingerprintMCPAppResource}. Returns
776
+ * `true` when the current resource differs from its baseline.
777
+ */
778
+ declare function detectMCPAppResourceDrift(current: string, baseline: string): boolean;
779
+
780
+ export { type CallToolResult, type CompleteRequestParams, type CompleteResult, type Configuration, type ElicitResult, ElicitResultSchema, type ElicitationRequest, ElicitationRequestSchema, type InitializeResult, type JSONRPCError, type JSONRPCMessage, type JSONRPCNotification, type JSONRPCRequest, type JSONRPCResponse, type ListToolsResult, type MCPAppResource, type MCPAppResourceCSP, type MCPAppResourceMeta, type MCPClient, type ClientCapabilities as MCPClientCapabilities, type MCPClientConfig, type MCPTransport, MCP_APP_MIME_TYPE, type McpProviderMetadata, type OAuthAuthorizationServerInformation, type OAuthClientInformation, type OAuthClientMetadata, type OAuthClientProvider, type OAuthTokens, UnauthorizedError, auth, createMCPClient, detectMCPAppResourceDrift, type MCPClient as experimental_MCPClient, type ClientCapabilities as experimental_MCPClientCapabilities, type MCPClientConfig as experimental_MCPClientConfig, createMCPClient as experimental_createMCPClient, fingerprintMCPAppResource, mcpAppClientCapabilities, readMCPAppResource, splitMCPAppTools, validateJSONRPCMessage };
package/dist/index.js CHANGED
@@ -1971,6 +1971,7 @@ function isCustomMcpTransport(transport) {
1971
1971
  // src/tool/mcp-apps.ts
1972
1972
  import { isJSONObject } from "@ai-sdk/provider";
1973
1973
  import { convertBase64ToUint8Array } from "@ai-sdk/provider-utils";
1974
+ import * as z4 from "zod/v4";
1974
1975
  var MCP_APP_EXTENSION_NAME = "io.modelcontextprotocol/ui";
1975
1976
  var MCP_APP_MIME_TYPE = "text/html;profile=mcp-app";
1976
1977
  var MCP_APP_LEGACY_RESOURCE_URI_META_KEY = "ui/resourceUri";
@@ -1985,11 +1986,25 @@ function getToolUiMeta(meta) {
1985
1986
  const uiMeta = meta == null ? void 0 : meta.ui;
1986
1987
  return isJSONObject(uiMeta) ? uiMeta : void 0;
1987
1988
  }
1989
+ var optionalStringArray = z4.array(z4.unknown()).transform((items) => items.filter((v) => typeof v === "string")).optional().catch(void 0);
1990
+ var MCPAppResourceCSPSchema = z4.looseObject({
1991
+ connectDomains: optionalStringArray,
1992
+ resourceDomains: optionalStringArray,
1993
+ frameDomains: optionalStringArray
1994
+ });
1995
+ var MCPAppResourceMetaSchema = z4.looseObject({
1996
+ prefersBorder: z4.boolean().optional().catch(void 0),
1997
+ csp: MCPAppResourceCSPSchema.optional().catch(void 0),
1998
+ permissions: z4.record(z4.string(), z4.unknown()).optional().catch(void 0)
1999
+ });
1988
2000
  function getResourceUiMeta(meta) {
1989
2001
  const resourceMeta = isJSONObject(meta) ? meta : void 0;
1990
2002
  const rawUiMeta = resourceMeta == null ? void 0 : resourceMeta.ui;
1991
- const uiMeta = isJSONObject(rawUiMeta) ? rawUiMeta : void 0;
1992
- return uiMeta;
2003
+ if (!isJSONObject(rawUiMeta)) {
2004
+ return void 0;
2005
+ }
2006
+ const parsed = MCPAppResourceMetaSchema.safeParse(rawUiMeta);
2007
+ return parsed.success ? parsed.data : void 0;
1993
2008
  }
1994
2009
  function parseVisibility(value) {
1995
2010
  return Array.isArray(value) ? value.filter(
@@ -2790,6 +2805,41 @@ var DefaultMCPClient = class {
2790
2805
  );
2791
2806
  }
2792
2807
  };
2808
+
2809
+ // src/tool/mcp-app-fingerprint.ts
2810
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
2811
+ var encoder = new TextEncoder();
2812
+ function canonicalJSON(value) {
2813
+ if (value == null || typeof value !== "object") {
2814
+ return JSON.stringify(value != null ? value : null);
2815
+ }
2816
+ if (Array.isArray(value)) {
2817
+ return `[${value.map(canonicalJSON).join(",")}]`;
2818
+ }
2819
+ const record2 = value;
2820
+ const entries = Object.keys(record2).sort().map((k) => `${JSON.stringify(k)}:${canonicalJSON(record2[k])}`);
2821
+ return `{${entries.join(",")}}`;
2822
+ }
2823
+ function toBase64url(bytes) {
2824
+ return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
2825
+ }
2826
+ async function fingerprintMCPAppResource(resource) {
2827
+ var _a3, _b3, _c, _d;
2828
+ const digest = await crypto.subtle.digest(
2829
+ "SHA-256",
2830
+ encoder.encode(
2831
+ canonicalJSON({
2832
+ html: resource.html,
2833
+ csp: (_b3 = (_a3 = resource.meta) == null ? void 0 : _a3.csp) != null ? _b3 : null,
2834
+ permissions: (_d = (_c = resource.meta) == null ? void 0 : _c.permissions) != null ? _d : null
2835
+ })
2836
+ )
2837
+ );
2838
+ return toBase64url(new Uint8Array(digest));
2839
+ }
2840
+ function detectMCPAppResourceDrift(current, baseline) {
2841
+ return current !== baseline;
2842
+ }
2793
2843
  export {
2794
2844
  ElicitResultSchema,
2795
2845
  ElicitationRequestSchema,
@@ -2797,7 +2847,9 @@ export {
2797
2847
  UnauthorizedError,
2798
2848
  auth,
2799
2849
  createMCPClient,
2850
+ detectMCPAppResourceDrift,
2800
2851
  createMCPClient as experimental_createMCPClient,
2852
+ fingerprintMCPAppResource,
2801
2853
  mcpAppClientCapabilities,
2802
2854
  readMCPAppResource,
2803
2855
  splitMCPAppTools,