@apollo/client-ai-apps 0.5.3 → 0.6.0

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 (71) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/config/defineConfig.d.ts +1 -0
  3. package/dist/config/defineConfig.d.ts.map +1 -1
  4. package/dist/config/schema.d.ts +1 -0
  5. package/dist/config/schema.d.ts.map +1 -1
  6. package/dist/config/schema.js +1 -0
  7. package/dist/config/schema.js.map +1 -1
  8. package/dist/mcp/core/McpAppManager.d.ts +2 -1
  9. package/dist/mcp/core/McpAppManager.d.ts.map +1 -1
  10. package/dist/mcp/core/McpAppManager.js +11 -1
  11. package/dist/mcp/core/McpAppManager.js.map +1 -1
  12. package/dist/mcp/react/hooks/useHostContext.d.ts +2 -0
  13. package/dist/mcp/react/hooks/useHostContext.d.ts.map +1 -0
  14. package/dist/mcp/react/hooks/useHostContext.js +7 -0
  15. package/dist/mcp/react/hooks/useHostContext.js.map +1 -0
  16. package/dist/mcp/react/index.d.ts +1 -0
  17. package/dist/mcp/react/index.d.ts.map +1 -1
  18. package/dist/mcp/react/index.js +1 -0
  19. package/dist/mcp/react/index.js.map +1 -1
  20. package/dist/openai/core/McpAppManager.d.ts +2 -1
  21. package/dist/openai/core/McpAppManager.d.ts.map +1 -1
  22. package/dist/openai/core/McpAppManager.js +11 -1
  23. package/dist/openai/core/McpAppManager.js.map +1 -1
  24. package/dist/openai/react/hooks/useHostContext.d.ts +2 -0
  25. package/dist/openai/react/hooks/useHostContext.d.ts.map +1 -0
  26. package/dist/openai/react/hooks/useHostContext.js +7 -0
  27. package/dist/openai/react/hooks/useHostContext.js.map +1 -0
  28. package/dist/openai/react/index.d.ts +1 -0
  29. package/dist/openai/react/index.d.ts.map +1 -1
  30. package/dist/openai/react/index.js +1 -0
  31. package/dist/openai/react/index.js.map +1 -1
  32. package/dist/react/index.d.ts +1 -0
  33. package/dist/react/index.d.ts.map +1 -1
  34. package/dist/react/index.js +1 -0
  35. package/dist/react/index.js.map +1 -1
  36. package/dist/react/index.mcp.d.ts +1 -1
  37. package/dist/react/index.mcp.d.ts.map +1 -1
  38. package/dist/react/index.mcp.js +1 -1
  39. package/dist/react/index.mcp.js.map +1 -1
  40. package/dist/react/index.openai.d.ts +1 -1
  41. package/dist/react/index.openai.d.ts.map +1 -1
  42. package/dist/react/index.openai.js +1 -1
  43. package/dist/react/index.openai.js.map +1 -1
  44. package/dist/types/application-manifest.d.ts +1 -0
  45. package/dist/types/application-manifest.d.ts.map +1 -1
  46. package/dist/types/application-manifest.js.map +1 -1
  47. package/dist/vite/__tests__/utilities/build.d.ts.map +1 -1
  48. package/dist/vite/__tests__/utilities/build.js +0 -1
  49. package/dist/vite/__tests__/utilities/build.js.map +1 -1
  50. package/dist/vite/apolloClientAiApps.d.ts +1 -0
  51. package/dist/vite/apolloClientAiApps.d.ts.map +1 -1
  52. package/dist/vite/apolloClientAiApps.js +63 -46
  53. package/dist/vite/apolloClientAiApps.js.map +1 -1
  54. package/package.json +1 -4
  55. package/src/config/schema.ts +1 -0
  56. package/src/mcp/core/McpAppManager.ts +23 -1
  57. package/src/mcp/react/hooks/__tests__/useHostContext.test.tsx +95 -0
  58. package/src/mcp/react/hooks/useHostContext.ts +14 -0
  59. package/src/mcp/react/index.ts +1 -0
  60. package/src/openai/core/McpAppManager.ts +22 -1
  61. package/src/openai/react/hooks/useHostContext.ts +14 -0
  62. package/src/openai/react/index.ts +1 -0
  63. package/src/react/index.mcp.ts +1 -0
  64. package/src/react/index.openai.ts +1 -0
  65. package/src/react/index.ts +3 -0
  66. package/src/testing/internal/mcp/mockMcpHost.ts +12 -0
  67. package/src/testing/internal/utilities/mockApplicationManifest.ts +1 -0
  68. package/src/types/application-manifest.ts +1 -0
  69. package/src/vite/__tests__/apolloClientAiApps.test.ts +460 -61
  70. package/src/vite/__tests__/utilities/build.ts +0 -1
  71. package/src/vite/apolloClientAiApps.ts +100 -57
@@ -9,12 +9,13 @@ import { glob } from "glob";
9
9
  import { print } from "@apollo/client/utilities";
10
10
  import { removeDirectivesFromDocument } from "@apollo/client/utilities/internal";
11
11
  import { of } from "rxjs";
12
- import { Kind, parse } from "graphql";
12
+ import { Kind, OperationTypeNode, parse } from "graphql";
13
13
  import { getArgumentValue, getDirectiveArgument, getTypeName, maybeGetArgumentValue, } from "./utilities/graphql.js";
14
14
  import { invariant } from "../utilities/invariant.js";
15
15
  import { explorer } from "./utilities/config.js";
16
16
  import { ApolloClientAiAppsConfigSchema } from "../config/schema.js";
17
17
  import { z } from "zod";
