How to integrate ActiveTrail MCP with Vercel AI SDK v6

Framework Integration Gradient
ActiveTrail Logo
Vercel AI SDK Logo
divider

Introduction

This guide walks you through connecting ActiveTrail to Vercel AI SDK v6 using the Composio tool router. By the end, you'll have a working ActiveTrail agent that can create a new email campaign for vip subscribers, add a contact to the 'newsletter' list, get open rates for last week's campaigns through natural language commands.

This guide will help you understand how to give your Vercel AI SDK agent real control over a ActiveTrail account through Composio's ActiveTrail MCP server.

Before we dive in, let's take a quick look at the key ideas and tools involved.

TL;DR

Here's what you'll learn:
  • How to set up and configure a Vercel AI SDK agent with ActiveTrail integration
  • Using Composio's Tool Router to dynamically load and access ActiveTrail tools
  • Creating an MCP client connection using HTTP transport
  • Building an interactive CLI chat interface with conversation history management
  • Handling tool calls and results within the Vercel AI SDK framework

What is Vercel AI SDK?

The Vercel AI SDK is a TypeScript library for building AI-powered applications. It provides tools for creating agents that can use external services and maintain conversation state.

Key features include:

  • streamText: Core function for streaming responses with real-time tool support
  • MCP Client: Built-in support for Model Context Protocol via @ai-sdk/mcp
  • Step Counting: Control multi-step tool execution with stopWhen: stepCountIs()
  • OpenAI Provider: Native integration with OpenAI models

What is the ActiveTrail MCP server, and what's possible with it?

The ActiveTrail MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your ActiveTrail account. It provides structured and secure access so your agent can perform ActiveTrail operations on your behalf.

Supported Tools & Triggers

