How to integrate Crowdin MCP with Vercel AI SDK v6

Trusted by
AWS
Glean
Zoom
Airtable

30 min · no commitment · see it on your stack

Crowdin logo
Vercel AI SDK logo
divider

Introduction

This guide walks you through connecting Crowdin to Vercel AI SDK v6 using the Composio tool router. By the end, you'll have a working Crowdin agent that can create a new crowdin project for our app, add new source file to the translations project, assign sprint label to specific string ids through natural language commands.

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

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

Also integrate Crowdin with

TL;DR

Here's what you'll learn:
  • How to set up and configure a Vercel AI SDK agent with Crowdin integration
  • Using Composio's Tool Router to dynamically load and access Crowdin 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 Crowdin MCP server, and what's possible with it?

The Crowdin MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Crowdin account. It provides structured and secure access to your localization projects, so your agent can manage branches, organize files, label content, automate webhooks, and orchestrate translation workflows on your behalf.

  • Branch and project management: Easily have your agent create, delete, or organize Crowdin projects and branches to streamline new releases or features.
  • Dynamic file handling: Let your agent add new files to projects, ensuring your translation assets are always up to date and properly organized by branch or directory.
  • Labeling and content categorization: Direct your agent to create, assign, or remove labels on resources and strings, helping you segment and track translation tasks with precision.
  • Workflow automation with webhooks: Automate your translation process by having the agent set up or remove webhooks for real-time notifications and integrations.
  • Resource cleanup and maintenance: Empower your agent to delete obsolete branches, labels, webhooks, or entire projects, keeping your Crowdin workspace clean and focused.

Supported Tools & Triggers