18
+ import { createFragmentRegistry } from "@apollo/client/cache";
18
19
  const root = process.cwd();
19
20
  const VALID_TARGETS = ["openai", "mcp"];
20
21
  function isValidTarget(target) {
@@ -29,14 +30,15 @@ export function devTarget(target) {
29
30
  }
30
31
  export function apolloClientAiApps(options) {
31
32
  const targets = Array.from(new Set(options.targets));
32
- const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;
33
+ const { devTarget = targets.length === 1 ? targets[0] : undefined, appsOutDir, } = options;
33
34
  const cache = new Map();
34
- let packageJson;
35
35
  let config;
36
+ const fragments = createFragmentRegistry();
36
37
  invariant(Array.isArray(targets) && targets.length > 0, "The `targets` option must be a non-empty array");
37
38
  invariant(targets.every(isValidTarget), `All targets must be one of: ${VALID_TARGETS.join(", ")}`);
39
+ invariant(path.basename(path.normalize(appsOutDir)) === "apps", "`appsOutDir` must end with `apps` as the final path segment (e.g. `path/to/apps`).");
38
40
  const client = new ApolloClient({
39
- cache: new InMemoryCache(),
41
+ cache: new InMemoryCache({ fragments }),
40
42
  link: processQueryLink,
41
43
  });
42
44
  async function processFile(file) {
@@ -51,41 +53,43 @@ export function apolloClientAiApps(options) {
51
53
  { name: "graphql-tag", identifier: "gql" },
52
54
  { name: "@apollo/client", identifier: "gql" },
53
55
  ],
54
- }).map((source) => ({
55
- node: parse(source.body),
56
- file,
57
- location: source.locationOffset,
58
- }));
59
- const operations = [];
60
- for (const source of sources) {
61
- const type = source.node.definitions.find((d) => d.kind === "OperationDefinition").operation;
62
- let result;
63
- if (type === "query") {
64
- result = await client.query({
65
- query: source.node,
66
- fetchPolicy: "no-cache",
67
- });
68
- }
69
- else if (type === "mutation") {
70
- result = await client.mutate({
71
- mutation: source.node,
72
- fetchPolicy: "no-cache",
73
- });
74
- }
75
- else {
76
- throw new Error("Found an unsupported operation type. Only Query and Mutation are supported.");
77
- }
78
- operations.push(result.data);
79
- }
56
+ }).map((source) => parse(source.body));
57
+ fragments.register(...sources);
80
58
  cache.set(file, {
81
59
  file: file,
82
60
  hash: fileHash,
83
- operations,
61
+ sources,
84
62
  });
85
63
  }