Tools
Add Group MemberTool to add a member to a group in ActiveTrail.
Get Contact GrowthTool to retrieve executive report on contact growth showing daily active and inactive contact growth.
Create or Update Group MemberTool to create or update a member in a group.
Create a New GroupTool to create a new group in ActiveTrail.
Create ContactTool to create a new contact in ActiveTrail.
Create Content CategoryTool to create a new content category in ActiveTrail account.
Create New Mailing ListTool to create a new mailing list in ActiveTrail.
Create OrderTool to create new orders in ActiveTrail commerce system.
Create Smart Code SiteTool to create a new Smart Code site in ActiveTrail.
Create WebhookTool to create a new webhook for event notifications in ActiveTrail.
Delete content categoryTool to delete a specific content category by ID.
Delete group memberTool to delete a group member by ID.
Delete AutomationsTool to delete one or more automations from Active Trail.
Delete CampaignTool to remove a campaign from ActiveTrail account.
Delete ContactTool to remove a contact from the ActiveTrail account.
Delete group by IDTool to delete a group by ID.
Delete Group MemberTool to remove a member from a group in ActiveTrail.
Delete Mailing ListTool to remove a mailing list from ActiveTrail account.
Delete Mailing List MemberTool to remove a member from a mailing list in ActiveTrail.
Delete Smart Code SiteTool to remove a Smart Code site from ActiveTrail.
Delete TemplateTool to remove a template from ActiveTrail account.
Delete template categoryTool to delete a template category by ID.
Delete webhook parameterTool to delete a given webhook parameter from your account's webhook configuration.
Get Account BalanceTool to retrieve email and SMS credit balance for the account.
Get specific content categoryTool to retrieve specific category details by ID.
Get ActiveCommerce Integration DataTool to retrieve the account's ActiveCommerce integration data.
Get Account Merge StatusTool to check if the account has awaited merges.
Get List of All SMS Campaign ClickersTool to retrieve all contacts who clicked on links in an SMS campaign.
Get All Campaign ReportsTool to retrieve a full overview of all campaign reports with comprehensive metrics.
Get All GroupsTool to retrieve the full list of account groups with pagination and filtering.
Get All Sent CampaignsTool to retrieve campaigns with optional filtering by date, mailing list, and search criteria.
Get SMS Campaign Delivered ListTool to get a specific SMS campaign's delivered list data.
Get SMS Campaign Recipient DataTool to get a specific SMS campaign's 'sent to' data as a list.
Get SMS Campaign Unsubscribed ListTool to get a specific SMS campaign's unsubscribed data as a list.
Get Automation LogTool to track contacts through automation journey by retrieving detailed logs.
Get Automation Queue LogsTool to retrieve contacts that did not finish a specific automation.
Get Automation SMS Campaign Summary ReportTool to retrieve SMS campaigns' summary reports for a specific automation.
Get AutomationsTool to list account automations with filtering and pagination.
Get Automation DetailsTool to retrieve detailed configuration of a specific automation excluding step-by-step execution details.
Get Automation Email Campaign StepsTool to retrieve all email campaign steps in an automation workflow.
Get Automation SMS Campaign StepsTool to retrieve all SMS campaign steps in an automation workflow.
Get Automation Trigger TypesTool to retrieve all available start trigger options for automations.
Get Campaign BouncesTool to retrieve bounce details by domain for a specific campaign.
Get Campaign Click-Through DataTool to access click-through data for a specific campaign.
Get Campaign ComplaintsTool to retrieve contacts who reported a specific campaign as spam.
Get Campaign DesignTool to retrieve campaign design configuration including visual layout and HTML content.
Get Campaign Domains ReportTool to retrieve a report by domain for a specific campaign.
Get Campaign OpensTool to retrieve contacts who opened a specific campaign.
Get Campaign ReportTool to retrieve an overview report for a specific campaign.
Get Campaign Bounced Emails by TypeTool to retrieve bounced email details filtered by bounce type for a specific campaign.
Get Campaign Click Details ReportTool to retrieve click details report for a specific campaign.
Get Campaign Spam ComplaintsTool to retrieve contacts who reported a specific campaign as spam.
Get Campaign Email Activity ReportTool to retrieve all contacts' activity on a specific campaign.
Get Campaign Sent EmailsTool to retrieve contacts who received a specific campaign email.
Get Campaign Unopened ContactsTool to retrieve contacts who did not open a specific campaign.
Get Campaign SchedulingTool to retrieve campaign schedule configuration including timing and delivery settings.
Get Campaign by IDTool to retrieve complete campaign information including send settings, design, template, and A/B test configuration.
Get Campaign DetailsTool to retrieve detailed campaign information including name, subject, and settings.
Get Campaign by ID (Copy)Tool to retrieve complete campaign information including send settings, design, template, and A/B test configuration.
Get Campaign Segment SettingsTool to retrieve campaign sending settings including target groups and sending restrictions.
Get Sent CampaignsTool to retrieve a list of all sent campaigns from ActiveTrail.
Get Campaign TemplateTool to retrieve template details associated with a specific campaign.
Get Campaign Unopened ContactsTool to retrieve contacts who did not open a specific campaign.
Get Campaign Unsubscribed ContactsTool to retrieve contacts who unsubscribed from a specific email campaign.
Get Click Details by Link IDTool to retrieve click details for a specific link within a campaign.
Get Contact ActivityTool to retrieve contact's email engagement history including opens and clicks.
Get Contact BouncesTool to retrieve bounce activity for a specific contact by contact ID.
Get Contact FieldsTool to retrieve account contact fields filtered by type.
Get Contact GroupsTool to retrieve all groups associated with a specific contact.
Get Contact ListTool to retrieve account contacts filtered by status and date range.
Get Contact's ErrorsTool to retrieve bounce and error history for a specific contact.
Get Contact's Mailing ListsTool to retrieve all mailing lists associated with a specific contact.
Get Contacts MergesTool to retrieve contacts experiencing merge conflicts with filtering options.
Get Contacts Subscription All ContactsTool to get contacts' subscription status and the source of their status (if known).
Get Contacts Subscription StatusTool to get statistics of contacts' statuses from specific dates.
Get Contacts Subscription UnsubscribersTool to retrieve all contacts who unsubscribed and the source of their unsubscription status.
Get Contacts Unsubscribers SMSTool to retrieve all contacts who unsubscribed from receiving SMS messages.
Get Contacts With SMS StateTool to retrieve account's contacts list with SMS subscription state.
Get Content CategoriesTool to retrieve all content categories from the ActiveTrail account.
Get Customer Stats for Transactional MessageTool to retrieve customer interaction statistics for a specific transactional message.
Get Executive ReportTool to retrieve executive performance reports for the ActiveTrail account.
Get Group DetailsTool to retrieve detailed information about a specific group by its unique identifier.
Get Group by IDTool to retrieve detailed information about a specific group by its unique identifier.
Get Group Contents by IDTool to retrieve all group members by group ID with pagination and filtering.
Get Group Information for ContactTool to retrieve all groups that a specific contact belongs to by contact ID.
Get Group EventsTool to retrieve all events for a specific group with optional filtering by event type, event date, and subscriber creation date.
Get Landing PagesTool to retrieve landing pages from the ActiveTrail account with pagination support.
Get Mailing ListTool to retrieve detailed information about a specific mailing list by its unique identifier.
Get Mailing List MembersTool to retrieve all members belonging to a specific mailing list.
Get Mailing ListsTool to retrieve all mailing lists from the ActiveTrail account.
Get OrderTool to retrieve complete details of a specific order from ActiveTrail commerce system.
Get Push Campaign OpensTool to retrieve contacts who opened a specific push notification campaign.
Get Push Campaign Delivered ReportTool to retrieve contacts who successfully received a specific push notification campaign.
Get Push Campaign Failed Delivery ReportTool to retrieve the failed delivery report for a specific push campaign.
Get Push Campaign ReportsTool to retrieve push notification campaign performance metrics and reports.
Get Push Campaign Sent ReportTool to retrieve contacts who were sent a specific push notification campaign.
Get Push Campaign Report SummaryTool to retrieve summary report information of Push campaigns by dates.
Get Push CampaignsTool to retrieve push notification campaigns with optional filtering by date, campaign ID, and search criteria.
Get Segmentation Rule Field TypesTool to retrieve dictionary of rule field types for segmentation.
Get Segmentation Rule OperationsTool to retrieve dictionary of rule operations for segmentation.
Get Segmentation Rule TypesTool to retrieve dictionary of segmentation rule types for automation.
Get SegmentationsTool to retrieve all segmentations from the ActiveTrail account.
Get Sending ProfilesTool to retrieve account email sending profiles.
Get Signup FormTool to retrieve detailed information about a specific signup form by its unique identifier.
Get Signup FormsTool to retrieve all signup forms from the ActiveTrail account.
Get Smart Code SitesTool to retrieve all Smart Code sites from the ActiveTrail account.
Get SMS Campaign by IDTool to retrieve detailed information about a specific SMS campaign by its unique identifier.
Get SMS Campaign ClickersTool to access link click data for SMS campaigns.
Get SMS Campaign Delivered ReportTool to retrieve delivery confirmations for a specific SMS campaign.
Get SMS Operational Message by IDTool to retrieve operational SMS message details by unique identifier.
Get SMS Campaign Report ClicksTool to retrieve SMS clicks (on links) reports for a specific campaign.
Get SMS Campaign Failed Delivery ReportTool to retrieve the failed delivery report for a specific SMS campaign.
Get SMS Campaign ReportsTool to retrieve SMS campaign performance metrics and reports with filtering options.
Get SMS Campaign Sent Contacts ReportTool to retrieve all contacts that an SMS campaign was sent to.
Get SMS Campaign Report SummaryTool to retrieve summary report information of SMS campaigns by dates.
Get SMS Campaign Unsubscribed ContactsTool to retrieve contacts who unsubscribed from a specific SMS campaign.
Get SMS Sending ProfilesTool to retrieve SMS sending profiles configured for the account.
Get TemplateTool to retrieve detailed information about a specific template from the account's saved templates.
Get Template ContentTool to retrieve HTML content of a specific template.
Get TemplatesTool to retrieve saved templates from the ActiveTrail account.
Get Template CategoriesTool to retrieve all template categories from 'my templates' section.
Get Transactional Messages ClassificationTool to retrieve all classification options for operational/transactional messages.
Get Transactional SMS MessageTool to retrieve detailed information about a specific transactional SMS message by its unique identifier.
Get Two-Way SMS RepliesTool to retrieve virtual number SMS replies with filtering options.
Get Automation Update ActionsTool to retrieve all types of actions that can update a contact in an automation.
Get User Bounces by Campaign IDTool to retrieve specific user details of users that got a bounce by Campaign ID, filtered by bounce type.
Get User Social AccountsTool to retrieve social media accounts connected to the ActiveTrail account.
Get Webhook by IDTool to retrieve detailed information about a specific webhook by its unique identifier.
Get WebhooksTool to list account webhooks with optional filtering.
Get Webhook ParametersTool to retrieve webhook parameters for a specified webhook ID.
Import New ContactsTool to import new contacts into a group in ActiveTrail.
List Landing PagesTool to retrieve landing pages from ActiveTrail.
List Mailing ListsTool to list mailing lists from ActiveTrail account.
List Members Of A Mailing ListTool to get all information of your mailing list members by page, limited to 50 contacts each time.
List Sign-Up FormsTool to retrieve signup forms from the ActiveTrail account.
List SMS CampaignsTool to retrieve SMS campaigns with optional filtering by date, search term, and type.
Get Specific SMS CampaignTool to retrieve a specific SMS campaign by ID including full details like content, status, targeting, and scheduling.
List Transactional SMS MessagesTool to retrieve all SMS transactional messages with pagination support.
Create Campaign from TemplateTool to create a campaign using a specific template.
Create Template CategoryTool to create a new template category in ActiveTrail.
Update Webhook ParameterTool to update a given webhook parameter configuration in your ActiveTrail account.
Send Test Webhook RequestTool to send a test webhook request with configurable URL and parameters.
Update content categoryTool to update a specific content category by ID.
Update Campaign DetailsTool to update campaign details in ActiveTrail.
Update Campaign Segment SettingsTool to update campaign sending settings including groups and sending restrictions.
Remove Contact from Mailing ListTool to remove a contact from a mailing list in ActiveTrail.
Remove external contacts from groupTool to remove contacts from a group via external ID.
Test WebhookTool to send a test request for a given webhook by its ID.
Update CampaignTool to update draft campaigns in ActiveTrail.
Update Campaign DesignTool to update the design and HTML content of an email campaign in ActiveTrail.
Update Campaign SchedulingTool to configure send schedule for draft campaigns.
Update Campaign DetailsTool to update a campaign's details by ID in ActiveTrail.
Update Campaign TemplateTool to update the template associated with an email campaign in ActiveTrail.
Update ContactTool to update an existing contact's information by ID.
Update Contact DetailsTool to update an existing contact's information in ActiveTrail.
Update GroupTool to update an existing group by ID.
Rename GroupTool to rename a group's name in ActiveTrail.
Update OrderTool to modify existing orders in ActiveTrail commerce system.
Update Smart Code SiteTool to update an existing Smart Code site in ActiveTrail.
Update TemplateTool to update an existing template in ActiveTrail account.
Update Template ContentTool to update the HTML content of an email template in ActiveTrail.
Update WebhookTool to update an existing webhook configuration in ActiveTrail.

