A comprehensive TypeScript client for the ToolRouter API supporting both direct access and account-level operations with full async support and type safety.
๐ Quick Links:
๐ Instant Integration - Deploy Model Control Panels (MCPs) in seconds and seamlessly integrate with your AI agents
๐ Authentication Made Simple - Built-in credential management with secure authentication handling, no manual setup needed
๐ Flexible Tool Composition - Mix and match tools across different MCPs to create powerful custom workflows
๐ค Universal Model Support - Compatible with OpenAI, Anthropic, Meta Llama, and all major AI models
๐ ๏ธ Extensive Tool Library - Access to 450+ production-ready tools across 40+ MCPs, with bi-weekly updates
๐ช Enterprise-Grade Reliability - Production-tested infrastructure trusted by numerous companies, with continuous improvements
- Two Client Types: DirectAccessClient for MCP-style tool calling, APIClient for full account management
- Full TypeScript Support: Complete type safety with comprehensive interfaces and error types
- Modern Async/Await: Built with axios for reliable HTTP communications
- Error Handling: Custom exception classes for different error types
- Rate Limiting: Built-in client-side rate limiting with sliding window
- Retry Logic: Automatic retry with exponential backoff
- Schema Support: OpenAI, Anthropic, and default schema formats
- Backward Compatibility: Maintains compatibility with existing ToolRouter class
- Production Ready: Comprehensive error handling, logging, and testing
npm install toolrouter
import { DirectAccessClient } from 'toolrouter';
async function main() {
const client = new DirectAccessClient(
"your-client-id",
"your-api-key",
"https://api.toolrouter.ai/s", // optional
"openai" // or "anthropic", "default"
);
try {
// List available tools
const tools = await client.listTools();
console.log(`Available: ${tools.length} tools`);
// Call a tool
if (tools.length > 0) {
const result = await client.callTool(
tools[0].name,
{ location: "San Francisco" }
);
console.log('Result:', result);
}
} catch (error) {
console.error('Error:', error);
}
}
main();
import { APIClient } from 'toolrouter';
async function main() {
const client = new APIClient(
"your-account-api-key",
"https://api.toolrouter.ai/v1", // optional
"openai"
);
try {
// Create a stack with server
const stack = await client.createStackWithServer(
"my-ai-stack",
"github-server",
true, // enable all tools
false, // analytics disabled
{ token: "ghp_your_token" }
);
// List tools in the stack
const tools = await client.listStackTools(stack.stack_id);
console.log(`Stack has ${tools.length} tools available`);
// Invoke a tool
const result = await client.invokeTool(
stack.stack_id,
"create_issue",
{ title: "Bug report", body: "Description" }
);
console.log('Tool result:', result);
} catch (error) {
console.error('Error:', error);
}
}
main();
Method | Description | Parameters | Returns |
---|---|---|---|
listTools() |
Get available tools from ToolRouter | schema?: SchemaType |
Promise<Tool[]> |
callTool() |
Call a tool using ToolRouter | toolName: string, toolInput: Record<string, any> |
Promise<any> |
Method | Description | Parameters | Returns |
---|---|---|---|
listStacks() |
List all stacks | None | Promise<Stack[]> |
createStack() |
Create a new stack | stackName: string, analyticsEnabled?: boolean |
Promise<Stack> |
updateStack() |
Update an existing stack | stackId: string, stackName?: string, analyticsEnabled?: boolean |
Promise<Stack> |
deleteStack() |
Delete a stack | stackId: string |
Promise<boolean> |
Method | Description | Parameters | Returns |
---|---|---|---|
listServers() |
List all available servers | None | Promise<Server[]> |
addServerToStack() |
Add a server to a stack | stackId: string, serverId: string, enableAllTools?: boolean, enabledTools?: string[] |
Promise<boolean> |
removeServerFromStack() |
Remove a server from a stack | stackId: string, serverId: string |
Promise<boolean> |
updateServerTools() |
Update enabled tools for a server | stackId: string, serverId: string, enabledTools: string[] |
Promise<boolean> |
Method | Description | Parameters | Returns |
---|---|---|---|
getCredentialsStatus() |
Get credentials status for a server | stackId: string, serverId: string |
Promise<CredentialsStatus> |
updateCredentials() |
Update credentials for a server | stackId: string, serverId: string, credentials: Record<string, string> |
Promise<boolean> |
Method | Description | Parameters | Returns |
---|---|---|---|
listStackTools() |
List tools available in a stack | stackId: string, schema?: SchemaType |
Promise<Tool[]> |
invokeTool() |
Invoke a tool in a stack | stackId: string, toolId: string, toolInput: Record<string, any> |
Promise<any> |
Method | Description | Parameters | Returns |
---|---|---|---|
createStackWithServer() |
Create stack and add server in one call | stackName: string, serverId: string, enableAllTools?: boolean, analyticsEnabled?: boolean, credentials?: Record<string, string> |
Promise<Stack> |
getStackSummary() |
Get comprehensive stack summary | stackId: string |
Promise<StackSummary> |
Function | Description | Parameters | Returns |
---|---|---|---|
setupDefaultRouter() |
Configure the default direct access client | clientId: string, apiKey: string, baseUrl?: string, options?: BaseClientOptions |
DirectAccessClient |
listTools() |
Async wrapper for list_tools (uses default client) | schema?: SchemaType |
Promise<Tool[]> |
callTool() |
Async wrapper for call_tool (uses default client) | toolName: string, toolInput: Record<string, any> |
Promise<any> |
For MCP-style direct tool access:
import { DirectAccessClient } from 'toolrouter';
const client = new DirectAccessClient(
"your-client-id",
"your-api-key",
"https://api.toolrouter.ai/s", // optional
"openai", // or "anthropic", "default"
{
timeout: 30000,
maxRetries: 3,
rateLimitRequests: 60,
rateLimitWindow: 60000
}
);
// List tools
const tools = await client.listTools("openai");
// Call tool
const result = await client.callTool("tool_name", { param: "value" });
For full account and stack management:
import { APIClient } from 'toolrouter';
const client = new APIClient(
"your-account-api-key",
"https://api.toolrouter.ai/v1", // optional
"openai",
{
timeout: 30000,
maxRetries: 3
}
);
// Stack operations
const stacks = await client.listStacks();
const stack = await client.createStack("My Stack", true);
await client.updateStack(stack.stack_id, "Updated Name");
await client.deleteStack(stack.stack_id);
// Server operations
const servers = await client.listServers();
await client.addServerToStack(stackId, serverId, true);
await client.removeServerFromStack(stackId, serverId);
await client.updateServerTools(stackId, serverId, ["tool1", "tool2"]);
// Credential management
const status = await client.getCredentialsStatus(stackId, serverId);
await client.updateCredentials(stackId, serverId, { api_key: "secret" });
// Tool operations
const tools = await client.listStackTools(stackId, "openai");
const result = await client.invokeTool(stackId, toolId, { param: "value" });
// Convenience methods
const stack = await client.createStackWithServer(
"Stack Name", "server-id",
true, // enable all tools
false, // analytics disabled
{ token: "secret" }
);
const summary = await client.getStackSummary(stackId);
export TOOLROUTER_CLIENT_ID="your-client-id"
export TOOLROUTER_API_KEY="your-api-key"
export TOOLROUTER_ACCOUNT_API_KEY="your-account-api-key"
import { BaseClientOptions } from 'toolrouter';
// Custom configuration
const options: BaseClientOptions = {
timeout: 60000, // Request timeout in ms
maxRetries: 5, // Retry attempts
rateLimitRequests: 100, // Requests per window
rateLimitWindow: 60000 // Window in milliseconds
};
const client = new DirectAccessClient(
"your-client-id",
"your-api-key",
"https://api.toolrouter.ai/s",
"openai",
options
);
The SDK provides specific exception types:
import {
ToolRouterError, // Base exception
AuthenticationError, // Invalid credentials
NotFoundError, // Resource not found
ValidationError, // Invalid request
ServerError, // Server-side error
RateLimitError // Rate limit exceeded
} from 'toolrouter';
try {
const result = await client.callTool("tool_name", {});
} catch (error) {
if (error instanceof AuthenticationError) {
console.log("Check your API key");
} else if (error instanceof NotFoundError) {
console.log("Tool or resource not found");
} else if (error instanceof RateLimitError) {
console.log("Rate limit exceeded, slow down");
} else if (error instanceof ToolRouterError) {
console.log(`General error: ${error.message} (Status: ${error.statusCode})`);
}
}
Existing code continues to work:
// Old API still works
import { ToolRouter, setupDefaultRouter, listTools, callTool } from 'toolrouter';
setupDefaultRouter("client-id", "api-key");
const tools = await listTools("openai");
const result = await callTool("tool_name", { param: "value" });
// ToolRouter class is now an alias for DirectAccessClient
const client = new ToolRouter("client-id", "api-key"); // Same as DirectAccessClient
src/
โโโ index.ts # Main SDK implementation
โ โโโ BaseClient # Shared functionality
โ โโโ DirectAccessClient # MCP-style tool calling
โ โโโ APIClient # Account management
โ โโโ Error classes # Custom error types
โ โโโ TypeScript interfaces # Type safety
tests/
โโโ toolrouter.test.ts # Comprehensive test suite
package.json # Package configuration
tsconfig.json # TypeScript configuration
.eslintrc.js # Linting configuration
# Install dev dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm test -- --coverage
# Build the project
npm run build
# Lint the code
npm run lint
# Lint and fix issues
npm run lint -- --fix
# Build TypeScript
npm run build
# Run all checks
npm test && npm run build && npm run lint
The SDK provides comprehensive TypeScript interfaces:
// Core interfaces
interface Tool {
tool_id?: string;
name: string;
description: string;
parameters: Record<string, any>;
input_schema?: Record<string, any>;
server?: string;
}
interface Stack {
stack_id: string;
stack_name: string;
configuration: StackConfiguration;
servers: StackServer[];
created_at: string;
updated_at: string;
}
interface Server {
server_id: string;
name: string;
description: string;
tools: Tool[];
required_credentials: Credential[];
optional_credentials: Credential[];
}
// Schema types
type SchemaType = 'openai' | 'anthropic' | 'default';
// Configuration options
interface BaseClientOptions {
timeout?: number;
maxRetries?: number;
rateLimitRequests?: number;
rateLimitWindow?: number;
}
- โจ Added APIClient for account-level operations
- โจ Full TypeScript support with comprehensive interfaces
- โจ Custom exception hierarchy with proper error handling
- โจ Built-in rate limiting and retry logic
- โจ Support for multiple schema formats (OpenAI, Anthropic, default)
- โจ Convenience methods for common workflows
- โจ Production-ready error handling and logging
- ๐ Maintained backward compatibility with ToolRouter class
- ๐ Comprehensive test suite with 77%+ coverage
- ๐ Initial release with basic ToolRouter functionality
Apache 2.0 License - see LICENSE file for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Add tests for new functionality
- Ensure all tests pass (
npm test
) - Build successfully (
npm run build
) - Lint your code (
npm run lint
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- Documentation: https://docs.toolrouter.ai
- Issues: GitHub Issues
- Email: admin@toolrouter.ai
Made with โค๏ธ by the ToolRouter team