86
64
  async function generateManifest(environment) {
87
65
  const appsConfig = await getAppsConfig();
88
- const operations = Array.from(cache.values()).flatMap((entry) => entry.operations);
66
+ const sources = Array.from(cache.values()).flatMap((entry) => entry.sources);
67
+ const operations = [];
68
+ for (const source of sources) {
69
+ const operationDef = source.definitions.find((d) => d.kind === Kind.OPERATION_DEFINITION);
70
+ if (!operationDef)
71
+ continue;
72
+ switch (operationDef.operation) {
73
+ case OperationTypeNode.QUERY: {
74
+ const result = await client.query({
75
+ query: source,
76
+ fetchPolicy: "no-cache",
77
+ });
78
+ operations.push(result.data);
79
+ break;
80
+ }
81
+ case OperationTypeNode.MUTATION: {
82
+ const result = await client.mutate({
83
+ mutation: source,
84
+ fetchPolicy: "no-cache",
85
+ });
86
+ operations.push(result.data);
87
+ break;
88
+ }
89
+ default:
90
+ throw new Error(`Found unsupported operation type '${operationDef.operation}'. Only queries and mutations are supported.`);
91
+ }
92
+ }
89
93
  invariant(operations.filter((o) => o.prefetch).length <= 1, "Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.");
90
94
  function getBuildResourceForTarget(target) {
91
95
  const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);
@@ -107,6 +111,9 @@ export function apolloClientAiApps(options) {
107
111
  else {
108
112
  resource = Object.fromEntries(targets.map((target) => [target, getBuildResourceForTarget(target)]));
109
113
  }
114
+ const packageJson = readPackageJson();
115
+ const appName = appsConfig.name ?? packageJson.name;
116
+ invariant(appName, "Error generating application manifest. Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`.");
110
117
  const manifest = {
111
118
  format: "apollo-ai-app-manifest",
112
119
  version: "1",
@@ -114,9 +121,10 @@ export function apolloClientAiApps(options) {
114
121
  name: appsConfig.name ?? packageJson.name,
115
122
  description: appsConfig.description ?? packageJson.description,
116
123
  hash: createHash("sha256").update(Date.now().toString()).digest("hex"),
117
- operations: Array.from(cache.values()).flatMap((entry) => entry.operations),
124
+ operations,
118
125
  resource,
119
126
  csp: {
127
+ baseUriDomains: appsConfig.csp?.baseUriDomains ?? [],
120
128
  connectDomains: appsConfig.csp?.connectDomains ?? [],
121
129
  frameDomains: appsConfig.csp?.frameDomains ?? [],
122
130
  redirectDomains: appsConfig.csp?.redirectDomains ?? [],
@@ -129,13 +137,7 @@ export function apolloClientAiApps(options) {
129
137
  if (isNonEmptyObject(appsConfig.labels)) {
130
138
  manifest.labels = appsConfig.labels;
131
139
  }
132
- // We create mcp and openai environments in order to write to
133
- // subdirectories, but we want the manifest to be in the root outDir. If we
134
- // are running in a different environment, we'll put it in the configured
135
- // outDir directly instead.
136
- const outDir = environment?.name === "mcp" || environment?.name === "openai" ?
137
- path.resolve(config.build.outDir, "../")
138
- : config.build.outDir;
140
+ const outDir = path.join(appsOutDir, appName);
139
141
  // Always write to build directory so the MCP server picks it up
140
142
  const dest = path.resolve(root, outDir, ".application-manifest.json");
141
143
  fs.mkdirSync(path.dirname(dest), { recursive: true });
@@ -146,8 +148,6 @@ export function apolloClientAiApps(options) {
146
148
  return {
147
149
  name: "@apollo/client-ai-apps/vite",
148
150
  async buildStart() {
149
- // Read package.json on start
150
- packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
151
151
  // Scan all files on startup
152
152
  const files = await glob("./src/**/*.{ts,tsx,js,jsx}", { fs });
153
153
  for (const file of files) {
@@ -162,19 +162,22 @@ export function apolloClientAiApps(options) {
162
162
  configResolved(resolvedConfig) {
163
163
  config = resolvedConfig;
164
164
  },
165
- configEnvironment(name, { build }) {
165
+ async configEnvironment(name, { build }) {
166
166
  if (!targets.includes(name))
167
167
  return;
168
+ const appsConfig = await getAppsConfig();
169
+ const appName = appsConfig.name ?? readPackageJson().name;
170
+ invariant(appName, "Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`.");
168
171
  return {
169
172
  build: {
170
- outDir: path.join(build?.outDir ?? "dist", name),
173
+ outDir: path.join(appsOutDir, appName, name),
171
174
  },
172
175
  };
173
176
  },
174
177
  configureServer(server) {
175
178
  server.watcher.on("change", async (file) => {
176
179
  if (file.endsWith("package.json")) {
177
- packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
180
+ readPackageJson.resetCache();
178
181
  await generateManifest();
179
182
  }
180
183
  else if (file.match(/\.?apollo-client-ai-apps\.config\.\w+$/)) {
@@ -187,7 +190,11 @@ export function apolloClientAiApps(options) {
187
190
  }
188
191
  });
189
192
  },
190
- config(_, { command }) {
193
+ config(userConfig, { command }) {
194
+ if (userConfig.build?.outDir) {
195
+ console.warn("[@apollo/client-ai-apps/vite] `build.outDir` is set in your Vite config but will be " +
196
+ "ignored. Use `appsOutDir` in the plugin options to control the output location.");
197
+ }
191
198
  if (command === "serve") {
192
199
  invariant(isValidTarget(devTarget) || targets.length === 1, "`devTarget` must be set for development when using multiple targets.");
193
200
  const target = devTarget ?? targets[0];
@@ -335,6 +342,16 @@ function getResourceFromConfig(appsConfig, mode, target) {
335
342
  const config = appsConfig.entry[mode];
336
343
  return typeof config === "string" ? config : config[target];
337
344
  }
345
+ function readPackageJson() {
346
+ if (readPackageJson.cache) {
347
+ return readPackageJson.cache;
348
+ }
349
+ return (readPackageJson.cache = JSON.parse(fs.readFileSync("package.json", "utf-8")));
350
+ }
351
+ readPackageJson.cache = undefined;
352
+ readPackageJson.resetCache = () => {
353
+ readPackageJson.cache = undefined;
354
+ };
338
355
  const ToolDirectiveSchema = z.strictObject({
339
356
  name: z.stringFormat("toolName", (value) => value.indexOf(" ") === -1, {
340
357
  error: (iss) => `Tool with name "${iss.input}" must not contain spaces`,
@@ -1 +1 @@
1
- {"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, parse, type OperationDefinitionNode } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n operations: ManifestOperation[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;\n const cache = new Map<string, FileCache>();\n\n let packageJson!: Record<string, any>;\n let config!: ResolvedConfig;\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache(),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => ({\n node: parse(source.body),\n file,\n location: source.locationOffset,\n }));\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const type = (\n source.node.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n ) as OperationDefinitionNode\n ).operation;\n\n let result;\n if (type === \"query\") {\n result = await client.query({\n query: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else if (type === \"mutation\") {\n result = await client.mutate({\n mutation: source.node,\n fetchPolicy: \"no-cache\",\n });\n } else {\n throw new Error(\n \"Found an unsupported operation type. Only Query and Mutation are supported.\"\n );\n }\n operations.push(result.data as ManifestOperation);\n }\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n operations,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const operations = Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n );\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations: Array.from(cache.values()).flatMap(\n (entry) => entry.operations\n ),\n resource,\n csp: {\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n // We create mcp and openai environments in order to write to\n // subdirectories, but we want the manifest to be in the root outDir. If we\n // are running in a different environment, we'll put it in the configured\n // outDir directly instead.\n const outDir =\n environment?.name === \"mcp\" || environment?.name === \"openai\" ?\n path.resolve(config.build.outDir, \"../\")\n : config.build.outDir;\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Read package.json on start\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n return {\n build: {\n outDir: path.join(build?.outDir ?? \"dist\", name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n packageJson = JSON.parse(fs.readFileSync(\"package.json\", \"utf-8\"));\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(_, { command }) {\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig() {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
1
+ {"version":3,"file":"apolloClientAiApps.js","sourceRoot":"","sources":["../../src/vite/apolloClientAiApps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defaultClientConditions,\n type Environment,\n type Plugin,\n type ResolvedConfig,\n} from \"vite\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { ApolloClient, ApolloLink, type DocumentNode } from \"@apollo/client\";\nimport { InMemoryCache } from \"@apollo/client\";\nimport { gqlPluckFromCodeStringSync } from \"@graphql-tools/graphql-tag-pluck\";\nimport { glob } from \"glob\";\nimport { print } from \"@apollo/client/utilities\";\nimport { removeDirectivesFromDocument } from \"@apollo/client/utilities/internal\";\nimport { of } from \"rxjs\";\nimport { Kind, OperationTypeNode, parse } from \"graphql\";\nimport {\n getArgumentValue,\n getDirectiveArgument,\n getTypeName,\n maybeGetArgumentValue,\n} from \"./utilities/graphql.js\";\nimport type {\n ApplicationManifest,\n ManifestOperation,\n} from \"../types/application-manifest\";\nimport { invariant } from \"../utilities/invariant.js\";\nimport { explorer } from \"./utilities/config.js\";\nimport type { ApolloClientAiAppsConfig } from \"../config/index.js\";\nimport { ApolloClientAiAppsConfigSchema } from \"../config/schema.js\";\nimport { z } from \"zod\";\nimport { createFragmentRegistry } from \"@apollo/client/cache\";\n\nexport declare namespace apolloClientAiApps {\n export type Target = ApolloClientAiAppsConfig.AppTarget;\n\n export interface Options {\n targets: Target[];\n devTarget?: Target | undefined;\n appsOutDir: string;\n }\n}\n\nconst root = process.cwd();\n\nconst VALID_TARGETS: apolloClientAiApps.Target[] = [\"openai\", \"mcp\"];\n\nfunction isValidTarget(target: unknown): target is apolloClientAiApps.Target {\n return VALID_TARGETS.includes(target as apolloClientAiApps.Target);\n}\n\nfunction buildExtensions(target: apolloClientAiApps.Target) {\n return [\".mjs\", \".js\", \".mts\", \".ts\", \".jsx\", \".tsx\", \".json\"].flatMap(\n (ext) => [`.${target}${ext}`, ext]\n );\n}\n\nexport function devTarget(target: string | undefined) {\n invariant(\n target === undefined || isValidTarget(target),\n `devTarget '${target}' is not a valid dev target. Must be one of ${VALID_TARGETS.join(\", \")}.`\n );\n\n return target;\n}\n\ninterface FileCache {\n file: string;\n hash: string;\n sources: DocumentNode[];\n}\n\nexport function apolloClientAiApps(\n options: apolloClientAiApps.Options\n): Plugin {\n const targets = Array.from(new Set(options.targets));\n const {\n devTarget = targets.length === 1 ? targets[0] : undefined,\n appsOutDir,\n } = options;\n const cache = new Map<string, FileCache>();\n\n let config!: ResolvedConfig;\n\n const fragments = createFragmentRegistry();\n\n invariant(\n Array.isArray(targets) && targets.length > 0,\n \"The `targets` option must be a non-empty array\"\n );\n\n invariant(\n targets.every(isValidTarget),\n `All targets must be one of: ${VALID_TARGETS.join(\", \")}`\n );\n\n invariant(\n path.basename(path.normalize(appsOutDir)) === \"apps\",\n \"`appsOutDir` must end with `apps` as the final path segment (e.g. `path/to/apps`).\"\n );\n\n const client = new ApolloClient({\n cache: new InMemoryCache({ fragments }),\n link: processQueryLink,\n });\n\n async function processFile(file: string) {\n const code = fs.readFileSync(file, \"utf-8\");\n\n if (!code.includes(\"gql\")) return;\n\n const fileHash = createHash(\"md5\").update(code).digest(\"hex\");\n if (cache.get(file)?.hash === fileHash) return;\n const sources = gqlPluckFromCodeStringSync(file, code, {\n modules: [\n { name: \"graphql-tag\", identifier: \"gql\" },\n { name: \"@apollo/client\", identifier: \"gql\" },\n ],\n }).map((source) => parse(source.body));\n\n fragments.register(...sources);\n\n cache.set(file, {\n file: file,\n hash: fileHash,\n sources,\n });\n }\n\n async function generateManifest(environment?: Environment) {\n const appsConfig = await getAppsConfig();\n const sources = Array.from(cache.values()).flatMap(\n (entry) => entry.sources\n );\n\n const operations: ManifestOperation[] = [];\n for (const source of sources) {\n const operationDef = source.definitions.find(\n (d) => d.kind === Kind.OPERATION_DEFINITION\n );\n\n if (!operationDef) continue;\n\n switch (operationDef.operation) {\n case OperationTypeNode.QUERY: {\n const result = await client.query<ManifestOperation>({\n query: source,\n fetchPolicy: \"no-cache\",\n });\n\n operations.push(result.data!);\n break;\n }\n case OperationTypeNode.MUTATION: {\n const result = await client.mutate<ManifestOperation>({\n mutation: source,\n fetchPolicy: \"no-cache\",\n });\n\n operations.push(result.data!);\n break;\n }\n default:\n throw new Error(\n `Found unsupported operation type '${operationDef.operation}'. Only queries and mutations are supported.`\n );\n }\n }\n\n invariant(\n operations.filter((o) => o.prefetch).length <= 1,\n \"Found multiple operations marked as `@prefetch`. You can only mark 1 operation with `@prefetch`.\"\n );\n\n function getBuildResourceForTarget(target: apolloClientAiApps.Target) {\n const entryPoint = getResourceFromConfig(appsConfig, config.mode, target);\n\n if (entryPoint) {\n return entryPoint;\n }\n\n if (config.mode === \"production\") {\n return `${target}/index.html`;\n }\n\n throw new Error(\n `No entry point found for mode \"${config.mode}\". Entry points other than \"development\" and \"production\" must be defined in package.json file.`\n );\n }\n\n let resource: ApplicationManifest[\"resource\"];\n if (config.command === \"serve\") {\n // Dev mode: resource is a string (dev server URL)\n resource =\n getResourceFromConfig(appsConfig, config.mode, devTarget!) ??\n `http${config.server.https ? \"s\" : \"\"}://${config.server.host ?? \"localhost\"}:${config.server.port}`;\n } else {\n resource = Object.fromEntries(\n targets.map((target) => [target, getBuildResourceForTarget(target)])\n ) as { mcp?: string; openai?: string };\n }\n\n const packageJson = readPackageJson();\n const appName = appsConfig.name ?? packageJson.name;\n\n invariant(\n appName,\n \"Error generating application manifest. Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`.\"\n );\n\n const manifest: ApplicationManifest = {\n format: \"apollo-ai-app-manifest\",\n version: \"1\",\n appVersion: appsConfig.version ?? packageJson.version,\n name: appsConfig.name ?? packageJson.name,\n description: appsConfig.description ?? packageJson.description,\n hash: createHash(\"sha256\").update(Date.now().toString()).digest(\"hex\"),\n operations,\n resource,\n csp: {\n baseUriDomains: appsConfig.csp?.baseUriDomains ?? [],\n connectDomains: appsConfig.csp?.connectDomains ?? [],\n frameDomains: appsConfig.csp?.frameDomains ?? [],\n redirectDomains: appsConfig.csp?.redirectDomains ?? [],\n resourceDomains: appsConfig.csp?.resourceDomains ?? [],\n },\n };\n\n if (isNonEmptyObject(appsConfig.widgetSettings)) {\n manifest.widgetSettings = appsConfig.widgetSettings;\n }\n\n if (isNonEmptyObject(appsConfig.labels)) {\n manifest.labels = appsConfig.labels;\n }\n\n const outDir = path.join(appsOutDir, appName);\n\n // Always write to build directory so the MCP server picks it up\n const dest = path.resolve(root, outDir, \".application-manifest.json\");\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.writeFileSync(dest, JSON.stringify(manifest));\n\n // Always write to the dev location so that the app can bundle the manifest content\n fs.writeFileSync(\".application-manifest.json\", JSON.stringify(manifest));\n }\n\n return {\n name: \"@apollo/client-ai-apps/vite\",\n async buildStart() {\n // Scan all files on startup\n const files = await glob(\"./src/**/*.{ts,tsx,js,jsx}\", { fs });\n\n for (const file of files) {\n const fullPath = path.resolve(root, file);\n await processFile(fullPath);\n }\n\n // We don't want to do this here on builds cause it just gets overwritten anyways. We'll call it on writeBundle instead.\n if (config.command === \"serve\") {\n await generateManifest(this.environment);\n }\n },\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async configEnvironment(name, { build }) {\n if (!targets.includes(name as any)) return;\n\n const appsConfig = await getAppsConfig();\n const appName = appsConfig.name ?? readPackageJson().name;\n\n invariant(\n appName,\n \"Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`.\"\n );\n\n return {\n build: {\n outDir: path.join(appsOutDir, appName, name),\n },\n };\n },\n configureServer(server) {\n server.watcher.on(\"change\", async (file) => {\n if (file.endsWith(\"package.json\")) {\n readPackageJson.resetCache();\n await generateManifest();\n } else if (file.match(/\\.?apollo-client-ai-apps\\.config\\.\\w+$/)) {\n explorer.clearCaches();\n await generateManifest();\n } else if (file.match(/\\.(jsx?|tsx?)$/)) {\n await processFile(file);\n await generateManifest();\n }\n });\n },\n\n config(userConfig, { command }) {\n if (userConfig.build?.outDir) {\n console.warn(\n \"[@apollo/client-ai-apps/vite] `build.outDir` is set in your Vite config but will be \" +\n \"ignored. Use `appsOutDir` in the plugin options to control the output location.\"\n );\n }\n\n if (command === \"serve\") {\n invariant(\n isValidTarget(devTarget) || targets.length === 1,\n \"`devTarget` must be set for development when using multiple targets.\"\n );\n\n const target = devTarget ?? targets[0];\n\n return {\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n };\n }\n\n return {\n environments: Object.fromEntries(\n targets.map((target) => [\n target,\n {\n consumer: \"client\",\n webCompatible: true,\n resolve: {\n extensions: buildExtensions(target),\n conditions: [target, ...defaultClientConditions],\n },\n },\n ])\n ),\n builder: {\n buildApp: async (builder) => {\n await Promise.all(\n targets.map((target) =>\n builder.build(builder.environments[target])\n )\n );\n },\n },\n };\n },\n transformIndexHtml(html, ctx) {\n if (!ctx.server) return html;\n\n let baseUrl = (\n ctx.server.config?.server?.origin ??\n ctx.server.resolvedUrls?.local[0] ??\n \"\"\n ).replace(/\\/$/, \"\");\n baseUrl = baseUrl.replace(/\\/$/, \"\");\n\n return (\n html\n // import \"/@vite/...\" or \"/@react-refresh\"\n .replace(/(from\\s+[\"'])\\/([^\"']+)/g, `$1${baseUrl}/$2`)\n // src=\"/src/...\"\n .replace(/(src=[\"'])\\/([^\"']+)/gi, `$1${baseUrl}/$2`)\n );\n },\n async writeBundle() {\n await generateManifest(this.environment);\n },\n } satisfies Plugin;\n}\n\nconst processQueryLink = new ApolloLink((operation) => {\n const body = print(\n removeManifestDirectives(sortTopLevelDefinitions(operation.query))\n );\n const name = operation.operationName;\n const definition = operation.query.definitions.find(\n (d) => d.kind === \"OperationDefinition\"\n );\n\n // Use `operation.query` so that the error reflects the end-user defined\n // document, not our sorted one\n invariant(\n definition,\n `Document does not contain an operation:\\n${print(operation.query)}`\n );\n\n const { directives, operation: type } = definition;\n\n const variables = definition.variableDefinitions?.reduce(\n (obj, varDef) => ({\n ...obj,\n [varDef.variable.name.value]: getTypeName(varDef.type),\n }),\n {}\n );\n\n const prefetch = directives?.some((d) => d.name.value === \"prefetch\");\n const id = createHash(\"sha256\").update(body).digest(\"hex\");\n // TODO: For now, you can only have 1 operation marked as prefetch. In the future, we'll likely support more than 1, and the \"prefetchId\" will be defined on the `@prefetch` itself as an argument\n const prefetchID = prefetch ? \"__anonymous\" : undefined;\n\n const tools = directives\n ?.filter((d) => d.name.value === \"tool\")\n .map((directive) => {\n const result = ToolDirectiveSchema.safeParse({\n name: getArgumentValue(\n getDirectiveArgument(\"name\", directive, { required: true }),\n Kind.STRING\n ),\n description: getArgumentValue(\n getDirectiveArgument(\"description\", directive, { required: true }),\n Kind.STRING\n ),\n extraInputs: maybeGetArgumentValue(\n getDirectiveArgument(\"extraInputs\", directive),\n Kind.LIST\n ),\n labels: maybeGetArgumentValue(\n getDirectiveArgument(\"labels\", directive),\n Kind.OBJECT\n ),\n });\n\n if (result.error) {\n throw z.prettifyError(result.error);\n }\n\n return result.data;\n });\n\n // TODO: Make this object satisfy the `ManifestOperation` type. Currently\n // it errors because we need more validation on a few of these fields\n return of({\n data: { id, name, type, body, variables, prefetch, prefetchID, tools },\n });\n});\n\nfunction removeManifestDirectives(doc: DocumentNode) {\n return removeDirectivesFromDocument(\n [{ name: \"prefetch\" }, { name: \"tool\" }],\n doc\n )!;\n}\n\n// Sort the definitions in this document so that operations come before fragments,\n// and so that each kind of definition is sorted by name.\nexport function sortTopLevelDefinitions(query: DocumentNode): DocumentNode {\n const definitions = [...query.definitions];\n // We want to avoid unnecessary dependencies, so write out a comparison\n // function instead of using _.orderBy.\n definitions.sort((a, b) => {\n // This is a reverse sort by kind, so that OperationDefinition precedes FragmentDefinition.\n if (a.kind > b.kind) {\n return -1;\n }\n if (a.kind < b.kind) {\n return 1;\n }\n\n // Extract the name from each definition. Jump through some hoops because\n // non-executable definitions don't have to have names (even though any\n // DocumentNode actually passed here should only have executable\n // definitions).\n const aName =\n a.kind === \"OperationDefinition\" || a.kind === \"FragmentDefinition\" ?\n (a.name?.value ?? \"\")\n : \"\";\n const bName =\n b.kind === \"OperationDefinition\" || b.kind === \"FragmentDefinition\" ?\n (b.name?.value ?? \"\")\n : \"\";\n\n // Sort by name ascending.\n if (aName < bName) {\n return -1;\n }\n if (aName > bName) {\n return 1;\n }\n\n // Assuming that the document is \"valid\", no operation or fragment name can appear\n // more than once, so we don't need to differentiate further to have a deterministic\n // sort.\n return 0;\n });\n return {\n ...query,\n definitions,\n };\n}\n\nfunction isNonEmptyObject<T extends object>(\n obj: T | null | undefined\n): obj is T {\n return !!obj && Object.keys(obj).length > 0;\n}\n\nasync function getAppsConfig() {\n const result = await explorer.search();\n const config = (result?.config ??\n {}) as Partial<ApolloClientAiAppsConfig.Config>;\n\n const parsed = ApolloClientAiAppsConfigSchema.safeParse(config);\n\n if (parsed.error) {\n throw z.prettifyError(parsed.error);\n }\n\n return parsed.data;\n}\n\nfunction getResourceFromConfig(\n appsConfig: z.infer<typeof ApolloClientAiAppsConfigSchema>,\n mode: string,\n target: apolloClientAiApps.Target\n) {\n if (!appsConfig.entry || !appsConfig.entry[mode]) {\n return;\n }\n\n const config = appsConfig.entry[mode];\n\n return typeof config === \"string\" ? config : config[target];\n}\n\nfunction readPackageJson(): Record<string, any> {\n if (readPackageJson.cache) {\n return readPackageJson.cache;\n }\n\n return (readPackageJson.cache = JSON.parse(\n fs.readFileSync(\"package.json\", \"utf-8\")\n ));\n}\n\nreadPackageJson.cache = undefined as Record<string, any> | undefined;\nreadPackageJson.resetCache = () => {\n readPackageJson.cache = undefined;\n};\n\nconst ToolDirectiveSchema = z.strictObject({\n name: z.stringFormat(\"toolName\", (value) => value.indexOf(\" \") === -1, {\n error: (iss) => `Tool with name \"${iss.input}\" must not contain spaces`,\n }),\n description: z.string(),\n extraInputs: z.optional(\n z.array(\n z.strictObject({\n name: z.string(),\n description: z.string(),\n type: z.literal([\"string\", \"boolean\", \"number\"]),\n })\n )\n ),\n labels: ApolloClientAiAppsConfigSchema.shape.labels.optional(),\n});\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "@apollo/client-ai-apps",
4
- "version": "0.5.3",
4
+ "version": "0.6.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -145,9 +145,6 @@
145
145
  "react-dom": "^19.0.0"
146
146
  },
147
147
  "peerDependenciesMeta": {
148
- "@modelcontextprotocol/ext-apps": {
149
- "optional": true
150
- },
151
148
  "react": {
152
149
  "optional": true
153
150
  },
@@ -40,6 +40,7 @@ export const ApolloClientAiAppsConfigSchema = z.strictObject({
40
40
  frameDomains: z.array(z.string()).exactOptional(),
41
41
  redirectDomains: z.array(z.string()).exactOptional(),
42
42
  resourceDomains: z.array(z.string()).exactOptional(),
43
+ baseUriDomains: z.array(z.string()).exactOptional(),
43
44
  })
44
45
  ),
45
46
  widgetSettings: z.exactOptional(
@@ -1,4 +1,8 @@
1
- import { App, PostMessageTransport } from "@modelcontextprotocol/ext-apps";
1
+ import {
2
+ App,
3
+ PostMessageTransport,
4
+ type McpUiHostContextChangedNotification,
5
+ } from "@modelcontextprotocol/ext-apps";
2
6
  import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
7
  import type { ApplicationManifest } from "../../types/application-manifest";
4
8
  import type { FormattedExecutionResult } from "graphql";
@@ -19,6 +23,10 @@ export class McpAppManager {
19
23
  #toolMetadata: ApolloMcpServerApps.CallToolResult["_meta"] | undefined;
20
24
  #toolInput: Record<string, unknown> | undefined;
21
25
 
26
+ #hostContextCallbacks = new Set<
27
+ (params: McpUiHostContextChangedNotification["params"]) => void
28
+ >();
29
+
22
30
  constructor(manifest: ApplicationManifest) {
23
31
  this.app = new App({ name: manifest.name, version: manifest.appVersion });
24
32
  }
@@ -35,6 +43,16 @@ export class McpAppManager {
35
43
  return this.#toolInput;
36
44
  }
37
45
 
46
+ onHostContextChanged(
47
+ cb: (params: McpUiHostContextChangedNotification["params"]) => void
48
+ ) {
49
+ this.#hostContextCallbacks.add(cb);
50
+
51
+ return () => {
52
+ this.#hostContextCallbacks.delete(cb);
53
+ };
54
+ }
55
+
38
56
  connect = cacheAsync(async () => {
39
57
  let toolResult = promiseWithResolvers<ApolloMcpServerApps.CallToolResult>();
40
58
  let toolInput = promiseWithResolvers<Parameters<App["ontoolinput"]>[0]>();
@@ -49,6 +67,10 @@ export class McpAppManager {
49
67
  toolInput.resolve(params);
50
68
  };
51
69
 
70
+ this.app.onhostcontextchanged = (params) => {
71
+ this.#hostContextCallbacks.forEach((cb) => cb(params));
72
+ };
73
+
52
74
  await this.connectToHost();
53
75
 
54
76
  const { structuredContent, _meta } = await toolResult.promise;
@@ -0,0 +1,95 @@
1
+ import { expect, test } from "vitest";
2
+ import { InMemoryCache } from "@apollo/client";
3
+ import {
4
+ graphqlToolResult,
5
+ minimalHostContextWithToolName,
6
+ mockApplicationManifest,
7
+ mockMcpHost,
8
+ spyOnConsole,
9
+ } from "../../../../testing/internal/index.js";
10
+ import { ApolloClient } from "../../../core/ApolloClient.js";
11
+ import {
12
+ disableActEnvironment,
13
+ renderHookToSnapshotStream,
14
+ } from "@testing-library/react-render-stream";
15
+ import { useHostContext } from "../useHostContext.js";
16
+ import { ApolloProvider } from "../../../../react/ApolloProvider.js";
17
+
18
+ test("returns the host context from the host", async () => {
19
+ using _ = spyOnConsole("debug");
20
+ const client = new ApolloClient({
21
+ cache: new InMemoryCache(),
22
+ manifest: mockApplicationManifest(),
23
+ });
24
+
25
+ using host = await mockMcpHost({
26
+ hostContext: {
27
+ ...minimalHostContextWithToolName("GetProduct"),
28
+ theme: "light",
29
+ },
30
+ });
31
+ host.onCleanup(() => client.stop());
32
+
33
+ host.sendToolInput({ arguments: {} });
34
+ host.sendToolResult(graphqlToolResult({ data: { product: null } }));
35
+
36
+ using _disabledAct = disableActEnvironment();
37
+ const { takeSnapshot } = await renderHookToSnapshotStream(
38
+ () => useHostContext(),
39
+ {
40
+ wrapper: ({ children }) => (
41
+ <ApolloProvider client={client}>{children}</ApolloProvider>
42
+ ),
43
+ }
44
+ );
45
+
46
+ await expect(takeSnapshot()).resolves.toStrictEqual({
47
+ ...minimalHostContextWithToolName("GetProduct"),
48
+ theme: "light",
49
+ });
50
+
51
+ await expect(takeSnapshot).not.toRerender();
52
+ });
53
+
54
+ test("rerenders when the host context changes", async () => {
55
+ using _ = spyOnConsole("debug");
56
+ const client = new ApolloClient({
57
+ cache: new InMemoryCache(),
58
+ manifest: mockApplicationManifest(),
59
+ });
60
+
61
+ using host = await mockMcpHost({
62
+ hostContext: {
63
+ ...minimalHostContextWithToolName("GetProduct"),
64
+ theme: "light",
65
+ },
66
+ });
67
+ host.onCleanup(() => client.stop());
68
+
69
+ host.sendToolInput({ arguments: {} });
70
+ host.sendToolResult(graphqlToolResult({ data: { product: null } }));
71
+
72
+ using _disabledAct = disableActEnvironment();
73
+ const { takeSnapshot } = await renderHookToSnapshotStream(
74
+ () => useHostContext(),
75
+ {
76
+ wrapper: ({ children }) => (
77
+ <ApolloProvider client={client}>{children}</ApolloProvider>
78
+ ),
79
+ }
80
+ );
81
+
82
+ await expect(takeSnapshot()).resolves.toStrictEqual({
83
+ ...minimalHostContextWithToolName("GetProduct"),
84
+ theme: "light",
85
+ });
86
+
87
+ host.sendHostContextChanged({ theme: "dark" });
88
+
89
+ await expect(takeSnapshot()).resolves.toStrictEqual({
90
+ ...minimalHostContextWithToolName("GetProduct"),
91
+ theme: "dark",
92
+ });
93
+
94
+ await expect(takeSnapshot).not.toRerender();
95
+ });
@@ -0,0 +1,14 @@
1
+ import { useCallback, useSyncExternalStore } from "react";
2
+ import { useApolloClient } from "./useApolloClient";
3
+
4
+ export function useHostContext() {
5
+ const appManager = useApolloClient()["appManager"];
6
+
7
+ return useSyncExternalStore(
8
+ useCallback(
9
+ (update) => appManager.onHostContextChanged(update),
10
+ [appManager]
11
+ ),
12
+ () => appManager.app.getHostContext()
13
+ );
14
+ }
@@ -1,4 +1,5 @@
1
1
  export { useApp } from "./hooks/useApp.js";
2
+ export { useHostContext } from "./hooks/useHostContext.js";
2
3
  export { useToolName } from "./hooks/useToolName.js";
3
4
  export { useToolMetadata } from "./hooks/useToolMetadata.js";
4
5
  export { useToolInput } from "./hooks/useToolInput.js";
@@ -1,4 +1,8 @@
1
- import { App, PostMessageTransport } from "@modelcontextprotocol/ext-apps";
1
+ import {
2
+ App,
3
+ PostMessageTransport,
4
+ type McpUiHostContextChangedNotification,
5
+ } from "@modelcontextprotocol/ext-apps";
2
6
  import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
7
  import type { ApplicationManifest } from "../../types/application-manifest";
4
8
  import type { FormattedExecutionResult } from "graphql";
@@ -19,6 +23,10 @@ export class McpAppManager {
19
23
  #toolMetadata: Record<string, unknown> | null = null;
20
24
  #toolInput: Record<string, unknown> | undefined;
21
25
 
26
+ #hostContextCallbacks = new Set<
27
+ (params: McpUiHostContextChangedNotification["params"]) => void
28
+ >();
29
+
22
30
  constructor(manifest: ApplicationManifest) {
23
31
  this.app = new App({ name: manifest.name, version: manifest.appVersion });
24
32
  }
@@ -35,6 +43,15 @@ export class McpAppManager {
35
43
  return this.#toolInput;
36
44
  }
37
45
 
46
+ onHostContextChanged(
47
+ cb: (params: McpUiHostContextChangedNotification["params"]) => void
48
+ ) {
49
+ this.#hostContextCallbacks.add(cb);
50
+ return () => {
51
+ this.#hostContextCallbacks.delete(cb);
52
+ };
53
+ }
54
+
38
55
  connect = cacheAsync(async () => {
39
56
  let toolResult = promiseWithResolvers<ApolloMcpServerApps.CallToolResult>();
40
57
 
@@ -44,6 +61,10 @@ export class McpAppManager {
44
61
  );
45
62
  };
46
63
 
64
+ this.app.onhostcontextchanged = (params) => {
65
+ this.#hostContextCallbacks.forEach((cb) => cb(params));
66
+ };
67
+
47
68
  await this.connectToHost();
48
69
 
49
70
  const { structuredContent } = await toolResult.promise;
@@ -0,0 +1,14 @@
1
+ import { useCallback, useSyncExternalStore } from "react";
2
+ import { useApolloClient } from "./useApolloClient";
3
+
4
+ export function useHostContext() {
5
+ const appManager = useApolloClient()["appManager"];
6
+
7
+ return useSyncExternalStore(
8
+ useCallback(
9
+ (update) => appManager.onHostContextChanged(update),
10
+ [appManager]
11
+ ),
12
+ () => appManager.app.getHostContext()
13
+ );
14
+ }
@@ -1,4 +1,5 @@
1
1
  export { useApp } from "./hooks/useApp.js";
2
+ export { useHostContext } from "./hooks/useHostContext.js";
2
3
  export { useToolName } from "./hooks/useToolName.js";
3
4
  export { useToolMetadata } from "./hooks/useToolMetadata.js";
4
5
  export { useToolInput } from "./hooks/useToolInput.js";
@@ -1,6 +1,7 @@
1
1
  export * from "./index.js";
2
2
  export {
3
3
  useApp,
4
+ useHostContext,
4
5
  useToolInput,
5
6
  createHydrationUtils,
6
7
  useToolMetadata,
@@ -1,6 +1,7 @@
1
1
  export * from "./index.js";
2
2
  export {
3
3
  useApp,
4
+ useHostContext,
4
5
  useToolInput,
5
6
  createHydrationUtils,
6
7
  useToolMetadata,
@@ -9,6 +9,9 @@ export type { Reactive } from "./reactive.js";
9
9
  export const useApp =
10
10
  missingHook<typeof import("./index.mcp.js").useApp>("useApp");
11
11
 
12
+ export const useHostContext =
13
+ missingHook<typeof import("./index.mcp.js").useHostContext>("useHostContext");
14
+
12
15
  export const useToolInput =
13
16
  missingHook<typeof import("./index.mcp.js").useToolInput>("useToolInput");
14
17