What is the Composio tool router, and how does it fit here?

What is Tool Router?

Composio's Tool Router helps agents find the right tools for a task at runtime. You can plug in multiple toolkits (like Gmail, HubSpot, and GitHub), and the agent will identify the relevant app and action to complete multi-step workflows. This can reduce token usage and improve the reliability of tool calls. Read more here: Getting started with Tool Router

The tool router generates a secure MCP URL that your agents can access to perform actions.

How the Tool Router works

The Tool Router follows a three-phase workflow:

  1. Discovery: Searches for tools matching your task and returns relevant toolkits with their details.
  2. Authentication: Checks for active connections. If missing, creates an auth config and returns a connection URL via Auth Link.
  3. Execution: Executes the action using the authenticated connection.

Step-by-step Guide

Prerequisites

Before you begin, make sure you have:
  • Node.js and npm installed
  • A Composio account with API key
  • An OpenAI API key

Getting API Keys for OpenAI and Composio

OpenAI API Key
  • Go to the OpenAI dashboard and create an API key. You'll need credits to use the models, or you can connect to another model provider.
  • Keep the API key safe.
Composio API Key
  • Log in to the Composio dashboard.
  • Navigate to your API settings and generate a new API key.
  • Store this key securely as you'll need it for authentication.

Install required dependencies

