@adcp/sdk 12.0.2 → 12.0.3

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.
Files changed (47) hide show
  1. package/dist/lib/index.d.mts +2 -2
  2. package/dist/lib/index.d.ts +2 -2
  3. package/dist/lib/index.d.ts.map +1 -1
  4. package/dist/lib/index.js +2 -0
  5. package/dist/lib/index.js.map +1 -1
  6. package/dist/lib/index.mjs +3 -1
  7. package/dist/lib/index.mjs.map +1 -1
  8. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  9. package/dist/lib/server/adcp-server.d.ts.map +1 -1
  10. package/dist/lib/server/adcp-server.js +18 -0
  11. package/dist/lib/server/adcp-server.js.map +1 -1
  12. package/dist/lib/server/adcp-server.mjs +15 -0
  13. package/dist/lib/server/adcp-server.mjs.map +1 -1
  14. package/dist/lib/server/create-adcp-server.d.mts +11 -0
  15. package/dist/lib/server/create-adcp-server.d.ts +11 -0
  16. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  17. package/dist/lib/server/create-adcp-server.js +21 -0
  18. package/dist/lib/server/create-adcp-server.js.map +1 -1
  19. package/dist/lib/server/create-adcp-server.mjs +26 -0
  20. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  21. package/dist/lib/server/index.d.mts +2 -0
  22. package/dist/lib/server/index.d.ts +2 -0
  23. package/dist/lib/server/index.d.ts.map +1 -1
  24. package/dist/lib/server/index.js +3 -0
  25. package/dist/lib/server/index.js.map +1 -1
  26. package/dist/lib/server/index.mjs +2 -0
  27. package/dist/lib/server/index.mjs.map +1 -1
  28. package/dist/lib/server/mcp-app.d.mts +57 -0
  29. package/dist/lib/server/mcp-app.d.ts +58 -0
  30. package/dist/lib/server/mcp-app.d.ts.map +1 -0
  31. package/dist/lib/server/mcp-app.js +110 -0
  32. package/dist/lib/server/mcp-app.js.map +1 -0
  33. package/dist/lib/server/mcp-app.mjs +83 -0
  34. package/dist/lib/server/mcp-app.mjs.map +1 -0
  35. package/dist/lib/server/mcp-modern-server.d.ts.map +1 -1
  36. package/dist/lib/server/mcp-modern-server.js +23 -1
  37. package/dist/lib/server/mcp-modern-server.js.map +1 -1
  38. package/dist/lib/server/mcp-modern-server.mjs +24 -1
  39. package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
  40. package/dist/lib/version.d.mts +3 -3
  41. package/dist/lib/version.d.ts +3 -3
  42. package/dist/lib/version.js +3 -3
  43. package/dist/lib/version.js.map +1 -1
  44. package/dist/lib/version.mjs +3 -3
  45. package/dist/lib/version.mjs.map +1 -1
  46. package/docs/guides/BUILD-AN-AGENT.md +70 -0
  47. package/package.json +1 -1
