Chanl

Automate with Tools

Create tools, group them in toolsets, and connect via MCP

Tools are functions your AI agents can call during conversations -- CRM lookups, order processing, appointment scheduling, anything your business needs. Define them once in Chanl, and every agent (native or connected via MCP) can use them.

Installation

npm install @chanl/sdk

Setup

import { Chanl } from '@chanl/sdk';

const chanl = new Chanl({
  apiKey: process.env.CHANL_API_KEY,
});

Create a tool

A tool is a function definition (name, description, JSON Schema parameters) plus an execution target (your HTTP endpoint).

const tool = await chanl.tools.create({
  name: 'lookup_order',
  description: 'Look up order details by order number',
  parameters: {
    type: 'object',
    properties: {
      order_id: {
        type: 'string',
        description: 'The order number (e.g., ORDER-12345)',
      },
    },
    required: ['order_id'],
  },
  handlerUrl: 'https://api.yourstore.com/orders/lookup',
});

console.log('Created tool:', tool.id);

Parameters:

ParameterTypeRequiredDescription
namestringYesFunction name (snake_case recommended)
descriptionstringYesWhat the tool does (shown to the LLM)
parametersobjectYesJSON Schema for input parameters
handlerUrlstringYesYour API endpoint
handlerMethodstringNoGET or POST (default: POST)
handlerHeadersobjectNoCustom headers to send
timeoutnumberNoTimeout in ms (default: 30000)
retriesnumberNoRetry count on failure (default: 0)

Returns: Promise<Tool>

Test the tool

Execute a tool directly to verify it works before connecting it to an agent.

const result = await chanl.tools.execute(tool.id, {
  order_id: 'ORDER-12345',
});

console.log('Success:', result.success);
console.log('Output:', result.output);
console.log('Duration:', result.duration, 'ms');

Returns: Promise<ToolExecutionResult>

Group tools into toolsets

A toolset bundles related tools into a reusable collection. Attach a "Customer Support" toolset to any agent and it gets all the tools at once.

const toolset = await chanl.toolsets.create({
  name: 'Customer Support Tools',
  description: 'Tools for customer support agents',
  toolIds: [lookupOrder.id, processRefund.id, scheduleCallback.id],
});

console.log('Created toolset:', toolset.id);

Parameters:

ParameterTypeRequiredDescription
namestringYesToolset name
descriptionstringNoWhat this collection is for
toolIdsstring[]YesTool IDs to include

Returns: Promise<Toolset>

Manage toolset membership

// Add a tool to a toolset
await chanl.toolsets.addTool('toolset_abc123', 'tool_new');

// Remove a tool from a toolset
await chanl.toolsets.removeTool('toolset_abc123', 'tool_old');

// List tools in a toolset
const toolset = await chanl.toolsets.get('toolset_abc123');
console.log('Tools:', toolset.tools.map((t) => t.name));

Connect via MCP

Tools you create in Chanl are automatically available through the MCP server. Any MCP-compatible client -- Claude Desktop, Cursor, VAPI, custom agents -- connects to your workspace's MCP endpoint and gets access to all your tools.

// Get MCP configuration for your workspace
const config = await chanl.mcp.getConfig();

console.log('MCP Server URL:', config.serverUrl);
console.log('Available Tools:', config.tools.length);

Configure MCP in your client:

chanl mcp config
# Follow prompts to configure the MCP server

Once connected, tell your AI assistant things like "Look up order ORDER-12345" and it calls your tool through Chanl.

Test the MCP connection

const health = await chanl.mcp.testConnection();

console.log('Connected:', health.connected);
console.log('Tools Available:', health.toolCount);
console.log('Latency:', health.latency, 'ms');

Example tool definitions

Schedule an appointment

const tool = await chanl.tools.create({
  name: 'schedule_appointment',
  description: 'Schedule a service appointment for the customer',
  parameters: {
    type: 'object',
    properties: {
      customer_id: { type: 'string', description: 'Customer ID' },
      service_type: {
        type: 'string',
        enum: ['installation', 'repair', 'consultation'],
        description: 'Type of service',
      },
      preferred_date: {
        type: 'string',
        format: 'date',
        description: 'Preferred date (YYYY-MM-DD)',
      },
    },
    required: ['customer_id', 'service_type', 'preferred_date'],
  },
  handlerUrl: 'https://api.yourcompany.com/appointments',
  timeout: 10000,
});