bash
npm install @ai-sdk/openai @ai-sdk/mcp @composio/core ai dotenv

First, install the necessary packages for your project.

What you're installing:

  • @ai-sdk/openai: Vercel AI SDK's OpenAI provider
  • @ai-sdk/mcp: MCP client for Vercel AI SDK
  • @composio/core: Composio SDK for tool integration
  • ai: Core Vercel AI SDK
  • dotenv: Environment variable management

Set up environment variables

bash
OPENAI_API_KEY=your_openai_api_key_here
COMPOSIO_API_KEY=your_composio_api_key_here
COMPOSIO_USER_ID=your_user_id_here

Create a .env file in your project root.

What's needed:

  • OPENAI_API_KEY: Your OpenAI API key for GPT model access
  • COMPOSIO_API_KEY: Your Composio API key for tool access
  • COMPOSIO_USER_ID: A unique identifier for the user session

Import required modules and validate environment

typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Composio } from "@composio/core";
import * as readline from "readline";
import { streamText, type ModelMessage, stepCountIs } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";

const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!process.env.OPENAI_API_KEY) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({
  apiKey: composioAPIKey,
});
What's happening:
  • We're importing all necessary libraries including Vercel AI SDK's OpenAI provider and Composio
  • The dotenv/config import automatically loads environment variables
  • The MCP client import enables connection to Composio's tool server

