@salesforce/sdk-chat
v1.135.0
Published
Chat SDK for participating in conversational flows across Salesforce application surfaces. Provides a unified API for sending messages, executing tools, managing widget state, and reading resources — regardless of whether the host is OpenAI ChatGPT, an MC
Maintainers
Keywords
Readme
@salesforce/sdk-chat
Chat SDK for participating in conversational flows across Salesforce application surfaces. Provides a unified API for sending messages, executing tools, managing widget state, and reading resources — regardless of whether the host is OpenAI ChatGPT, an MCP Apps host, or Salesforce Agentforce.
Installation
npm install @salesforce/sdk-chatQuick Start
import { createChatSDK } from "@salesforce/sdk-chat";
const sdk = await createChatSDK();
// Send a message to the host
await sdk.sendMessageToHost?.({ content: "Hello from the widget" });
// Read tool input provided by the host
const input = sdk.accessToolInput<{ query: string }>();
if (input) {
console.log(input.data.query);
}Initialization
Factory (Async)
createChatSDK detects the runtime surface and returns the appropriate implementation. Each call creates a new instance.
const sdk = await createChatSDK();Singleton (Recommended)
getChatSDK caches the instance so all callers share one SDK. The Promise itself is cached, preventing race conditions from concurrent callers.
import { getChatSDK } from "@salesforce/sdk-chat";
const sdk = await getChatSDK();Synchronous Access
After getChatSDK() has resolved, you can access the instance synchronously. Returns null if not yet initialized.
import { getChatSDKSync } from "@salesforce/sdk-chat";
const sdk = getChatSDKSync(); // ChatSDK | nullOptions
import { Surface } from "@salesforce/sdk-core";
const sdk = await createChatSDK({
// Force a specific surface (skip auto-detection)
surface: Surface.MCPApps,
// MCP Apps session options
mcpApps: {
appIdentity: { name: "my-app" },
handshakeTimeout: 5000,
},
});Reset (Testing)
import { resetChatSDK } from "@salesforce/sdk-chat";
resetChatSDK(); // Clears cached singleton; next getChatSDK() creates fresh instanceAPI Reference
All ChatSDK methods are optional — availability depends on the runtime surface. Always use optional chaining (?.) when calling them.
sendMessageToHost
Send a message into the conversation.
await sdk.sendMessageToHost?.({
content: "Here are the results",
metadata: { source: "search" }, // optional
});| Param | Type | Description |
| ------------------ | ------------------------- | --------------------------- |
| message.content | string | Message text |
| message.metadata | Record<string, unknown> | Optional key-value metadata |
callTool
Execute a tool on the MCP server and get the result.
const result = await sdk.callTool<{ items: string[] }>({
toolName: "search",
params: { query: "accounts" },
});| Param | Type | Description |
| ------------------- | ------------------------- | -------------------------- |
| toolCall.toolName | string | Name of the tool to invoke |
| toolCall.params | Record<string, unknown> | Optional tool parameters |
accessToolInput / accessToolOutput
Read the current tool input or output provided by the host. These are synchronous getters that return the latest state.
const input = sdk.accessToolInput<{ accountId: string }>();
const output = sdk.accessToolOutput<{ name: string; revenue: number }>();
if (input) {
console.log(input.data.accountId);
}Returns ToolState<T> | null where ToolState<T> = { data: T; timestamp?: number }.
accessToolMetadata
Access metadata about the current tool (schema, description, response metadata).
const meta = sdk.accessToolMetadata<{ schema: object }>();getWidgetState / setWidgetState
Persist widget state across tool invocations via the host's model context.
// Save state
sdk.setWidgetState?.({ selectedTab: "overview", filters: ["active"] });
// Restore state
const state = sdk.getWidgetState<{ selectedTab: string }>();setWidgetState is fire-and-forget — it sends state to the host but does not wait for acknowledgment.
readResource
Read resource content by URI. MCP Apps only.
const resource = await sdk.readResource<{ html: string }>({
uri: "salesforce://accounts/001xxx",
});openLink
Open a URL. On OpenAI, falls back to window.open() if the native API is unavailable.
await sdk.openLink?.("https://salesforce.com/help");setDisplayMode
Request the host to change the widget's display mode.
const result = await sdk.setDisplayMode?.("fullscreen");
// result.mode === "fullscreen"| Mode | Description |
| -------------- | --------------------------------- |
| "inline" | Normal embedded view in chat |
| "fullscreen" | Expanded full-screen view |
| "pip" | Picture-in-Picture floating panel |
getHostContext
Get environment information from the host. MCP Apps only.
const ctx = sdk.getHostContext?.();
if (ctx) {
console.log(ctx.theme); // "light" | "dark"
console.log(ctx.displayMode); // "inline" | "fullscreen" | "pip"
console.log(ctx.locale); // "en-US"
console.log(ctx.maxHeight); // number (CSS pixels)
console.log(ctx.safeArea); // { top, right, bottom, left }
console.log(ctx.deviceCapabilities); // { touch?, hover? }
console.log(ctx.styles); // { variables?, css? }
}subscribe
Subscribe to SDK data changes (tool input, output, metadata, host context). Designed to work with React's useSyncExternalStore.
const unsubscribe = sdk.subscribe?.(() => {
const output = sdk.accessToolOutput();
// re-render with new data
});
// Cleanup
unsubscribe?.();onToolCanceled
Register a callback for when the host cancels tool execution. MCP Apps only.
const unsubscribe = sdk.onToolCanceled?.((reason) => {
console.log("Tool canceled:", reason);
});followUpActions
Get available follow-up actions (SalesforceACC only, currently returns []).
const actions = sdk.followUpActions?.() ?? [];Surface Capabilities
Not all methods are available on every surface. Use getSurfaceCapabilities from @salesforce/sdk-core to check at runtime, or refer to this matrix:
| Method | MCP Apps | OpenAI | Salesforce ACC |
| -------------------- | -------- | ------ | -------------- |
| sendMessageToHost | Yes | Yes | Yes |
| callTool | Yes | Yes | No |
| accessToolInput | Yes | Yes | No |
| accessToolOutput | Yes | Yes | No |
| accessToolMetadata | Yes | Yes | No |
| getWidgetState | Yes | Yes | No |
| setWidgetState | Yes | Yes | No |
| readResource | Yes | No | No |
| openLink | Yes | Yes | Yes |
| setDisplayMode | Yes | Yes | No |
| getHostContext | Yes | No | No |
| onToolCanceled | Yes | No | No |
| subscribe | Yes | Yes | Yes |
WebApp and Mosaic surfaces return an empty object with no methods.
import { getSurface, getSurfaceCapabilities } from "@salesforce/sdk-core";
const caps = getSurfaceCapabilities(getSurface());
if (caps.callTool) {
await sdk.callTool?.({ toolName: "search", params: { q: "test" } });
}Exported Types
import type {
ChatSDK,
ChatMessage,
ToolCall,
ToolState,
ResourceRequest,
DisplayMode,
HostContext,
SafeAreaInsets,
DeviceCapabilities,
SDKOptions,
} from "@salesforce/sdk-chat";
import type { ChatSDKOptions } from "@salesforce/sdk-chat";License
Copyright (c) 2026, Salesforce, Inc. All rights reserved. For full license text, see the LICENSE.txt file.
