Documentation Index
Fetch the complete documentation index at: https://docs-staging.skybridge.tech/llms.txt
Use this file to discover all available pages before exploring further.
The useCallTool function allows you to call additional MCP tools from your view. It wraps the window.openai.callTool function while providing a more convenient state management and typed API.
Make sure your tool _meta["openai/widgetAccessible"] property is set to true to make it accessible from views - more info on component-initiated tool calls.
Basic usage
import { useCallTool } from "skybridge/web";
import { useState } from "react";
function BookTableView() {
const { callTool, isPending, isSuccess, data } = useCallTool<
{ time: string; people: number },
{ structuredContent: { tableNumber: string } }
>("bookTable");
return (
<div>
<button
disabled={isPending}
onClick={() => callTool({ time: "12:00", people: 2 })}
>
Book Table
</button>
{isSuccess && <p>Table booked: {data.structuredContent.tableNumber}</p>}
</div>
);
}
Parameters
const {
data,
error,
isError,
isIdle,
isPending,
isSuccess,
status,
callTool,
callToolAsync,
} = useCallTool<ToolArgs, ToolResponse>(name);
callTool(toolArgs, {
onError,
onSettled,
onSuccess,
});
await callToolAsync(toolArgs);
name
Required
The name of the tool to call. This must match the name of a tool registered on your MCP server.
Type Parameters
ToolArgs extends CallToolArgs = null
The type of arguments your tool accepts. Defaults to null for tools that don’t require arguments.
- If your tool has no arguments, you can omit this type parameter or set it to
null.
- If your tool requires arguments, define the shape as a
Record<string, unknown>.
ToolResponse extends Partial<
{ structuredContent: Record<string, unknown>; meta: Record<string, unknown> }
> = {}
The type of the response returned by your tool. This allows you to specify the exact shape of both the structuredContent and meta fields of your tool’s response.
Returns
callTool: (toolArgs?: ToolArgs, sideEffects?: SideEffects) => void
The mutation function you can call to trigger the tool. Optionally pass side-effect callbacks.
toolArgs: ToolArgs
- Optional if
ToolArgs is null
- The arguments to pass to the tool
sideEffects: SideEffects
- Optional
- The side-effect callbacks to execute when the tool call is successful, encounters an error, or is settled:
onSuccess: (data: ToolResponse, toolArgs: ToolArgs) => void
- Optional
- This function will fire when the tool call is successful and will be passed the tool’s response
onError: (error: unknown, toolArgs: ToolArgs) => void
- Optional
- This function will fire if the tool call encounters an error
onSettled: (data: ToolResponse | undefined, error: unknown | undefined, toolArgs: ToolArgs) => void
- Optional
- This function will fire when the tool call is either successful or encounters an error
callToolAsync: (toolArgs?: ToolArgs) => Promise<ToolResponse>;
Similar to callTool but returns a promise which can be awaited.
status
status: "idle" | "pending" | "success" | "error";
idle - Initial status prior to the tool call executing
pending - The tool call is currently executing
success - The last tool call was successful
error - The last tool call resulted in an error
isIdle, isPending, isSuccess, isError
isIdle: boolean;
isPending: boolean;
isSuccess: boolean;
isError: boolean;
Boolean variables derived from status for convenience.
data
data: ToolResponse | undefined;
- The successfully resolved data from the last tool call. Only available when the status is
success.
- Contains the default
CallToolResponse shape merged with your ToolResponse type:
type CallToolResponse = {
/** content, isError and result shape is not configurable and shared across all tools */
content: { type: "text"; text: string }[];
isError: boolean;
result: string;
/** structuredContent and meta are shaped according to your ToolResponse type parameter */
structuredContent: Record<string, unknown>;
meta: Record<string, unknown>;
};
error
error: unknown | undefined;
- Only available when the status is
error.
- The error object if the last tool call encountered an error
Examples
With Side Effects
Handle success, error, and settled states with callbacks:
import { useCallTool } from "skybridge/web";
function SubmitForm() {
const { callTool, isPending } = useCallTool<{ email: string }>("subscribe");
const handleSubmit = (email: string) => {
callTool(
{ email },
{
onSuccess: (data) => {
console.log("Subscribed successfully!", data);
},
onError: (error) => {
console.error("Subscription failed:", error);
},
onSettled: (data, error) => {
console.log("Request completed", { data, error });
},
}
);
};
return (
<button
disabled={isPending}
onClick={() => handleSubmit("user@example.com")}
>
Subscribe
</button>
);
}
You can pass side effect options as the first argument to the callTool function if it doesn’t require any arguments.
import { useCallTool } from "skybridge/web";
function RefreshButton() {
const { callTool, isPending } = useCallTool("refresh");
return (
<button
disabled={isPending}
onClick={() =>
callTool({
onSuccess: () => {
console.log("Refreshed");
},
})
}
>
{isPending ? "Refreshing..." : "Refresh"}
</button>
);
}
Async/Await Pattern
Use callToolAsync for async/await syntax:
import { useCallTool } from "skybridge/web";
function AsyncExample() {
const { callToolAsync, isPending, isError, error } = useCallTool<
{ id: string },
{ structuredContent: { name: string; price: number } }
>("getProduct");
const handleClick = async () => {
try {
const response = await callToolAsync({ id: "123" });
console.log("Product:", response.structuredContent.name);
} catch (err) {
console.error("Failed to fetch product:", err);
}
};
return (
<div>
<button disabled={isPending} onClick={handleClick}>
Fetch Product
</button>
{isError && <p>Error: {String(error)}</p>}
</div>
);
}
Typed Response
Leverage TypeScript to get full type safety on the response:
import { useCallTool } from "skybridge/web";
type WeatherArgs = {
city: string;
units?: "metric" | "imperial";
};
type WeatherResponse = {
structuredContent: {
temperature: number;
conditions: string;
humidity: number;
};
};
function WeatherView() {
const { callTool, data, isPending, isSuccess } = useCallTool<
WeatherArgs,
WeatherResponse
>("getWeather");
return (
<div>
<button
disabled={isPending}
onClick={() => callTool({ city: "Paris", units: "metric" })}
>
Get Weather
</button>
{isSuccess && (
<div>
<p>Temperature: {data.structuredContent.temperature}°C</p>
<p>Conditions: {data.structuredContent.conditions}</p>
<p>Humidity: {data.structuredContent.humidity}%</p>
</div>
)}
</div>
);
}