Create Tool Router session and initialize MCP client

typescript
async function main() {
  // Create a tool router session for the user
  const session = await composio.create(composioUserID!, {
    toolkits: ["active_trail"],
  });

  const mcpUrl = session.mcp.url;
What's happening:
  • We're creating a Tool Router session that gives your agent access to ActiveTrail tools
  • The create method takes the user ID and specifies which toolkits should be available
  • The returned mcp object contains the URL and authentication headers needed to connect to the MCP server
  • This session provides access to all ActiveTrail-related tools through the MCP protocol

Connect to MCP server and retrieve tools

typescript
const mcpClient = await createMCPClient({
  transport: {
    type: "http",
    url: mcpUrl,
    headers: session.mcp.headers, // Authentication headers for the Composio MCP server
  },
});

const tools = await mcpClient.tools();
What's happening:
  • We're creating an MCP client that connects to our Composio Tool Router session via HTTP
  • The mcp.url provides the endpoint, and mcp.headers contains authentication credentials
  • The type: "http" is important - Composio requires HTTP transport
  • tools() retrieves all available ActiveTrail tools that the agent can use

Initialize conversation and CLI interface

typescript
let messages: ModelMessage[] = [];

console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
console.log(
  "Ask any questions related to active_trail, like summarize my last 5 emails, send an email, etc... :)))\n",
);

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: "> ",
});

rl.prompt();
What's happening:
  • We initialize an empty messages array to maintain conversation history
  • A readline interface is created to accept user input from the command line
  • Instructions are displayed to guide the user on how to interact with the agent

Handle user input and stream responses with real-time tool feedback

typescript
rl.on("line", async (userInput: string) => {
  const trimmedInput = userInput.trim();

  if (["exit", "quit", "bye"].includes(trimmedInput.toLowerCase())) {
    console.log("\nGoodbye!");
    rl.close();
    process.exit(0);
  }

  if (!trimmedInput) {
    rl.prompt();
    return;
  }

  messages.push({ role: "user", content: trimmedInput });
  console.log("\nAgent is thinking...\n");

  try {
    const stream = streamText({
      model: openai("gpt-5"),
      messages,
      tools,
      toolChoice: "auto",
      stopWhen: stepCountIs(10),
      onStepFinish: (step) => {
        for (const toolCall of step.toolCalls) {
          console.log(`[Using tool: ${toolCall.toolName}]`);
          }
          if (step.toolCalls.length > 0) {
            console.log(""); // Add space after tool calls
          }
        },
      });

      for await (const chunk of stream.textStream) {
        process.stdout.write(chunk);
      }

      console.log("\n\n---\n");

      // Get final result for message history
      const response = await stream.response;
      if (response?.messages?.length) {
        messages.push(...response.messages);
      }
    } catch (error) {
      console.error("\nAn error occurred while talking to the agent:");
      console.error(error);
      console.log(
        "\nYou can try again or restart the app if it keeps happening.\n",
      );
    } finally {
      rl.prompt();
    }
  });

  rl.on("close", async () => {
    await mcpClient.close();
    console.log("\nđź‘‹ Session ended.");
    process.exit(0);
  });
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});
What's happening:
  • We use streamText instead of generateText to stream responses in real-time
  • toolChoice: "auto" allows the model to decide when to use ActiveTrail tools
  • stopWhen: stepCountIs(10) allows up to 10 steps for complex multi-tool operations
  • onStepFinish callback displays which tools are being used in real-time
  • We iterate through the text stream to create a typewriter effect as the agent responds
  • The complete response is added to conversation history to maintain context
  • Errors are caught and displayed with helpful retry suggestions

