Docs

useCallTool

Call tools and functions defined by the ChatGPT host environment

useCallTool

Call tools and functions defined by the ChatGPT host environment. This hook allows your widget to invoke capabilities provided by the host, such as accessing user data, performing calculations, or triggering actions.

Usage

import { useCallTool } from '@chatgpt-apps/sdk';

function MyWidget() {
  const callTool = useCallTool();

  const handleAnalyze = async () => {
    const result = await callTool('analyze_data', {
      data: userInput,
      options: { deep: true },
    });
    
    console.log('Analysis result:', result);
  };

  return <button onClick={handleAnalyze}>Analyze</button>;
}

Parameters

The hook itself accepts no parameters. The returned function accepts:

ParameterTypeDescription
toolNamestringThe name of the tool to call
paramsobjectParameters to pass to the tool

Return Type

Returns a function with the following signature:

type CallToolFunction = <T = unknown>(
  toolName: string,
  params?: Record<string, unknown>
) => Promise<T>;

Example

Basic Tool Call

import { useCallTool } from '@chatgpt-apps/sdk';

function CalculatorWidget() {
  const callTool = useCallTool();
  const [result, setResult] = useState<number | null>(null);

  const calculate = async (expression: string) => {
    try {
      const answer = await callTool<number>('calculate', {
        expression,
      });
      setResult(answer);
    } catch (error) {
      console.error('Calculation failed:', error);
    }
  };

  return (
    <div>
      <input 
        type="text" 
        placeholder="Enter expression"
        onKeyDown={(e) => {
          if (e.key === 'Enter') {
            calculate(e.currentTarget.value);
          }
        }}
      />
      {result !== null && <p>Result: {result}</p>}
    </div>
  );
}

With Loading State

import { useCallTool } from '@chatgpt-apps/sdk';

function DataWidget() {
  const callTool = useCallTool();
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState(null);

  const fetchData = async () => {
    setLoading(true);
    try {
      const result = await callTool('fetch_user_data', {
        includeProfile: true,
        includeSettings: false,
      });
      setData(result);
    } catch (error) {
      console.error('Failed to fetch data:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? 'Loading...' : 'Fetch Data'}
      </button>
      {data && <DataDisplay data={data} />}
    </div>
  );
}

Type-Safe Tool Calls

import { useCallTool } from '@chatgpt-apps/sdk';

interface SearchParams {
  query: string;
  limit: number;
  filters?: string[];
}

interface SearchResult {
  items: Array<{
    id: string;
    title: string;
    score: number;
  }>;
  total: number;
}

function SearchWidget() {
  const callTool = useCallTool();
  const [results, setResults] = useState<SearchResult | null>(null);

  const performSearch = async (query: string) => {
    const params: SearchParams = {
      query,
      limit: 10,
      filters: ['recent'],
    };

    const result = await callTool<SearchResult>('search', params);
    setResults(result);
  };

  return (
    <div>
      <SearchInput onSearch={performSearch} />
      {results && <SearchResults items={results.items} />}
    </div>
  );
}

Error Handling

import { useCallTool } from '@chatgpt-apps/sdk';

function SafeWidget() {
  const callTool = useCallTool();
  const [error, setError] = useState<string | null>(null);

  const invokeTool = async () => {
    setError(null);
    try {
      const result = await callTool('risky_operation', { force: true });
      return result;
    } catch (err) {
      if (err instanceof Error) {
        setError(err.message);
      } else {
        setError('An unknown error occurred');
      }
      return null;
    }
  };

  return (
    <div>
      <button onClick={invokeTool}>Run Operation</button>
      {error && <div className="error">{error}</div>}
    </div>
  );
}

Notes

  • Tool availability depends on the host environment configuration
  • Always handle errors gracefully as tools may not be available
  • Use TypeScript generics for type-safe return values
  • Tool calls are asynchronous and return Promises
  • The host may impose rate limits or permissions on tool usage

On this page