Skip to main content
Utility Tools provide dynamic tool discovery and execution capabilities for TypeScript/Node.js applications, allowing your AI agents to explore and use tools at runtime.

Overview

Utility Tools enable your TypeScript agents to:
  • Discover tools based on natural language queries
  • Execute tools dynamically without knowing their names in advance
  • Explore capabilities of connected integrations
  • Adapt behaviour based on available tools
Main Concepts: For conceptual information about Utility Tools and how they work, see the Utility Tools Introduction. This page focuses on TypeScript-specific implementation details.

Getting Utility Tools

import { StackOneToolSet } from '@stackone/ai';

const toolset = new StackOneToolSet({
  accountId: 'your-account-id',
});

// Fetch tools via MCP
const tools = await toolset.fetchTools();

// Get utility tools for dynamic discovery
const utilityTools = await tools.utilityTools();
Complete TypeScript Examples: View the full implementation with all TypeScript-specific patterns in our Utility Tools example.

Available Utility Tools

Find relevant tools based on natural language queries:
const searchTool = utilityTools.getTool('tool_search');

const { tools = [] } = (await searchTool.execute({
  query: 'send a gmail message',
  limit: 5,
  minScore: 0.3
})) as { tools?: Array<{ name: string; description: string; score: number }> };

const gmailTool = tools.find((tool) => tool.name === 'gmail_send_message');
if (!gmailTool) {
  throw new Error('gmail_send_message is not available for this account');
}

console.log('📧 Gmail tool found:', gmailTool);
Parameters:
  • query (string): Natural language description of what you want to do
  • limit (number): Maximum number of tools to return (default: 5)
  • minScore (number): Minimum relevance score (0-1, default: 0.3)

tool_execute

Execute any tool dynamically by name after discovering it:
const executeTool = utilityTools.getTool('tool_execute');

const emailResult = await executeTool.execute({
  toolName: 'gmail_send_message',
  params: {
    body: {
      raw: 'U3ViamVjdDogV2VsY29tZQ0KDQpIZWxsbywgdGhpcyBpcyBhIHRlc3QgZW1haWwu', // base64url-encoded MIME payload
    },
  },
});

console.log('Email output:', emailResult);
Parameters:
  • toolName (string): Name of the tool to execute
  • params (object): Parameters that match the target tool’s schema

Framework Integration

OpenAI Functions

import { OpenAI } from 'openai';

const openai = new OpenAI();
const utilityTools = await tools.utilityTools();
const openAITools = utilityTools.toOpenAI();

const completion = await openai.chat.completions.create({
  model: 'gpt-4',
  messages: [
    {
      role: 'user',
      content: 'Find tools for managing employee time off and show me recent requests'
    }
  ],
  tools: openAITools
});

// Handle tool calls
for (const toolCall of completion.choices[0].message.tool_calls || []) {
  const tool = utilityTools.getTool(toolCall.function.name);
  const result = await tool.execute(JSON.parse(toolCall.function.arguments));
  console.log('Result:', result);
}
Complete OpenAI Example: See the full OpenAI integration with proper error handling and multi-turn conversations in openai-integration.ts.

Vercel AI SDK

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';

const utilityTools = await tools.utilityTools();
const aiSdkTools = await utilityTools.toAISDK();

const { text, toolCalls } = await generateText({
  model: openai('gpt-4'),
  tools: aiSdkTools,
  prompt: 'Search for HR tools and list employees in the engineering department',
  maxSteps: 5
});
Complete AI SDK Example: See the full Vercel AI SDK integration with streaming and tool execution in ai-sdk-integration.ts.

TypeScript-Specific Patterns

Type-Safe Tool Execution

TypeScript enables type-safe utility tool usage with proper interface definitions:
import type { Tools } from '@stackone/ai';

interface ToolExecutionResult<T = Record<string, unknown>> {
  data: T;
  success: boolean;
  error?: string;
}

class TypedUtilityToolsAgent {
  constructor(private utilityTools: Tools) {}

  async executeWithTypes<T>(toolName: string, params: Record<string, unknown>): Promise<ToolExecutionResult<T>> {
    const executeTool = this.utilityTools.getTool('tool_execute');
    if (!executeTool) {
      throw new Error('tool_execute not available');
    }
    const data = (await executeTool.execute({ toolName, params })) as T;
    return { success: true, data };
  }
}

Async/Await Patterns

Utility tools work with modern TypeScript async patterns:
async function discoverAndExecute(query: string) {
  const utilityTools = await tools.utilityTools();

  // Step 1: Search for tools
  console.log(`🔍 Searching for tools related to: "${query}"`);
  const searchTool = utilityTools.getTool('tool_search');
  if (!searchTool) throw new Error('tool_search not available');
  const searchResults = await searchTool.execute({ query, limit: 5 });

  const tools = (searchResults.tools ?? []) as Array<{ name: string }>;
  if (tools.length === 0) {
    console.log('❌ No relevant tools found');
    return;
  }

  // Step 2: Execute the best tool
  const bestTool = tools[0];
  console.log(`⚡ Executing: ${bestTool.name}`);

  const executeTool = utilityTools.getTool('tool_execute');
  if (!executeTool) throw new Error('tool_execute not available');
  const result = await executeTool.execute({
    toolName: bestTool.name,
    params: { limit: 5 }
  });

  console.log('✅ Result:', result);
}

Error Handling Patterns

async function safeToolExecution(toolName: string, params: any) {
  try {
    const executeTool = utilityTools.getTool('tool_execute');
    if (!executeTool) throw new Error('tool_execute not available');
    const result = await executeTool.execute({ toolName, params });
    return { success: true, data: result };
  } catch (error) {
    console.error(`Failed to execute ${toolName}:`, error);
    return { success: false, error: error.message };
  }
}

Example

examples/utility-tools.ts
View on GitHub →

Best Practices

  1. Cache Tool Metadata: Store tool descriptions to avoid repeated API calls
  2. Handle Failures Gracefully: Utility tools may fail if integrations are unavailable
  3. Use Appropriate Filters: Set reasonable minScore and limit values
  4. Validate Parameters: Always validate parameters before executing tools
  5. Monitor Usage: Utility tools count toward your API usage limits

Limitations

  • Beta Status: API may change in future versions
  • Performance: Tool discovery adds latency compared to direct tool calls
  • Accuracy: Search results depend on tool metadata quality
  • Rate Limits: Subject to the same rate limits as regular tools

Next Steps