Tools
Add BranchTool to create a new branch in a Crowdin project.
Add DirectoryTool to create a new directory in a Crowdin project.
Add FileTool to add a new file to a Crowdin project.
Add Glossary TermTool to add a new term to a Crowdin glossary.
Add LabelTool to create a new label in a Crowdin project.
Create Crowdin ProjectTool to create a new project in Crowdin.
Add Project File Format SettingsTool to add file format settings to a Crowdin project.
Add WebhookTool to create a new webhook in a Crowdin project.
Assign Label to StringsAssign a label to one or more source strings in a Crowdin project.
Build Project Directory TranslationTool to build translations for a specific directory in a Crowdin project.
Build Project File TranslationTool to build a project file translation in Crowdin.
Build Project TranslationTool to build project translation in Crowdin, generating downloadable translation files.
Cancel Project Translation BuildTool to cancel a project translation build in Crowdin.
Check Bundle Export StatusTool to check the status of a bundle export operation in Crowdin.
Check Glossary Export StatusTool to check the status of a glossary export operation.
Check Glossary Import StatusTool to check the status of a glossary import operation.
Check GraphQL Rate LimitTool to check GraphQL API rate limit status for Crowdin.
Check Project Report StatusTool to check report generation status in a Crowdin project.
Check Project Build StatusTool to check the status of a project translation build in Crowdin.
Check TM Export StatusTool to check Translation Memory export status in Crowdin.
Check TM Import StatusTool to check Translation Memory import status in Crowdin.
Check AI Report StatusTool to check the generation status of an AI report for a Crowdin user.
Clone AI PromptTool to clone an existing AI prompt in Crowdin.
Create GlossaryTool to create a new glossary in Crowdin.
Import GlossaryTool to import glossary terms from a file into a Crowdin glossary.
Create Custom LanguageTool to create a custom language in Crowdin.
Create MT TranslationsTool to translate strings using Crowdin's Machine Translation engine.
Create Project CommentTool to add a comment or issue to a string or file (asset) in a Crowdin project.
Add Project MemberTool to add members to a Crowdin project.
Add BundleTool to add a new bundle to a Crowdin project.
Add DistributionTool to create a new distribution in a Crowdin project.
Create Report Settings TemplateTool to create a report settings template in Crowdin.
Create Project Strings Exporter SettingsTool to add project strings exporter settings in Crowdin.
Create Project TaskTool to create a new task in a Crowdin project.
Create StringTool to add a new source string to a Crowdin project.
Create TM ImportTool to import a Translation Memory file into Crowdin.
Add Translation MemoryTool to create a new Translation Memory (TM) in Crowdin.
Create TM SegmentsTool to create translation memory segments in Crowdin.
Create TM Segment RecordsTool to create translation memory segment records in Crowdin.
Create Translation AlignmentTool to create translation alignment for a project.
Create AI PromptTool to create a new AI prompt in Crowdin.
Add AI SnippetTool to create an AI snippet in Crowdin.
Create User Report Settings TemplateTool to create a user report settings template in Crowdin.
Delete BranchTool to delete a specific branch from a Crowdin project.
Delete DirectoryTool to delete a specific directory from a Crowdin project.
Delete FileTool to delete a specific file from a Crowdin project.
Delete GlossaryTool to delete a glossary from Crowdin.
Delete Glossary ConceptTool to delete a concept from a Crowdin glossary.
Delete Glossary TermTool to delete a term from a Crowdin glossary.
Delete Glossary TermsTool to clear terms from a Crowdin glossary.
Delete LabelTool to delete the label identified by the specified label ID in a project.
Delete Custom LanguageTool to delete a custom language from Crowdin.
Delete ProjectTool to delete a Crowdin project by its ID.
Delete Project Comment AttachmentTool to delete an attachment from a string or asset comment in a Crowdin project.
Delete Project MemberTool to delete a member from a Crowdin project.
Delete BundleTool to delete a bundle from a Crowdin project.
Delete DistributionTool to delete a distribution from a Crowdin project.
Delete Project File Format SettingsTool to delete file format settings from a Crowdin project.
Delete Report Settings TemplateTool to delete a report settings template from a Crowdin project.
Delete ScreenshotTool to delete a screenshot from a Crowdin project.
Delete Project Strings Exporter SettingsTool to delete project strings exporter settings in Crowdin.
Delete Task Settings TemplateTool to delete a task settings template from a Crowdin project.
Delete Project TaskTool to delete a specific task from a Crowdin project.
Delete Project Task CommentTool to delete a specific comment from a project task.
Delete StorageTool to delete a storage from Crowdin.
Delete StringTool to delete a specific source string from a Crowdin project.
Delete Translation MemoryTool to delete a Translation Memory (TM) from Crowdin.
Delete TM SegmentTool to delete a specific translation memory segment from Crowdin.
Clear TM SegmentsTool to clear all segments from a Translation Memory in Crowdin.
Delete TM Segment RecordTool to delete a translation memory segment record in Crowdin.
Delete User AI PromptTool to delete an AI prompt for a specific user.
Delete User AI ProviderTool to delete an AI provider for a specific user.
Delete AI SnippetTool to delete an AI snippet from Crowdin.
Delete User Report Settings TemplateTool to delete a user report settings template from Crowdin.
Delete WebhookPermanently deletes a webhook from a Crowdin project.
Download FileTool to download a file from a Crowdin project.
Download Glossary ExportTool to download an exported glossary from Crowdin.
Download Bundle ExportTool to download an exported bundle from Crowdin.
Download Project ReportTool to download a generated project report from Crowdin.
Download Project Translation BuildTool to download a built project translation from Crowdin.
Download TM ExportTool to download an exported Translation Memory from Crowdin.
Download AI ReportTool to download an AI report from Crowdin.
Edit FileTool to update file details in a project.
Edit LabelTool to edit a label's title in a Crowdin project.
Edit ProjectTool to update project details using JSON-Patch.
Edit StringEdit a source string in a Crowdin project using JSON Patch operations.
Execute GraphQL QueryTool to execute GraphQL queries against the Crowdin GraphQL API.
Export GlossaryTool to initiate a glossary export operation in Crowdin.
Export BundleTool to initiate an asynchronous export operation for a bundle in Crowdin.
Export Project TranslationsTool to export project translations from Crowdin.
Export Project Task StringsTool to export strings from a project task in XLIFF format.
Export Translation MemoryTool to export Translation Memory (TM) from Crowdin.
Generate Project ReportTool to generate organization reports in Crowdin projects.
Generate AI Prompt Fine-Tuning DatasetTool to generate an AI prompt fine-tuning dataset from project or TM data.
Get BranchTool to retrieve details of a specific branch in a Crowdin project by its ID.
Get FileTool to retrieve detailed information about a specific file in a Crowdin project.
Get GlossaryTool to retrieve information about a specific glossary by its ID.
Get Glossary ConceptTool to retrieve a specific concept from a Crowdin glossary.
Get Glossary TermTool to retrieve a specific term from a Crowdin glossary.
Get LabelTool to retrieve information about the label identified by the specified label ID in a project.
Get LanguageTool to retrieve details of a specific language.
Get Member InfoTool to retrieve information about a project member.
Get MTTool to retrieve details of a specific Machine Translation engine.
Get ProjectTool to retrieve details of a specific Crowdin project.
Get Project AI SettingsTool to retrieve AI settings for a specific Crowdin project.
Get Branch ProgressTool to retrieve branch translation progress for all languages in a Crowdin project.
Get BundleTool to retrieve details of a specific bundle from a Crowdin project.
Get String/Asset CommentTool to retrieve a specific string or asset comment by its ID in a Crowdin project.
Get DirectoryTool to retrieve information about a specific directory in a Crowdin project.
Get Directory ProgressTool to get translation progress for all languages in a specific directory of a Crowdin project.
Get DistributionTool to retrieve details of a specific distribution in a Crowdin project.
Get Project File Format SettingsTool to retrieve file format settings for a specific project.
Get File ProgressTool to retrieve file translation progress for all languages in a Crowdin project.
Get File RevisionTool to retrieve details of a specific file revision in a Crowdin project.
Get Project ProgressTool to retrieve project translation progress for all languages in a Crowdin project.
Get Language ProgressTool to retrieve translation progress for a specific language across all files in a Crowdin project.
Get QA Checks Revalidation StatusTool to retrieve the status of a QA checks revalidation job.
Get Report Settings TemplateTool to retrieve a specific report settings template from Crowdin.
Get Project Strings Exporter SettingsTool to retrieve project strings exporter settings by ID.
Get Task Settings TemplateTool to retrieve a specific task settings template from a Crowdin project.
Get Project TaskTool to retrieve details of a specific task in a Crowdin project.
Get Project Task CommentTool to retrieve a specific task comment by its ID in a Crowdin project.
Get StorageTool to retrieve details of a specific file uploaded to Crowdin storage.
Get StringRetrieves detailed information about a specific source string in a Crowdin project.
Get Translation MemoryTool to retrieve information about a specific Translation Memory by its ID.
Get Authenticated UserTool to retrieve information about the currently authenticated user.
Get AI PromptTool to retrieve a specific AI prompt from Crowdin.
Get AI Prompt Fine-Tuning Dataset StatusTool to retrieve the generation status of an AI prompt fine-tuning dataset.
Get User AI ProviderTool to retrieve an AI provider for a specific user.
Get User AI SettingsTool to retrieve AI settings for a Crowdin user.
Get AI SnippetTool to retrieve an AI snippet from Crowdin.
Get User Report ArchiveTool to get a specific report archive for a Crowdin user.
Get User Report Settings TemplateTool to retrieve a user report settings template in Crowdin.
Get User Security LogTool to retrieve details of a specific security log entry for a user.
Get ViewerTool to retrieve information about the authenticated user via GraphQL.
Get WebhookRetrieves detailed information about a specific webhook in a Crowdin project.
List Application InstallationsList all application installations in Crowdin with pagination and filtering support.
List BranchesList all branches in a Crowdin project.
List FilesTool to list files in a Crowdin project.
List GlossariesTool to list all glossaries available to the authenticated user.
List Glossaries ConceptsTool to list concepts in a Crowdin glossary with pagination and sorting support.
List Glossary TermsTool to list all terms in a Crowdin glossary.
List Project File Strings (GraphQL)Tool to list source strings within files in Crowdin projects using GraphQL API.
List LabelsLists all labels in a Crowdin project with pagination support.
List LanguagesTool to retrieve a list of supported languages.
List MTsTool to retrieve a paginated list of Machine Translation engines.
List Project MembersTool to list members in a Crowdin project.
List Projects (v2)List all Crowdin projects accessible to the authenticated user with advanced filtering and sorting options.
List Projects ApprovalsTool to list translation approvals in a Crowdin project with filtering and pagination.
List BundlesRetrieves a paginated list of bundles in a Crowdin project.
List Bundle FilesTool to list files in a specific Crowdin project bundle.
List Project CommentsTool to retrieve a paginated list of comments on strings or assets in a Crowdin project.
List Project DictionariesTool to list all dictionaries in a Crowdin project.
List DirectoriesList all directories in a Crowdin project.
List DistributionsTool to retrieve a list of distributions for a Crowdin project.
List Project File Format SettingsTool to list all file format settings for a Crowdin project.
List Asset ReferencesTool to list asset references for a specific file in a Crowdin project.
List File RevisionsTool to list all revisions for a specific file in a Crowdin project.
List Projects IssuesTool to list reported issues in a Crowdin project.
List Language TranslationsTool to list language translations for a specific project and language.
List Projects QA ChecksTool to list QA check issues in a Crowdin project with pagination and filtering support.
List Report Settings TemplatesTool to list report settings templates for a Crowdin project.
List ScreenshotsTool to list screenshots in a Crowdin project.
List Project StringsLists all source strings in a Crowdin project with filtering and pagination.
List Project Strings Exporter SettingsTool to list project strings exporter settings in Crowdin.
List Task Settings TemplatesTool to retrieve a paginated list of task settings templates for a Crowdin project.
List Project BuildsTool to list translation builds for a Crowdin project.
List Translation VotesTool to list translation votes in a Crowdin project.
List Project WebhooksTool to retrieve a paginated list of webhooks configured in a Crowdin project.
List Project Task CommentsTool to retrieve all comments on a specific project task.
List StoragesTool to list files uploaded to Crowdin storage with pagination.
List TasksTool to list tasks in a Crowdin project.
List Translation MemoriesTool to list all Translation Memories available to the authenticated user.
List TM SegmentsTool to list Translation Memory segments in Crowdin.
List User AI PromptsTool to list AI prompts for a specific user in Crowdin.
List AI Prompt Fine-Tuning JobsTool to list AI prompt fine-tuning jobs for a specific user.
List User AI ProvidersTool to list all AI providers configured for a specific user.
List User AI Provider ModelsTool to list AI provider models configured for a specific user.
List Supported AI Provider ModelsTool to list supported AI provider models for a user.
List AI SnippetsTool to list AI snippets for a specific user in Crowdin.
List User Report ArchivesTool to list report archives for a Crowdin user.
List User Report Settings TemplatesTool to list user report settings templates in Crowdin.
List User Security LogsTool to list security log entries for a specific user.
List User TasksTool to retrieve a paginated list of tasks assigned to a specific user.
List User TasksTool to retrieve tasks assigned to the authenticated user across all projects.
List Viewer Projects FilesTool to list files within projects using GraphQL viewer query.
List Translations By LanguageTool to retrieve translation information for strings in specific target languages.
List Viewer Projects (GraphQL)Tool to retrieve projects via Crowdin GraphQL API using viewer.
List Viewer Projects TranslationsTool to list translations for projects in a specific language using GraphQL viewer query.
Notify Project MembersTool to send notifications to Crowdin project members.
Query GraphQL NodeTool to query Crowdin GraphQL Project nodes by their global ID.
Release DistributionTool to release a distribution in a Crowdin project.
Reset Project File Format Settings Custom SegmentationsTool to reset custom segmentations for file format settings in a Crowdin project.
Revalidate QA ChecksTool to revalidate QA checks for a Crowdin project.
Search Glossaries ConcordanceTool to search for glossary terms using concordance search in Crowdin.
Search TM ConcordanceTool to search for translations in Translation Memory (TM) using concordance search.
Send NotificationTool to send a notification message to the authenticated Crowdin user.
Update GlossariesTool to update glossary details using JSON-Patch operations.
Update Glossary ConceptTool to update a concept in a Crowdin glossary.
Update Glossary TermTool to update an existing glossary term in Crowdin using JSON Patch operations.
Update Custom LanguageTool to update a custom language in Crowdin using JSON-Patch operations.
Edit String/Asset CommentTool to edit a string or asset comment in a Crowdin project using JSON Patch operations.
Update BranchTool to update branch details using JSON-Patch operations.
Update BundleTool to update bundle properties in a Crowdin project using JSON-Patch operations.
Update Projects CommentsTool to perform batch operations on project comments using JSON-Patch.
Update Project DictionariesTool to edit a dictionary in a Crowdin project using JSON-Patch operations.
Update DirectoryTool to update directory details in a Crowdin project using JSON-Patch operations.
Edit DistributionTool to update distribution settings using JSON-Patch operations.
Update Project File Format SettingsTool to edit file format settings in a Crowdin project using JSON Patch operations.
Update or Restore FileTool to update or restore a file in a Crowdin project.
Update Report Settings TemplateTool to update a report settings template using JSON-Patch operations.
Edit ScreenshotTool to edit a screenshot in a Crowdin project using JSON Patch operations.
Edit Screenshot TagTool to edit a screenshot tag in a Crowdin project using JSON Patch operations.
Update Projects StringsTool to perform batch operations on strings in a Crowdin project using JSON Patch.
Update Project Strings Exporter SettingsTool to edit project strings exporter settings in Crowdin using JSON Patch operations.
Update Task Settings TemplateTool to update a task settings template in a Crowdin project using JSON Patch operations.
Update Project WebhookTool to update webhook configuration in a Crowdin project using JSON Patch operations.
Update Project TaskTool to update a project task in Crowdin using JSON Patch operations.
Edit Project Task CommentTool to edit a task comment in a Crowdin project using JSON Patch operations.
Update Translation MemoryTool to update a Translation Memory (TM) in Crowdin using JSON Patch operations.
Update TM SegmentsTool to edit a translation memory segment in Crowdin using JSON Patch operations.
Update Authenticated UserTool to update the authenticated user's profile using JSON Patch operations.
Update AI PromptTool to update an AI prompt in Crowdin using JSON-Patch operations.
Update User AI ProviderTool to edit an AI Provider for a specific user using JSON Patch operations.
Edit User AI SettingsTool to update AI settings for a Crowdin user using JSON Patch operations.
Update AI SnippetTool to update an existing AI snippet in Crowdin using JSON Patch operations.
Update User Report Settings TemplateTool to update a user report settings template in Crowdin using JSON Patch operations.
Update Organization WebhookTool to update organization webhook configuration in Crowdin using JSON Patch operations.
Upload StorageUpload a file to Crowdin storage to get a storage ID for subsequent operations.
Validate QA ChecksTool to validate translation text by QA checks in a Crowdin project.

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

What is Composio SDK?

Composio's Composio SDK 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 Composio SDK

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

How the Composio SDK works

The Composio SDK 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: ["crowdin"],
  });

  const mcpUrl = session.mcp.url;
What's happening:
  • We're creating a Tool Router session that gives your agent access to Crowdin 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 Crowdin-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 Crowdin 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 crowdin, 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 Crowdin 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 Crowdin 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: ["crowdin"],
  });

  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 crowdin, 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 Crowdin 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 Crowdin MCP Agent with another framework

FAQ

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

With a standalone Crowdin MCP server, the agents and LLMs can only access a fixed set of Crowdin tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Crowdin 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 Crowdin tools.

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

Yes, absolutely. You can configure which Crowdin 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 Crowdin 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.