Process a refund

const tool = await chanl.tools.create({
  name: 'process_refund',
  description: 'Process a refund for an order',
  parameters: {
    type: 'object',
    properties: {
      order_id: { type: 'string', description: 'Order to refund' },
      amount: { type: 'number', description: 'Refund amount (omit for full refund)' },
      reason: {
        type: 'string',
        enum: ['damaged', 'wrong_item', 'not_as_described', 'changed_mind', 'other'],
        description: 'Reason for refund',
      },
    },
    required: ['order_id', 'reason'],
  },
  handlerUrl: 'https://api.yourstore.com/refunds/process',
  timeout: 15000,
  retries: 2,
});

Implement a handler

Your handler receives POST requests with the tool parameters as the JSON body. Return a JSON response with the result.

// Express.js example
app.post('/tools/lookup-order', async (req, res) => {
  const { order_id } = req.body;

  try {
    const order = await db.orders.findOne({ orderId: order_id });

    if (!order) {
      return res.json({
        success: false,
        error: `Order ${order_id} not found`,
      });
    }

    return res.json({
      success: true,
      output: {
        orderId: order.orderId,
        status: order.status,
        items: order.items,
        total: order.total,
        trackingNumber: order.trackingNumber,
      },
    });
  } catch (error) {
    return res.status(500).json({
      success: false,
      error: 'Failed to look up order',
    });
  }
});

Manage tools

// List all tools
const { tools } = await chanl.tools.list();

// Search by name
const { tools } = await chanl.tools.list({ search: 'order' });

// Exclude system tools (kb_search, chanl_reason, etc.)
const { tools } = await chanl.tools.list({ includeSystem: false });

// Update a tool
await chanl.tools.update('tool_abc123', {
  description: 'Updated description',
  timeout: 20000,
  handlerUrl: 'https://new-api.example.com/handler',
});

// Delete a tool
await chanl.tools.delete('tool_abc123');

// Force delete (removes from all toolsets)
await chanl.tools.delete('tool_abc123', { force: true });

Full example

Set up a complete customer support tool suite.

import { Chanl } from '@chanl/sdk';

const chanl = new Chanl({
  apiKey: process.env.CHANL_API_KEY,
});

async function setupSupportTools() {
  const lookupOrder = await chanl.tools.create({
    name: 'lookup_order',
    description: 'Look up order details by order number or customer email',
    parameters: {
      type: 'object',
      properties: {
        order_id: { type: 'string', description: 'Order number' },
        email: { type: 'string', description: 'Customer email (alternative to order_id)' },
      },
    },
    handlerUrl: process.env.API_URL + '/tools/orders/lookup',
  });

  const processRefund = await chanl.tools.create({
    name: 'process_refund',
    description: 'Process a refund for an order',
    parameters: {
      type: 'object',
      properties: {
        order_id: { type: 'string' },
        amount: { type: 'number', description: 'Amount to refund (omit for full)' },
        reason: { type: 'string', enum: ['damaged', 'wrong_item', 'not_satisfied', 'other'] },
      },
      required: ['order_id', 'reason'],
    },
    handlerUrl: process.env.API_URL + '/tools/refunds/process',
  });

  const scheduleCallback = await chanl.tools.create({
    name: 'schedule_callback',
    description: 'Schedule a callback for the customer',
    parameters: {
      type: 'object',
      properties: {
        phone: { type: 'string', description: 'Phone number' },
        preferred_time: { type: 'string', enum: ['asap', '1_hour', '4_hours', 'tomorrow'] },
        reason: { type: 'string', description: 'Reason for callback' },
      },
      required: ['phone', 'preferred_time'],
    },
    handlerUrl: process.env.API_URL + '/tools/callbacks/schedule',
  });

  // Bundle into a toolset
  const toolset = await chanl.toolsets.create({
    name: 'Customer Support Suite',
    description: 'Core tools for customer support agents',
    toolIds: [lookupOrder.id, processRefund.id, scheduleCallback.id],
  });

  console.log('Toolset:', toolset.id);
  console.log('Tools:', [lookupOrder.name, processRefund.name, scheduleCallback.name]);

  return toolset;
}

Next steps

On this page