Releases: apollographql/apollo-client-ai-apps
0.6.5 (2026-03-23)
Features
Add support for extraOutputs to the @tool directive
The @tool directive now supports an extraOutputs argument. This is a free-form object (any shape) that is written to the manifest under each tool's config. Values provided to extraOutputs are returned by Apollo MCP Server for the tool result in structuredContent to make it accessible to the LLM.
query MyQuery
@tool(
name: "my-tool",
description: "My tool",
extraOutputs: { "follow-up-instructions": "Perform a feat of magic" }
) {
myField
}Support @private in operations to hide parts of a query result from LLMs
In MCP Apps, you may have data that you want made available to your app but hidden from the LLM. A new @private directive is now supported that hides these fields from LLMs:
query ProductsQuery {
topProducts {
sku
title
meta @private {
createdAt
barcode
}
}
}
@private directs Apollo MCP Server to remove those fields in structuredContent so that the field data is not available to the LLM. The full result is instead added to _meta. @apollo/client-ai-apps handles reading the query result from the proper location when @private is used.
0.6.4 (2026-03-13)
Fixes
Always write the manifest in buildStart
The Vite plugin currently writes the manifest file in the writeBundle phase of the build. This causes issues if you try to build the app before the manifest file is generated since the source code imports the manifest to provide to the ApolloClient constructor. This change writes the manifest in buildStart to ensure it is available before the build begins.
This change makes it easier to add .application-manifest.json to .gitignore if you find it too noisy to commit to source control.
0.6.3 (2026-03-13)
Fixes
Fix ChatGPT page reload getting stuck
Fixes an issue where reloading the page in ChatGPT would cause the app to get stuck indefinitely. After a reload, ChatGPT does not re-send the ui/notifications/tool-result notification, so the app is stuck waiting for an event that would never arrive.
Fix issue with operation description on executed queries
Fixes an issue where a query executed by the client through the Apollo MCP Server execute tool maintained operation descriptions on the query.
0.6.2 (2026-03-12)
Fixes
Strip operation description from manifest body field
When a GraphQL operation uses an operation description as the tool description, the description is removed from the operation body in the manifest. This fixes a compatibility issue with Apollo MCP Server which currently does not support operation descriptions.
0.6.1 (2026-03-11)
Features
Add useToolInfo hook
A new useToolInfo() hook is now available that combines useToolName() and useToolInput() into a single hook. useToolInfo is more type-safe and automatically narrows the toolInput type based on the toolName.
// With toolInputs registered for "CreateTodo" and "DeleteTodo":
const info = useToolInfo();
// info: { toolName: "CreateTodo"; toolInput: CreateTodoInput }
// | { toolName: "DeleteTodo"; toolInput: DeleteTodoInput }
// | undefined
if (info?.toolName === "CreateTodo") {
// info.toolInput is narrowed to `CreateTodoInput`
doSomething(info.toolInput.title);
}As a result, useToolName() and useToolInput() are now deprecated in favor of useToolInfo(). These hooks will be removed with the next major version.
Generate a TypeScript definition file for .application-manifest.json
The Vite plugin now generates a .application-manifest.json.d.ts TypeScript declaration file next to .application-manifest.json. This file declares the manifest as ApplicationManifest, so TypeScript infers the correct type automatically when you import it.
This removes the need to type cast the manifest when initializing ApolloClient:
// before
import manifest from "./.application-manifest.json";
const client = new ApolloClient({
manifest: manifest as ApplicationManifest, // cast required
});
// after
import manifest from "./.application-manifest.json";
const client = new ApolloClient({
manifest, // type is inferred as ApplicationManifest
});Note
This requires the TypeScript allowArbitraryExtensions option. Please ensure your tsconfig.json extends one of the provided tsconfig, or add these compiler options manually:
{
"compilerOptions": {
"allowArbitraryExtensions": true,
"resolveJsonModule": true
}
}Add type-safe tool names
The Vite plugin now generates a .apollo-client-ai-apps/types/register.d.ts TypeScript declaration file. This file contains a union of all tool names found in your app's @tool directives.
This means the useToolName() hook now provides the precise union of tool names instead of string | undefined:
// before
const toolName = useToolName(); // string | undefined
// after (with @tool directives on "CreateTodo", "DeleteTodo", "UpdateTodo")
const toolName = useToolName(); // "CreateTodo" | "DeleteTodo" | "UpdateTodo" | undefinedThe generated file is written to .apollo-client-ai-apps/types/register.d.ts and is kept up to date as you edit your operations. Add this path to your tsconfig.json include to ensure these types are included:
{
"include": ["src", ".apollo-client-ai-apps/types"]
}You might also consider adding .apollo-client-ai-apps/ to your .gitignore since it is fully generated.
The ToolName type is exported from @apollo/client-ai-apps if you need access to the available tool names for your own utilities.
@tool name and description arguments are now optional
The name and description arguments on the @tool directive are now optional. When omitted, they fall back to the operation name and description respectively.
0.6.0 (2026-03-06)
Breaking Changes
Added a new required appsOutDir option to the apolloClientAiApps Vite plugin
The apolloClientAiApps Vite plugin now requires an appsOutDir option that controls where build output is written. The value must end with apps as the final path segment (e.g. "dist/apps").
apolloClientAiApps({ targets: ["mcp"], appsOutDir: "dist/apps" });The plugin will now write the application manifest to <appsOutDir>/<appName>/.application-manifest.json, where appName is taken from the name field in your apollo-client-ai-apps config or package.json. Previously, the output location was derived from build.outDir in your Vite config. Setting build.outDir alongside this plugin will now emit a warning that it is ignored.
This option replaces build.outDir. Setting build.outDir now emits a warning and the value is ignored. To migrate, please move the path from build.outDir to the appsOutDir option in the apolloClientAiApps plugin.
// vite.config.ts
export default defineConfig({
- build: {
- outDir: "../../apps",
- },
plugins: [
apolloClientAiApps({
targets: ["mcp"],
+ appsOutDir: "../../apps" ,
}),
],
});Features
Add baseUriDomains to CSP config
Adds support for configuring baseUriDomains in CSP settings. Only available for MCP apps.
Add a useHostContext hook
Adds a new useHostContext hook that returns the current host context from the MCP host.
import { useHostContext } from "@apollo/client-ai-apps/react";
function MyComponent() {
const hostContext = useHostContext();
// ...
}Fixes
@modelcontextprotocol/ext-apps is now a required peer dependency
@modelcontextprotocol/ext-apps is now a required peer dependency and must be installed along with this library.
0.5.4 (2026-02-27)
Fixes
Fix build when using fragment definitions
Fix an issue where fragment definitions would cause the Vite build to crash.
0.5.3 (2026-02-26)
Features
Add createHydrationUtils factory and reactive helper
Adds a new createHydrationUtils(query) factory that returns a useHydratedVariables hook. This hook is used to populate variables from tool input to ensure the data returned by your query matches what the LLM returned.
import { createHydrationUtils, reactive } from "@apollo/client-ai-apps/react";
const MY_QUERY = gql`
query MyQuery($category: String!, $page: Int) @tool(name: "MyQuery") {
# ...
}
`;
const { useHydratedVariables } = createHydrationUtils(MY_QUERY);
function ProductPage({ id, category }: Props) {
const [variables, setVariables] = useHydratedVariables({
page: 1, // state: managed internally, seeded from tool input
sortBy: "title", // state: managed internally, seeded from tool input
id: reactive(props.id), // reactive: always follows props.id after hydration
category: reactive(props.category), // reactive: always follows props.category
});
const { data } = useQuery(MY_QUERY, { variables });
}0.5.2 (2026-02-23)
Fixes
Add fallback when toolName is not available from host context
Provides a fallback in MCP apps to get the executed tool name from _meta.toolName when the host does not provide toolInfo from host context, or structuredContent.toolName when the host does not forward _meta to the connected application.
Always use window.openai.toolInput to initialize the tool input value
ChatGPT doesn't always send the ui/notifications/tool-input notification before we get ui/notifications/tool-result. Other times it sends the notification more than once. Because of the inconsistency, we can't always accurately get the correct tool input value using the notification by the time we get the ui/notifications/tool-result notification. This results in the wrong value for variables and incorrectly writes the query data to the cache.
This fix falls back to get toolInput from window.openai.toolInput in ChatGPT apps after we receive the ui/notification/tool-result notification to ensure we have the correct tool input value.
0.5.1 (2026-02-19)
Fixes
Fixes the type of ApolloClientAiAppsConfig.Config
The ApolloClientAiAppsConfig.Config is mistakenly set as the output type instead of the input type. This primarily affected the labels config which expected a different input shape than the output shape.