@@ -0,0 +1,83 @@
1
+ const MCP_APP_RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
2
+ function normalizeMcpAppResources(resources) {
3
+ if (resources === void 0) return [];
4
+ const names = /* @__PURE__ */ new Set();
5
+ const uris = /* @__PURE__ */ new Set();
6
+ return resources.map((resource, index) => {
7
+ const path = `resources[${index}]`;
8
+ if (!resource || typeof resource !== "object") {
9
+ throw new Error(`createAdcpServer: ${path} must be an MCP App resource definition`);
10
+ }
11
+ if (typeof resource.name !== "string" || resource.name.trim() === "") {
12
+ throw new Error(`createAdcpServer: ${path}.name must be a non-empty string`);
13
+ }
14
+ if (names.has(resource.name)) {
15
+ throw new Error(`createAdcpServer: duplicate MCP App resource name "${resource.name}"`);
16
+ }
17
+ names.add(resource.name);
18
+ if (typeof resource.uri !== "string" || !resource.uri.startsWith("ui://")) {
19
+ throw new Error(`createAdcpServer: ${path}.uri must use the ui:// scheme`);
20
+ }
21
+ try {
22
+ const parsed = new URL(resource.uri);
23
+ if (parsed.protocol !== "ui:" || parsed.hostname === "" && parsed.pathname === "") throw new Error("empty URI");
24
+ if (parsed.href !== resource.uri) {
25
+ throw new Error(`non-canonical URI; use "${parsed.href}"`);
26
+ }
27
+ } catch (error) {
28
+ const detail = error instanceof Error && error.message.startsWith("non-canonical URI") ? ` (${error.message})` : "";
29
+ throw new Error(`createAdcpServer: ${path}.uri must be a valid canonical ui:// URI${detail}`);
30
+ }
31
+ if (uris.has(resource.uri)) {
32
+ throw new Error(`createAdcpServer: duplicate MCP App resource URI "${resource.uri}"`);
33
+ }
34
+ uris.add(resource.uri);
35
+ if (resource.mimeType !== void 0 && resource.mimeType !== MCP_APP_RESOURCE_MIME_TYPE) {
36
+ throw new Error(
37
+ `createAdcpServer: ${path}.mimeType must be "${MCP_APP_RESOURCE_MIME_TYPE}" for an MCP App resource`
38
+ );
39
+ }
40
+ if (typeof resource.handler !== "function") {
41
+ throw new Error(`createAdcpServer: ${path}.handler must be a function`);
42
+ }
43
+ return { ...resource, mimeType: MCP_APP_RESOURCE_MIME_TYPE };
44
+ });
45
+ }
46
+ function mcpAppResourceMetadata(resource) {
47
+ return {
48
+ ...resource.title !== void 0 && { title: resource.title },
49
+ ...resource.description !== void 0 && { description: resource.description },
50
+ mimeType: MCP_APP_RESOURCE_MIME_TYPE,
51
+ ...resource._meta !== void 0 && { _meta: resource._meta }
52
+ };
53
+ }
54
+ async function readMcpAppResource(resource, uri, ctx) {
55
+ let text;
56
+ try {
57
+ const result = await resource.handler(uri, ctx);
58
+ if (typeof result !== "string") {
59
+ throw new TypeError(`handler returned ${result === null ? "null" : typeof result}, not a string`);
60
+ }
61
+ text = result;
62
+ } catch (error) {
63
+ console.error(`[adcp/mcp-app] resource handler "${resource.name}" failed`, error);
64
+ throw new Error("MCP App resource is temporarily unavailable");
65
+ }
66
+ return {
67
+ contents: [
68
+ {
69
+ uri: uri.href,
70
+ mimeType: MCP_APP_RESOURCE_MIME_TYPE,
71
+ text,
72
+ ...resource._meta !== void 0 && { _meta: resource._meta }
73
+ }
74
+ ]
75
+ };
76
+ }
77
+ export {
78
+ MCP_APP_RESOURCE_MIME_TYPE,
79
+ mcpAppResourceMetadata,
80
+ normalizeMcpAppResources,
81
+ readMcpAppResource
82
+ };
83
+ //# sourceMappingURL=mcp-app.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/server/mcp-app.ts"],"sourcesContent":["/** MIME type required by the stable MCP Apps HTML resource contract. */\nexport const MCP_APP_RESOURCE_MIME_TYPE = 'text/html;profile=mcp-app' as const;\n\n/** Content Security Policy sources requested by an MCP App resource. */\nexport interface McpAppResourceCsp {\n /** Origins allowed for fetch, XHR, and WebSocket connections. */\n connectDomains?: string[];\n /** Origins allowed for scripts, styles, images, fonts, and media. */\n resourceDomains?: string[];\n /** Origins allowed for nested iframes. */\n frameDomains?: string[];\n /** Origins allowed in the document's base URI. */\n baseUriDomains?: string[];\n}\n\n/** Browser permissions an MCP App may ask its host to grant. */\nexport interface McpAppResourcePermissions {\n camera?: Record<string, never>;\n microphone?: Record<string, never>;\n geolocation?: Record<string, never>;\n clipboardWrite?: Record<string, never>;\n}\n\n/** Security and presentation hints for an MCP App resource. */\nexport interface McpAppResourceUiMeta {\n csp?: McpAppResourceCsp;\n permissions?: McpAppResourcePermissions;\n /** Host-specific dedicated sandbox domain. */\n domain?: string;\n /** Whether the host should render a visible boundary around the app. */\n prefersBorder?: boolean;\n}\n\n/** Typed metadata emitted on both resource discovery and resource content. */\nexport interface McpAppResourceMeta {\n ui?: McpAppResourceUiMeta;\n}\n\n/** Transport-neutral context passed to an MCP App resource handler. */\nexport interface McpAppResourceReadContext {\n signal: AbortSignal;\n}\n\n/**\n * Declarative registration for one static HTML MCP App resource.\n *\n * The framework registers the resource on both the legacy MCP SDK server and\n * every modern per-request server reconstruction. The handler returns the\n * complete HTML document; the framework owns the URI, MIME type, and metadata\n * in the `resources/read` response so discovery and readback cannot drift.\n */\nexport interface AdcpMcpResourceDefinition {\n /** Stable programmatic name surfaced by `resources/list`. */\n name: string;\n /** MCP Apps require the `ui://` URI scheme. */\n uri: `ui://${string}`;\n title?: string;\n description?: string;\n /** Defaults to the only MIME type currently supported by MCP Apps. */\n mimeType?: typeof MCP_APP_RESOURCE_MIME_TYPE;\n _meta?: McpAppResourceMeta;\n handler: (uri: URL, ctx: McpAppResourceReadContext) => string | Promise<string>;\n}\n\n/** @internal */\nexport function normalizeMcpAppResources(\n resources: readonly AdcpMcpResourceDefinition[] | undefined\n): readonly AdcpMcpResourceDefinition[] {\n if (resources === undefined) return [];\n\n const names = new Set<string>();\n const uris = new Set<string>();\n return resources.map((resource, index) => {\n const path = `resources[${index}]`;\n if (!resource || typeof resource !== 'object') {\n throw new Error(`createAdcpServer: ${path} must be an MCP App resource definition`);\n }\n if (typeof resource.name !== 'string' || resource.name.trim() === '') {\n throw new Error(`createAdcpServer: ${path}.name must be a non-empty string`);\n }\n if (names.has(resource.name)) {\n throw new Error(`createAdcpServer: duplicate MCP App resource name \"${resource.name}\"`);\n }\n names.add(resource.name);\n\n if (typeof resource.uri !== 'string' || !resource.uri.startsWith('ui://')) {\n throw new Error(`createAdcpServer: ${path}.uri must use the ui:// scheme`);\n }\n try {\n const parsed = new URL(resource.uri);\n if (parsed.protocol !== 'ui:' || (parsed.hostname === '' && parsed.pathname === '')) throw new Error('empty URI');\n if (parsed.href !== resource.uri) {\n throw new Error(`non-canonical URI; use \"${parsed.href}\"`);\n }\n } catch (error) {\n const detail =\n error instanceof Error && error.message.startsWith('non-canonical URI') ? ` (${error.message})` : '';\n throw new Error(`createAdcpServer: ${path}.uri must be a valid canonical ui:// URI${detail}`);\n }\n if (uris.has(resource.uri)) {\n throw new Error(`createAdcpServer: duplicate MCP App resource URI \"${resource.uri}\"`);\n }\n uris.add(resource.uri);\n\n if (resource.mimeType !== undefined && resource.mimeType !== MCP_APP_RESOURCE_MIME_TYPE) {\n throw new Error(\n `createAdcpServer: ${path}.mimeType must be \"${MCP_APP_RESOURCE_MIME_TYPE}\" for an MCP App resource`\n );\n }\n if (typeof resource.handler !== 'function') {\n throw new Error(`createAdcpServer: ${path}.handler must be a function`);\n }\n\n return { ...resource, mimeType: MCP_APP_RESOURCE_MIME_TYPE };\n });\n}\n\n/** @internal */\nexport function mcpAppResourceMetadata(resource: AdcpMcpResourceDefinition): Record<string, unknown> {\n return {\n ...(resource.title !== undefined && { title: resource.title }),\n ...(resource.description !== undefined && { description: resource.description }),\n mimeType: MCP_APP_RESOURCE_MIME_TYPE,\n ...(resource._meta !== undefined && { _meta: resource._meta }),\n };\n}\n\n/** @internal */\nexport async function readMcpAppResource(\n resource: AdcpMcpResourceDefinition,\n uri: URL,\n ctx: McpAppResourceReadContext\n): Promise<{\n contents: Array<{\n uri: string;\n mimeType: typeof MCP_APP_RESOURCE_MIME_TYPE;\n text: string;\n _meta?: Record<string, unknown>;\n }>;\n}> {\n let text: string;\n try {\n const result = await resource.handler(uri, ctx);\n if (typeof result !== 'string') {\n throw new TypeError(`handler returned ${result === null ? 'null' : typeof result}, not a string`);\n }\n text = result;\n } catch (error) {\n // Resource callbacks sit outside the AdCP tool-error envelope. Log the\n // private cause here, then expose a fixed message so provider errors,\n // file paths, and credentials never become JSON-RPC error text.\n console.error(`[adcp/mcp-app] resource handler \"${resource.name}\" failed`, error);\n throw new Error('MCP App resource is temporarily unavailable');\n }\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: MCP_APP_RESOURCE_MIME_TYPE,\n text,\n ...(resource._meta !== undefined && { _meta: resource._meta as Record<string, unknown> }),\n },\n ],\n };\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-modern-server.d.ts","sourceRoot":"","sources":["../../../src/lib/server/mcp-modern-server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,EAA+B,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAY5C,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
1
+ {"version":3,"file":"mcp-modern-server.d.ts","sourceRoot":"","sources":["../../../src/lib/server/mcp-modern-server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,OAAO,EAA+B,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAc5C,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
@@ -25,6 +25,7 @@ var import_server = require("@modelcontextprotocol/server");
25
25
  var import_node = require("@modelcontextprotocol/node");
26
26
  var import_adcp_server = require('./adcp-server.js');
27
27
  var import_create_adcp_server = require('./create-adcp-server.js');
28
+ var import_mcp_app = require('./mcp-app.js');
28
29
  function toAdcpAuthInfo(authInfo) {
29
30
  if (!authInfo) return void 0;
30
31
  return {
@@ -35,6 +36,12 @@ function toAdcpAuthInfo(authInfo) {
35
36
  ...authInfo.extra !== void 0 && { extra: authInfo.extra }
36
37
  };
37
38
  }
39
+ function linkedMcpAppResourceUri(tool) {
40
+ const ui = tool._meta?.["ui"];
41
+ if (ui === null || typeof ui !== "object") return void 0;
42
+ const resourceUri = ui["resourceUri"];
43
+ return typeof resourceUri === "string" ? resourceUri : void 0;
44
+ }
38
45
  function createModernMcpServerAdapter(agentServer) {
39
46
  const sdkServer = (0, import_adcp_server.getSdkServer)(agentServer);
40
47
  if (!sdkServer) {
@@ -55,8 +62,11 @@ function createModernMcpServerAdapter(agentServer) {
55
62
  { instructions: (0, import_adcp_server.getSdkServerInstructions)(sdkServer) }
56
63
  );
57
64
  const authInfo = toAdcpAuthInfo(requestContext.authInfo);
65
+ const toolVisibility = /* @__PURE__ */ new Map();
58
66
  for (const tool of toolDefinitions) {
59
- if (!await (0, import_adcp_server.isRegisteredToolVisible)(agentServer, { toolName: tool.name, authInfo })) continue;
67
+ const visible = await (0, import_adcp_server.isRegisteredToolVisible)(agentServer, { toolName: tool.name, authInfo });
68
+ toolVisibility.set(tool.name, visible);
69
+ if (!visible) continue;
60
70
  const config = {
61
71
  ...tool.title !== void 0 && { title: tool.title },
62
72
  ...tool.description !== void 0 && { description: tool.description },
@@ -82,6 +92,18 @@ function createModernMcpServerAdapter(agentServer) {
82
92
  modern.registerTool(tool.name, config, async (ctx) => invoke({}, ctx));
83
93
  }
84
94
  }
95
+ for (const resource of (0, import_adcp_server.listMcpAppResources)(agentServer)) {
96
+ const linkedTools = toolDefinitions.filter((tool) => linkedMcpAppResourceUri(tool) === resource.uri);
97
+ if (linkedTools.length > 0 && !linkedTools.some((tool) => toolVisibility.get(tool.name) === true)) continue;
98
+ modern.registerResource(
99
+ resource.name,
100
+ resource.uri,
101
+ (0, import_mcp_app.mcpAppResourceMetadata)(resource),
102
+ async (uri, ctx) => (0, import_mcp_app.readMcpAppResource)(resource, uri, {
103
+ signal: ctx.mcpReq.signal
104
+ })
105
+ );
106
+ }
85
107
  return modern;
86
108
  },
87
109
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/server/mcp-modern-server.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 server adapter.\n *\n * AdCP's handler pipeline remains registered on the v1 SDK server so legacy\n * MCP Tasks continue to work. This adapter mirrors only the public tool\n * definitions into the official v2 SDK and dispatches calls through the\n * opaque AdcpServer.invoke() surface.\n */\n\nimport {\n McpServer as ModernMcpServer,\n createMcpHandler,\n isLegacyRequest,\n type AuthInfo as ModernAuthInfo,\n type StandardSchemaWithJSON,\n type ServerContext,\n type ToolAnnotations,\n} from '@modelcontextprotocol/server';\nimport { toNodeHandler, toWebRequest, type NodeMcpRequestHandler } from '@modelcontextprotocol/node';\nimport type { IncomingMessage } from 'http';\nimport {\n getSdkServer,\n getSdkServerInfo,\n getSdkServerInstructions,\n isRegisteredToolVisible,\n listRegisteredToolDefinitions,\n type AdcpAuthInfo,\n type AdcpServer,\n} from './adcp-server';\nimport { ADCP_INSTRUCTIONS_RESOLVER } from './create-adcp-server';\n\nexport interface ModernMcpServerAdapter {\n handle: NodeMcpRequestHandler;\n isLegacyRequest(req: IncomingMessage, parsedBody: unknown): Promise<boolean>;\n close(): Promise<void>;\n}\n\nfunction toAdcpAuthInfo(authInfo: ModernAuthInfo | undefined): AdcpAuthInfo | undefined {\n if (!authInfo) return undefined;\n return {\n token: authInfo.token,\n clientId: authInfo.clientId,\n scopes: authInfo.scopes,\n ...(authInfo.expiresAt !== undefined && { expiresAt: authInfo.expiresAt }),\n ...(authInfo.extra !== undefined && { extra: authInfo.extra }),\n };\n}\n\n/** Build a strict 2026-07-28 handler around one configured AdCP server. @internal */\nexport function createModernMcpServerAdapter(agentServer: AdcpServer): ModernMcpServerAdapter {\n const sdkServer = getSdkServer(agentServer);\n if (!sdkServer) {\n throw new Error('Modern MCP serving requires an AdcpServer backed by the official MCP SDK');\n }\n\n const serverInfo = getSdkServerInfo(sdkServer);\n const toolDefinitions = listRegisteredToolDefinitions(sdkServer);\n const handler = createMcpHandler(\n async requestContext => {\n if (requestContext.requestInfo?.headers.get('mcp-method') === 'server/discover') {\n const instructionsResolver = (agentServer as unknown as Record<symbol, unknown>)[ADCP_INSTRUCTIONS_RESOLVER];\n if (typeof instructionsResolver === 'function') {\n await (instructionsResolver as () => Promise<string | undefined>)();\n }\n }\n const modern = new ModernMcpServer(\n { name: serverInfo.name, version: serverInfo.version },\n { instructions: getSdkServerInstructions(sdkServer) }\n );\n\n const authInfo = toAdcpAuthInfo(requestContext.authInfo);\n for (const tool of toolDefinitions) {\n if (!(await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo }))) continue;\n const config = {\n ...(tool.title !== undefined && { title: tool.title }),\n ...(tool.description !== undefined && { description: tool.description }),\n ...(tool.outputSchema !== undefined && {\n outputSchema: tool.outputSchema as StandardSchemaWithJSON,\n }),\n ...(tool.annotations !== undefined && { annotations: tool.annotations as ToolAnnotations }),\n ...(tool._meta !== undefined && { _meta: tool._meta }),\n };\n const invoke = (args: Record<string, unknown>, ctx: ServerContext) =>\n agentServer.invoke({\n toolName: tool.name,\n args,\n authInfo: toAdcpAuthInfo(ctx.http?.authInfo),\n signal: ctx.mcpReq.signal,\n });\n\n if (tool.inputSchema !== undefined) {\n modern.registerTool(\n tool.name,\n { ...config, inputSchema: tool.inputSchema as StandardSchemaWithJSON },\n async (args, ctx) => invoke((args ?? {}) as Record<string, unknown>, ctx)\n );\n } else {\n modern.registerTool(tool.name, config, async ctx => invoke({}, ctx));\n }\n }\n\n return modern;\n },\n {\n legacy: 'reject',\n onerror(error) {\n console.error('[adcp/serve] modern MCP error:', error);\n },\n }\n );\n\n return {\n handle: toNodeHandler(handler, {\n onerror(error) {\n console.error('[adcp/serve] modern MCP Node adapter error:', error);\n },\n }),\n async isLegacyRequest(req, parsedBody) {\n const request = await toWebRequest(req, parsedBody);\n return isLegacyRequest(request, parsedBody);\n },\n close: () => handler.close(),\n };\n}\n"],"mappings":"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","names":["ModernMcpServer"]}
1
+ {"version":3,"sources":["../../../src/lib/server/mcp-modern-server.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 server adapter.\n *\n * AdCP's handler pipeline remains registered on the v1 SDK server so legacy\n * MCP Tasks continue to work. This adapter mirrors only the public tool\n * definitions into the official v2 SDK and dispatches calls through the\n * opaque AdcpServer.invoke() surface.\n */\n\nimport {\n McpServer as ModernMcpServer,\n createMcpHandler,\n isLegacyRequest,\n type AuthInfo as ModernAuthInfo,\n type ResourceMetadata,\n type StandardSchemaWithJSON,\n type ServerContext,\n type ToolAnnotations,\n} from '@modelcontextprotocol/server';\nimport { toNodeHandler, toWebRequest, type NodeMcpRequestHandler } from '@modelcontextprotocol/node';\nimport type { IncomingMessage } from 'http';\nimport {\n getSdkServer,\n getSdkServerInfo,\n getSdkServerInstructions,\n isRegisteredToolVisible,\n listMcpAppResources,\n listRegisteredToolDefinitions,\n type AdcpAuthInfo,\n type AdcpServer,\n} from './adcp-server';\nimport { ADCP_INSTRUCTIONS_RESOLVER } from './create-adcp-server';\nimport { mcpAppResourceMetadata, readMcpAppResource } from './mcp-app';\n\nexport interface ModernMcpServerAdapter {\n handle: NodeMcpRequestHandler;\n isLegacyRequest(req: IncomingMessage, parsedBody: unknown): Promise<boolean>;\n close(): Promise<void>;\n}\n\nfunction toAdcpAuthInfo(authInfo: ModernAuthInfo | undefined): AdcpAuthInfo | undefined {\n if (!authInfo) return undefined;\n return {\n token: authInfo.token,\n clientId: authInfo.clientId,\n scopes: authInfo.scopes,\n ...(authInfo.expiresAt !== undefined && { expiresAt: authInfo.expiresAt }),\n ...(authInfo.extra !== undefined && { extra: authInfo.extra }),\n };\n}\n\nfunction linkedMcpAppResourceUri(tool: { _meta?: Record<string, unknown> }): string | undefined {\n const ui = tool._meta?.['ui'];\n if (ui === null || typeof ui !== 'object') return undefined;\n const resourceUri = (ui as Record<string, unknown>)['resourceUri'];\n return typeof resourceUri === 'string' ? resourceUri : undefined;\n}\n\n/** Build a strict 2026-07-28 handler around one configured AdCP server. @internal */\nexport function createModernMcpServerAdapter(agentServer: AdcpServer): ModernMcpServerAdapter {\n const sdkServer = getSdkServer(agentServer);\n if (!sdkServer) {\n throw new Error('Modern MCP serving requires an AdcpServer backed by the official MCP SDK');\n }\n\n const serverInfo = getSdkServerInfo(sdkServer);\n const toolDefinitions = listRegisteredToolDefinitions(sdkServer);\n const handler = createMcpHandler(\n async requestContext => {\n if (requestContext.requestInfo?.headers.get('mcp-method') === 'server/discover') {\n const instructionsResolver = (agentServer as unknown as Record<symbol, unknown>)[ADCP_INSTRUCTIONS_RESOLVER];\n if (typeof instructionsResolver === 'function') {\n await (instructionsResolver as () => Promise<string | undefined>)();\n }\n }\n const modern = new ModernMcpServer(\n { name: serverInfo.name, version: serverInfo.version },\n { instructions: getSdkServerInstructions(sdkServer) }\n );\n\n const authInfo = toAdcpAuthInfo(requestContext.authInfo);\n const toolVisibility = new Map<string, boolean>();\n for (const tool of toolDefinitions) {\n const visible = await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo });\n toolVisibility.set(tool.name, visible);\n if (!visible) continue;\n const config = {\n ...(tool.title !== undefined && { title: tool.title }),\n ...(tool.description !== undefined && { description: tool.description }),\n ...(tool.outputSchema !== undefined && {\n outputSchema: tool.outputSchema as StandardSchemaWithJSON,\n }),\n ...(tool.annotations !== undefined && { annotations: tool.annotations as ToolAnnotations }),\n ...(tool._meta !== undefined && { _meta: tool._meta }),\n };\n const invoke = (args: Record<string, unknown>, ctx: ServerContext) =>\n agentServer.invoke({\n toolName: tool.name,\n args,\n authInfo: toAdcpAuthInfo(ctx.http?.authInfo),\n signal: ctx.mcpReq.signal,\n });\n\n if (tool.inputSchema !== undefined) {\n modern.registerTool(\n tool.name,\n { ...config, inputSchema: tool.inputSchema as StandardSchemaWithJSON },\n async (args, ctx) => invoke((args ?? {}) as Record<string, unknown>, ctx)\n );\n } else {\n modern.registerTool(tool.name, config, async ctx => invoke({}, ctx));\n }\n }\n\n // `createMcpHandler` reconstructs the MCP v2 server for every request,\n // so resources must be registered inside the factory rather than once\n // when the opaque AdCP server is created.\n for (const resource of listMcpAppResources(agentServer)) {\n const linkedTools = toolDefinitions.filter(tool => linkedMcpAppResourceUri(tool) === resource.uri);\n if (linkedTools.length > 0 && !linkedTools.some(tool => toolVisibility.get(tool.name) === true)) continue;\n modern.registerResource(\n resource.name,\n resource.uri,\n mcpAppResourceMetadata(resource) as ResourceMetadata,\n async (uri, ctx) =>\n readMcpAppResource(resource, uri, {\n signal: ctx.mcpReq.signal,\n })\n );\n }\n\n return modern;\n },\n {\n legacy: 'reject',\n onerror(error) {\n console.error('[adcp/serve] modern MCP error:', error);\n },\n }\n );\n\n return {\n handle: toNodeHandler(handler, {\n onerror(error) {\n console.error('[adcp/serve] modern MCP Node adapter error:', error);\n },\n }),\n async isLegacyRequest(req, parsedBody) {\n const request = await toWebRequest(req, parsedBody);\n return isLegacyRequest(request, parsedBody);\n },\n close: () => handler.close(),\n };\n}\n"],"mappings":"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","names":["ModernMcpServer"]}
@@ -9,9 +9,11 @@ import {
9
9
  getSdkServerInfo,
10
10
  getSdkServerInstructions,
11
11
  isRegisteredToolVisible,
12
+ listMcpAppResources,
12
13
  listRegisteredToolDefinitions
13
14
  } from "./adcp-server.mjs";
14
15
  import { ADCP_INSTRUCTIONS_RESOLVER } from "./create-adcp-server.mjs";
16
+ import { mcpAppResourceMetadata, readMcpAppResource } from "./mcp-app.mjs";
15
17
  function toAdcpAuthInfo(authInfo) {
16
18
  if (!authInfo) return void 0;
17
19
  return {
@@ -22,6 +24,12 @@ function toAdcpAuthInfo(authInfo) {
22
24
  ...authInfo.extra !== void 0 && { extra: authInfo.extra }
23
25
  };
24
26
  }
27
+ function linkedMcpAppResourceUri(tool) {
28
+ const ui = tool._meta?.["ui"];
29
+ if (ui === null || typeof ui !== "object") return void 0;
30
+ const resourceUri = ui["resourceUri"];
31
+ return typeof resourceUri === "string" ? resourceUri : void 0;
32
+ }
25
33
  function createModernMcpServerAdapter(agentServer) {
26
34
  const sdkServer = getSdkServer(agentServer);
27
35
  if (!sdkServer) {
@@ -42,8 +50,11 @@ function createModernMcpServerAdapter(agentServer) {
42
50
  { instructions: getSdkServerInstructions(sdkServer) }
43
51
  );
44
52
  const authInfo = toAdcpAuthInfo(requestContext.authInfo);
53
+ const toolVisibility = /* @__PURE__ */ new Map();
45
54
  for (const tool of toolDefinitions) {
46
- if (!await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo })) continue;
55
+ const visible = await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo });
56
+ toolVisibility.set(tool.name, visible);
57
+ if (!visible) continue;
47
58
  const config = {
48
59
  ...tool.title !== void 0 && { title: tool.title },
49
60
  ...tool.description !== void 0 && { description: tool.description },
@@ -69,6 +80,18 @@ function createModernMcpServerAdapter(agentServer) {
69
80
  modern.registerTool(tool.name, config, async (ctx) => invoke({}, ctx));
70
81
  }
71
82
  }
83
+ for (const resource of listMcpAppResources(agentServer)) {
84
+ const linkedTools = toolDefinitions.filter((tool) => linkedMcpAppResourceUri(tool) === resource.uri);
85
+ if (linkedTools.length > 0 && !linkedTools.some((tool) => toolVisibility.get(tool.name) === true)) continue;
86
+ modern.registerResource(
87
+ resource.name,
88
+ resource.uri,
89
+ mcpAppResourceMetadata(resource),
90
+ async (uri, ctx) => readMcpAppResource(resource, uri, {
91
+ signal: ctx.mcpReq.signal
92
+ })
93
+ );
94
+ }
72
95
  return modern;
73
96
  },
74
97
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/server/mcp-modern-server.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 server adapter.\n *\n * AdCP's handler pipeline remains registered on the v1 SDK server so legacy\n * MCP Tasks continue to work. This adapter mirrors only the public tool\n * definitions into the official v2 SDK and dispatches calls through the\n * opaque AdcpServer.invoke() surface.\n */\n\nimport {\n McpServer as ModernMcpServer,\n createMcpHandler,\n isLegacyRequest,\n type AuthInfo as ModernAuthInfo,\n type StandardSchemaWithJSON,\n type ServerContext,\n type ToolAnnotations,\n} from '@modelcontextprotocol/server';\nimport { toNodeHandler, toWebRequest, type NodeMcpRequestHandler } from '@modelcontextprotocol/node';\nimport type { IncomingMessage } from 'http';\nimport {\n getSdkServer,\n getSdkServerInfo,\n getSdkServerInstructions,\n isRegisteredToolVisible,\n listRegisteredToolDefinitions,\n type AdcpAuthInfo,\n type AdcpServer,\n} from './adcp-server';\nimport { ADCP_INSTRUCTIONS_RESOLVER } from './create-adcp-server';\n\nexport interface ModernMcpServerAdapter {\n handle: NodeMcpRequestHandler;\n isLegacyRequest(req: IncomingMessage, parsedBody: unknown): Promise<boolean>;\n close(): Promise<void>;\n}\n\nfunction toAdcpAuthInfo(authInfo: ModernAuthInfo | undefined): AdcpAuthInfo | undefined {\n if (!authInfo) return undefined;\n return {\n token: authInfo.token,\n clientId: authInfo.clientId,\n scopes: authInfo.scopes,\n ...(authInfo.expiresAt !== undefined && { expiresAt: authInfo.expiresAt }),\n ...(authInfo.extra !== undefined && { extra: authInfo.extra }),\n };\n}\n\n/** Build a strict 2026-07-28 handler around one configured AdCP server. @internal */\nexport function createModernMcpServerAdapter(agentServer: AdcpServer): ModernMcpServerAdapter {\n const sdkServer = getSdkServer(agentServer);\n if (!sdkServer) {\n throw new Error('Modern MCP serving requires an AdcpServer backed by the official MCP SDK');\n }\n\n const serverInfo = getSdkServerInfo(sdkServer);\n const toolDefinitions = listRegisteredToolDefinitions(sdkServer);\n const handler = createMcpHandler(\n async requestContext => {\n if (requestContext.requestInfo?.headers.get('mcp-method') === 'server/discover') {\n const instructionsResolver = (agentServer as unknown as Record<symbol, unknown>)[ADCP_INSTRUCTIONS_RESOLVER];\n if (typeof instructionsResolver === 'function') {\n await (instructionsResolver as () => Promise<string | undefined>)();\n }\n }\n const modern = new ModernMcpServer(\n { name: serverInfo.name, version: serverInfo.version },\n { instructions: getSdkServerInstructions(sdkServer) }\n );\n\n const authInfo = toAdcpAuthInfo(requestContext.authInfo);\n for (const tool of toolDefinitions) {\n if (!(await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo }))) continue;\n const config = {\n ...(tool.title !== undefined && { title: tool.title }),\n ...(tool.description !== undefined && { description: tool.description }),\n ...(tool.outputSchema !== undefined && {\n outputSchema: tool.outputSchema as StandardSchemaWithJSON,\n }),\n ...(tool.annotations !== undefined && { annotations: tool.annotations as ToolAnnotations }),\n ...(tool._meta !== undefined && { _meta: tool._meta }),\n };\n const invoke = (args: Record<string, unknown>, ctx: ServerContext) =>\n agentServer.invoke({\n toolName: tool.name,\n args,\n authInfo: toAdcpAuthInfo(ctx.http?.authInfo),\n signal: ctx.mcpReq.signal,\n });\n\n if (tool.inputSchema !== undefined) {\n modern.registerTool(\n tool.name,\n { ...config, inputSchema: tool.inputSchema as StandardSchemaWithJSON },\n async (args, ctx) => invoke((args ?? {}) as Record<string, unknown>, ctx)\n );\n } else {\n modern.registerTool(tool.name, config, async ctx => invoke({}, ctx));\n }\n }\n\n return modern;\n },\n {\n legacy: 'reject',\n onerror(error) {\n console.error('[adcp/serve] modern MCP error:', error);\n },\n }\n );\n\n return {\n handle: toNodeHandler(handler, {\n onerror(error) {\n console.error('[adcp/serve] modern MCP Node adapter error:', error);\n },\n }),\n async isLegacyRequest(req, parsedBody) {\n const request = await toWebRequest(req, parsedBody);\n return isLegacyRequest(request, parsedBody);\n },\n close: () => handler.close(),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/server/mcp-modern-server.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 server adapter.\n *\n * AdCP's handler pipeline remains registered on the v1 SDK server so legacy\n * MCP Tasks continue to work. This adapter mirrors only the public tool\n * definitions into the official v2 SDK and dispatches calls through the\n * opaque AdcpServer.invoke() surface.\n */\n\nimport {\n McpServer as ModernMcpServer,\n createMcpHandler,\n isLegacyRequest,\n type AuthInfo as ModernAuthInfo,\n type ResourceMetadata,\n type StandardSchemaWithJSON,\n type ServerContext,\n type ToolAnnotations,\n} from '@modelcontextprotocol/server';\nimport { toNodeHandler, toWebRequest, type NodeMcpRequestHandler } from '@modelcontextprotocol/node';\nimport type { IncomingMessage } from 'http';\nimport {\n getSdkServer,\n getSdkServerInfo,\n getSdkServerInstructions,\n isRegisteredToolVisible,\n listMcpAppResources,\n listRegisteredToolDefinitions,\n type AdcpAuthInfo,\n type AdcpServer,\n} from './adcp-server';\nimport { ADCP_INSTRUCTIONS_RESOLVER } from './create-adcp-server';\nimport { mcpAppResourceMetadata, readMcpAppResource } from './mcp-app';\n\nexport interface ModernMcpServerAdapter {\n handle: NodeMcpRequestHandler;\n isLegacyRequest(req: IncomingMessage, parsedBody: unknown): Promise<boolean>;\n close(): Promise<void>;\n}\n\nfunction toAdcpAuthInfo(authInfo: ModernAuthInfo | undefined): AdcpAuthInfo | undefined {\n if (!authInfo) return undefined;\n return {\n token: authInfo.token,\n clientId: authInfo.clientId,\n scopes: authInfo.scopes,\n ...(authInfo.expiresAt !== undefined && { expiresAt: authInfo.expiresAt }),\n ...(authInfo.extra !== undefined && { extra: authInfo.extra }),\n };\n}\n\nfunction linkedMcpAppResourceUri(tool: { _meta?: Record<string, unknown> }): string | undefined {\n const ui = tool._meta?.['ui'];\n if (ui === null || typeof ui !== 'object') return undefined;\n const resourceUri = (ui as Record<string, unknown>)['resourceUri'];\n return typeof resourceUri === 'string' ? resourceUri : undefined;\n}\n\n/** Build a strict 2026-07-28 handler around one configured AdCP server. @internal */\nexport function createModernMcpServerAdapter(agentServer: AdcpServer): ModernMcpServerAdapter {\n const sdkServer = getSdkServer(agentServer);\n if (!sdkServer) {\n throw new Error('Modern MCP serving requires an AdcpServer backed by the official MCP SDK');\n }\n\n const serverInfo = getSdkServerInfo(sdkServer);\n const toolDefinitions = listRegisteredToolDefinitions(sdkServer);\n const handler = createMcpHandler(\n async requestContext => {\n if (requestContext.requestInfo?.headers.get('mcp-method') === 'server/discover') {\n const instructionsResolver = (agentServer as unknown as Record<symbol, unknown>)[ADCP_INSTRUCTIONS_RESOLVER];\n if (typeof instructionsResolver === 'function') {\n await (instructionsResolver as () => Promise<string | undefined>)();\n }\n }\n const modern = new ModernMcpServer(\n { name: serverInfo.name, version: serverInfo.version },\n { instructions: getSdkServerInstructions(sdkServer) }\n );\n\n const authInfo = toAdcpAuthInfo(requestContext.authInfo);\n const toolVisibility = new Map<string, boolean>();\n for (const tool of toolDefinitions) {\n const visible = await isRegisteredToolVisible(agentServer, { toolName: tool.name, authInfo });\n toolVisibility.set(tool.name, visible);\n if (!visible) continue;\n const config = {\n ...(tool.title !== undefined && { title: tool.title }),\n ...(tool.description !== undefined && { description: tool.description }),\n ...(tool.outputSchema !== undefined && {\n outputSchema: tool.outputSchema as StandardSchemaWithJSON,\n }),\n ...(tool.annotations !== undefined && { annotations: tool.annotations as ToolAnnotations }),\n ...(tool._meta !== undefined && { _meta: tool._meta }),\n };\n const invoke = (args: Record<string, unknown>, ctx: ServerContext) =>\n agentServer.invoke({\n toolName: tool.name,\n args,\n authInfo: toAdcpAuthInfo(ctx.http?.authInfo),\n signal: ctx.mcpReq.signal,\n });\n\n if (tool.inputSchema !== undefined) {\n modern.registerTool(\n tool.name,\n { ...config, inputSchema: tool.inputSchema as StandardSchemaWithJSON },\n async (args, ctx) => invoke((args ?? {}) as Record<string, unknown>, ctx)\n );\n } else {\n modern.registerTool(tool.name, config, async ctx => invoke({}, ctx));\n }\n }\n\n // `createMcpHandler` reconstructs the MCP v2 server for every request,\n // so resources must be registered inside the factory rather than once\n // when the opaque AdCP server is created.\n for (const resource of listMcpAppResources(agentServer)) {\n const linkedTools = toolDefinitions.filter(tool => linkedMcpAppResourceUri(tool) === resource.uri);\n if (linkedTools.length > 0 && !linkedTools.some(tool => toolVisibility.get(tool.name) === true)) continue;\n modern.registerResource(\n resource.name,\n resource.uri,\n mcpAppResourceMetadata(resource) as ResourceMetadata,\n async (uri, ctx) =>\n readMcpAppResource(resource, uri, {\n signal: ctx.mcpReq.signal,\n })\n );\n }\n\n return modern;\n },\n {\n legacy: 'reject',\n onerror(error) {\n console.error('[adcp/serve] modern MCP error:', error);\n },\n }\n );\n\n return {\n handle: toNodeHandler(handler, {\n onerror(error) {\n console.error('[adcp/serve] modern MCP Node adapter error:', error);\n },\n }),\n async isLegacyRequest(req, parsedBody) {\n const request = await toWebRequest(req, parsedBody);\n return isLegacyRequest(request, parsedBody);\n },\n close: () => handler.close(),\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "12.0.2";
4
+ export declare const LIBRARY_VERSION = "12.0.3";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "12.0.2";
36
+ readonly library: "12.0.3";
37
37
  readonly adcp: "3.1.2";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.1.0", "3.1", "3.1.1", "3.1.2"];
39
- readonly generatedAt: "2026-07-18T19:40:02.202Z";
39
+ readonly generatedAt: "2026-07-19T01:26:47.776Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "12.0.2";
4
+ export declare const LIBRARY_VERSION = "12.0.3";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "12.0.2";
36
+ readonly library: "12.0.3";
37
37
  readonly adcp: "3.1.2";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.1.0", "3.1", "3.1.1", "3.1.2"];
39
- readonly generatedAt: "2026-07-18T19:40:02.202Z";
39
+ readonly generatedAt: "2026-07-19T01:26:47.776Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -31,7 +31,7 @@ __export(version_exports, {
31
31
  toReleasePrecisionVersion: () => toReleasePrecisionVersion
32
32
  });
33
33
  module.exports = __toCommonJS(version_exports);
34
- const LIBRARY_VERSION = "12.0.2";
34
+ const LIBRARY_VERSION = "12.0.3";
35
35
  const ADCP_VERSION = "3.1.2";
36
36
  const ADCP_MAJOR_VERSION = 3;
37
37
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -63,10 +63,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
63
63
  "3.1.2"
64
64
  ];
65
65
  const VERSION_INFO = {
66
- library: "12.0.2",
66
+ library: "12.0.3",
67
67
  adcp: "3.1.2",
68
68
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
69
- generatedAt: "2026-07-18T19:40:02.202Z"
69
+ generatedAt: "2026-07-19T01:26:47.776Z"
70
70
  };
71
71
  function getAdcpVersion() {
72
72
  return ADCP_VERSION;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.2';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.2',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-18T19:40:02.202Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.3';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.3',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-19T01:26:47.776Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "12.0.2";
1
+ const LIBRARY_VERSION = "12.0.3";
2
2
  const ADCP_VERSION = "3.1.2";
3
3
  const ADCP_MAJOR_VERSION = 3;
4
4
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -30,10 +30,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
30
30
  "3.1.2"
31
31
  ];
32
32
  const VERSION_INFO = {
33
- library: "12.0.2",
33
+ library: "12.0.3",
34
34
  adcp: "3.1.2",
35
35
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
36
- generatedAt: "2026-07-18T19:40:02.202Z"
36
+ generatedAt: "2026-07-19T01:26:47.776Z"
37
37
  };
38
38
  function getAdcpVersion() {
39
39
  return ADCP_VERSION;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.2';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.2',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-18T19:40:02.202Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":"AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.3';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.3',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-19T01:26:47.776Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":"AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
@@ -562,6 +562,76 @@ createAdcpServerFromPlatform(platform, {
562
562
 
563
563
  See [SIGNING-GUIDE.md](./SIGNING-GUIDE.md) for the full walkthrough: key generation, JWKS publication, brand.json, conformance testing, and KMS-backed production deployment.
564
564
 
565
+ ### Portable MCP Apps for custom tools
566
+
567
+ Use `resources` with custom-tool `_meta.ui` to attach one host-neutral MCP
568
+ App to a tool. The framework registers the `ui://` resource on both legacy
569
+ MCP connections and every modern per-request server reconstruction; the same
570
+ configuration therefore works in compliant Claude, ChatGPT, and future hosts.
571
+
572
+ ```typescript
573
+ import {
574
+ createAdcpServerFromPlatform,
575
+ MCP_APP_RESOURCE_MIME_TYPE,
576
+ } from '@adcp/sdk/server';
577
+
578
+ const server = createAdcpServerFromPlatform(platform, {
579
+ name: 'My Publisher',
580
+ version: '1.0.0',
581
+ resources: [
582
+ {
583
+ name: 'creative_upload',
584
+ uri: 'ui://creative/upload',
585
+ mimeType: MCP_APP_RESOURCE_MIME_TYPE,
586
+ _meta: {
587
+ ui: {
588
+ csp: {
589
+ connectDomains: ['https://uploads.example.com'],
590
+ resourceDomains: ['https://assets.example.com'],
591
+ },
592
+ prefersBorder: true,
593
+ },
594
+ },
595
+ handler: async () => renderUploadApp(),
596
+ },
597
+ ],
598
+ customTools: {
599
+ upload_creative_asset: {
600
+ description: 'Open the creative upload flow.',
601
+ _meta: { ui: { resourceUri: 'ui://creative/upload' } },
602
+ handler: async () => ({
603
+ // Required text-only fallback for hosts without MCP Apps support.
604
+ content: [{ type: 'text', text: 'Upload a creative asset.' }],
605
+ }),
606
+ },
607
+ prepare_creative_upload: {
608
+ _meta: { ui: { visibility: ['app'] } },
609
+ handler: prepareCreativeUpload,
610
+ },
611
+ finalize_creative_upload: {
612
+ _meta: { ui: { visibility: ['app'] } },
613
+ handler: finalizeCreativeUpload,
614
+ },
615
+ },
616
+ });
617
+ ```
618
+
619
+ MCP App resources always use a `ui://` URI and
620
+ `text/html;profile=mcp-app`; the public types and construction-time checks
621
+ reject other shapes. The resource `_meta.ui` object carries CSP domains,
622
+ permissions, a dedicated host domain, and border preference, and is emitted
623
+ consistently by both `resources/list` and `resources/read`.
624
+
625
+ `ui.visibility` is host routing metadata, not an authorization boundary.
626
+ App-only handlers must still authenticate and authorize every request, and
627
+ tools should always return meaningful text content so clients that do not
628
+ negotiate `io.modelcontextprotocol/ui` degrade gracefully. A startup warning
629
+ identifies any tool `resourceUri` that does not match a configured resource.
630
+ Resource handlers intentionally receive no authentication material: the HTML
631
+ bundle must be principal-independent and cache-safe. Fetch tenant data or mint
632
+ short-lived upload URLs through authenticated app-only tools after the app has
633
+ loaded.
634
+
565
635
  ### createTaskCapableServer (Low-Level)
566
636
 
567
637
  For advanced cases where you need direct control over MCP tool registration, schema wiring, and response formatting. `createAdcpServerFromPlatform` calls into this internally.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "12.0.2",
3
+ "version": "12.0.3",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",