Complete Code

Here's the complete code to get you started with ActiveTrail and Vercel AI SDK:

typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Composio } from "@composio/core";
import * as readline from "readline";
import { streamText, type ModelMessage, stepCountIs } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";

const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!process.env.OPENAI_API_KEY) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({
  apiKey: composioAPIKey,
});

async function main() {
  // Create a tool router session for the user
  const session = await composio.create(composioUserID!, {
    toolkits: ["active_trail"],
  });

  const mcpUrl = session.mcp.url;

  const mcpClient = await createMCPClient({
    transport: {
      type: "http",
      url: mcpUrl,
      headers: session.mcp.headers, // Authentication headers for the Composio MCP server
    },
  });

  const tools = await mcpClient.tools();

  let messages: ModelMessage[] = [];

  console.log("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
  console.log(
    "Ask any questions related to active_trail, like summarize my last 5 emails, send an email, etc... :)))\n",
  );

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: "> ",
  });

  rl.prompt();

  rl.on("line", async (userInput: string) => {
    const trimmedInput = userInput.trim();

    if (["exit", "quit", "bye"].includes(trimmedInput.toLowerCase())) {
      console.log("\nGoodbye!");
      rl.close();
      process.exit(0);
    }

    if (!trimmedInput) {
      rl.prompt();
      return;
    }

    messages.push({ role: "user", content: trimmedInput });
    console.log("\nAgent is thinking...\n");

    try {
      const stream = streamText({
        model: openai("gpt-5"),
        messages,
        tools,
        toolChoice: "auto",
        stopWhen: stepCountIs(10),
        onStepFinish: (step) => {
          for (const toolCall of step.toolCalls) {
            console.log(`[Using tool: ${toolCall.toolName}]`);
          }
          if (step.toolCalls.length > 0) {
            console.log(""); // Add space after tool calls
          }
        },
      });

      for await (const chunk of stream.textStream) {
        process.stdout.write(chunk);
      }

      console.log("\n\n---\n");

      // Get final result for message history
      const response = await stream.response;
      if (response?.messages?.length) {
        messages.push(...response.messages);
      }
    } catch (error) {
      console.error("\nAn error occurred while talking to the agent:");
      console.error(error);
      console.log(
        "\nYou can try again or restart the app if it keeps happening.\n",
      );
    } finally {
      rl.prompt();
    }
  });

  rl.on("close", async () => {
    await mcpClient.close();
    console.log("\nđź‘‹ Session ended.");
    process.exit(0);
  });
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});

Conclusion

You've successfully built a ActiveTrail agent using the Vercel AI SDK with streaming capabilities! This implementation provides a powerful foundation for building AI applications with natural language interfaces and real-time feedback.

Key features of this implementation:

  • Real-time streaming responses for a better user experience with typewriter effect
  • Live tool execution feedback showing which tools are being used as the agent works
  • Dynamic tool loading through Composio's Tool Router with secure authentication
  • Multi-step tool execution with configurable step limits (up to 10 steps)
  • Comprehensive error handling for robust agent execution
  • Conversation history maintenance for context-aware responses

You can extend this further by adding custom error handling, implementing specific business logic, or integrating additional Composio toolkits to create multi-app workflows.

How to build ActiveTrail MCP Agent with another framework

FAQ

What are the differences in Tool Router MCP and ActiveTrail MCP?

With a standalone ActiveTrail MCP server, the agents and LLMs can only access a fixed set of ActiveTrail tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from ActiveTrail and many other apps based on the task at hand, all through a single MCP endpoint.

Can I use Tool Router MCP with Vercel AI SDK v6?

Yes, you can. Vercel AI SDK v6 fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right ActiveTrail tools.

Can I manage the permissions and scopes for ActiveTrail while using Tool Router?

Yes, absolutely. You can configure which ActiveTrail scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your ActiveTrail data and credentials are handled as safely as possible.

Used by agents from

Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai
Context
Letta
glean
HubSpot
Agent.ai
Altera
DataStax
Entelligence
Rolai

Never worry about agent reliability

We handle tool reliability, observability, and security so you never have to second-guess an agent action.