How to integrate Youtube MCP with LlamaIndex

This guide walks you through connecting Youtube to LlamaIndex using the Composio tool router. By the end, you'll have a working Youtube agent that can list your most recent uploaded videos, get subscriber count for your channel, search youtube for trending tutorials through natural language commands. This guide will help you understand how to give your LlamaIndex agent real control over a Youtube account through Composio's Youtube MCP server. Before we dive in, let's take a quick look at the key ideas and tools involved.

Youtube logoYoutube
Oauth2

YouTube is a leading video-sharing platform for uploading, streaming, and discovering content. It empowers creators and businesses to reach global audiences and monetize their work.

47 Tools4 Triggers

Introduction

This guide walks you through connecting Youtube to LlamaIndex using the Composio tool router. By the end, you'll have a working Youtube agent that can list your most recent uploaded videos, get subscriber count for your channel, search youtube for trending tutorials through natural language commands.

This guide will help you understand how to give your LlamaIndex agent real control over a Youtube account through Composio's Youtube MCP server.

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

Also integrate Youtube with

TL;DR

Here's what you'll learn:
  • Set your OpenAI and Composio API keys
  • Install LlamaIndex and Composio packages
  • Create a Composio Tool Router session for Youtube
  • Connect LlamaIndex to the Youtube MCP server
  • Build a Youtube-powered agent using LlamaIndex
  • Interact with Youtube through natural language

What is LlamaIndex?

LlamaIndex is a data framework for building LLM applications. It provides tools for connecting LLMs to external data sources and services through agents and tools.

Key features include:

  • ReAct Agent: Reasoning and acting pattern for tool-using agents
  • MCP Tools: Native support for Model Context Protocol
  • Context Management: Maintain conversation context across interactions
  • Async Support: Built for async/await patterns

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

The Youtube MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Youtube account. It provides structured and secure access to your channel data, so your agent can perform actions like searching videos, managing playlists, retrieving channel insights, and handling subscriptions on your behalf.

  • Channel activity monitoring: Let your agent fetch and summarize recent channel activities, including uploads, likes, playlist additions, and more, to keep you up to date at a glance.
  • Automated video and playlist management: Easily list videos from any channel, retrieve your own playlists, and organize your content—all through AI-driven commands.
  • Channel analytics and statistics: Ask your agent to pull detailed channel metrics such as subscriber counts, total views, or video counts for quick reporting and insights.
  • Subscription management: Have your agent list your current subscriptions or even subscribe you to new channels based on your interests or instructions.
  • Search and caption handling: Empower your agent to search YouTube for videos, channels, or playlists, as well as retrieve and download caption tracks for accessible viewing and content repurposing.

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

Step by step10 STEPS
1

Prerequisites

Before you begin, make sure you have:
  • Python 3.8/Node 16 or higher installed
  • A Composio account with the API key
  • An OpenAI API key
  • A Youtube account and project
  • Basic familiarity with async Python/Typescript
2

Getting API Keys for OpenAI, Composio, and Youtube

OpenAI API key (OPENAI_API_KEY)
  • Go to the OpenAI dashboard
  • Create an API key if you don't have one
  • Assign it to OPENAI_API_KEY in .env
Composio API key and user ID
  • Log into the Composio dashboard
  • Copy your API key from Settings
    • Use this as COMPOSIO_API_KEY
  • Pick a stable user identifier (email or ID)
    • Use this as COMPOSIO_USER_ID
3

Installing dependencies

npm install @composio/llamaindex @llamaindex/openai @llamaindex/tools @llamaindex/workflow dotenv

Create a new Typescript project and install the necessary dependencies:

  • @composio/llamaindex: Composio's LlamaIndex integration
  • @llamaindex/openai: OpenAI LLM integration
  • @llamaindex/tools: MCP client for LlamaIndex
  • @llamaindex/workflow: Workflow framework for LlamaIndex
  • dotenv: Environment variable management
4

Set environment variables

bash
OPENAI_API_KEY=your-openai-api-key
COMPOSIO_API_KEY=your-composio-api-key
COMPOSIO_USER_ID=your-user-id

Create a .env file in your project root:

These credentials will be used to:

  • Authenticate with OpenAI's GPT-5 model
  • Connect to Composio's Tool Router
  • Identify your Composio user session for Youtube access
5

Import modules

import "dotenv/config";
import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

import { Composio } from "@composio/core";

import { mcp } from "@llamaindex/tools";
import { agent as createAgent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";

dotenv.config();

Create a new file called youtube_llamaindex_agent.ts and import the required modules:

Key imports:

  • dotenv.config loads .env at runtime
  • readline gives us a simple CLI chat loop
  • Composio is the main Composio SDK client
  • mcp connects to an MCP endpoint
  • createAgent builds a LlamaIndex agent
  • openai configures the LLM backend
6

Load environment variables and initialize Composio

const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const COMPOSIO_API_KEY = process.env.COMPOSIO_API_KEY;
const COMPOSIO_USER_ID = process.env.COMPOSIO_USER_ID;

if (!OPENAI_API_KEY) throw new Error("OPENAI_API_KEY is not set");
if (!COMPOSIO_API_KEY) throw new Error("COMPOSIO_API_KEY is not set");
if (!COMPOSIO_USER_ID) throw new Error("COMPOSIO_USER_ID is not set");

What's happening:

This ensures missing credentials cause early, clear errors before the agent attempts to initialise.

7

Create a Tool Router session and build the agent function

async function buildAgent() {

  console.log(`Initializing Composio client...${COMPOSIO_USER_ID!}...`);
  console.log(`COMPOSIO_USER_ID: ${COMPOSIO_USER_ID!}...`);

  const composio = new Composio({
    apiKey: COMPOSIO_API_KEY,
    provider: new LlamaindexProvider(),
  });

  const session = await composio.create(
    COMPOSIO_USER_ID!,
    {
      toolkits: ["youtube"],
    },
  );

  const mcpUrl = session.mcp.url;
  console.log(`Composio Tool Router MCP URL: ${mcpUrl}`);

  const server = mcp({
    url: mcpUrl,
    clientName: "composio_tool_router_with_llamaindex",
    requestInit: {
      headers: {
        "x-api-key": COMPOSIO_API_KEY!,
      },
    },
    // verbose: true,
  });

  const tools = await server.tools();

  const llm = openai({ apiKey: OPENAI_API_KEY, model: "gpt-5" });

  const agent = createAgent({
    name: "composio_tool_router_with_llamaindex",
        description : "An agent that uses Composio Tool Router MCP tools to perform actions.",
    systemPrompt:
      "You are a helpful assistant connected to Composio Tool Router."+
"Use the available tools to answer user queries and perform Youtube actions." ,
    llm,
    tools,
  });

  return agent;
}

What's happening here:

  • We create a Composio client using your API key and configure it with the LlamaIndex provider
  • We then create a tool router MCP session for your user, specifying the toolkits we want to use (in this case, youtube)
  • The session returns an MCP HTTP endpoint URL that acts as a gateway to all your configured tools
  • LlamaIndex will connect to this endpoint to dynamically discover and use the available Youtube tools.
  • The MCP tools are mapped to LlamaIndex-compatible tools and plug them into the Agent.
8

Create an interactive chat loop

async function chatLoop(agent: ReturnType<typeof createAgent>) {
  const rl = readline.createInterface({ input, output });

  console.log("Type 'quit' or 'exit' to stop.");

  while (true) {
    let userInput: string;

    try {
      userInput = (await rl.question("\nYou: ")).trim();
    } catch {
      console.log("\nAgent: Bye!");
      break;
    }

    if (!userInput) {
      continue;
    }

    const lower = userInput.toLowerCase();
    if (lower === "quit" || lower === "exit") {
      console.log("Agent: Bye!");
      break;
    }

    try {
      process.stdout.write("Agent: ");

      const stream = agent.runStream(userInput);
      let finalResult: any = null;

      for await (const event of stream) {
        // The event.data contains the streamed content
        const data: any = event.data;

        // Check for streaming delta content
        if (data?.delta) {
          process.stdout.write(data.delta);
        }

        // Store final result for fallback
        if (data?.result || data?.message) {
          finalResult = data;
        }
      }

      // If no streaming happened, show the final result
      if (finalResult) {
        const answer =
          finalResult.result ??
          finalResult.message?.content ??
          finalResult.message ??
          "";
        if (answer && typeof answer === "string" && !answer.includes("[object")) {
          process.stdout.write(answer);
        }
      }

      console.log(); // New line after streaming completes
    } catch (err: any) {
      console.error("\nAgent error:", err?.message ?? err);
    }
  }

  rl.close();
}

What's happening:

  • We're creating a direct terminal interface to chat with Youtube
  • The LLM's responses are streamed to the CLI for faster interaction.
  • The agent uses context to maintain conversation history
  • The agent processes the request, selects appropriate Youtube tools, and returns a result
  • We extract the answer from the result data structure and display it to the user
  • You can type 'quit' or 'exit' to stop the chat loop gracefully
  • Agent responses and any errors are streamed in a clear, readable format
9

Define the main entry point

async function main() {
  try {
    const agent = await buildAgent();
    await chatLoop(agent);
  } catch (err) {
    console.error("Failed to start agent:", err);
    process.exit(1);
  }
}

main();

What's happening here:

  • We're orchestrating the entire application flow
  • The agent gets built with proper error handling
  • Then we kick off the interactive chat loop so you can start talking to Youtube
10

Run the agent

npx ts-node llamaindex-agent.ts

When prompted, authenticate and authorise your agent with Youtube, then start asking questions.

Complete Code

Here's the complete code to get you started with Youtube and LlamaIndex:

import "dotenv/config";
import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

import { Composio } from "@composio/core";
import { LlamaindexProvider } from "@composio/llamaindex";

import { mcp } from "@llamaindex/tools";
import { agent as createAgent } from "@llamaindex/workflow";
import { openai } from "@llamaindex/openai";

dotenv.config();

const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const COMPOSIO_API_KEY = process.env.COMPOSIO_API_KEY;
const COMPOSIO_USER_ID = process.env.COMPOSIO_USER_ID;

if (!OPENAI_API_KEY) {
    throw new Error("OPENAI_API_KEY is not set in the environment");
  }
if (!COMPOSIO_API_KEY) {
    throw new Error("COMPOSIO_API_KEY is not set in the environment");
  }
if (!COMPOSIO_USER_ID) {
    throw new Error("COMPOSIO_USER_ID is not set in the environment");
  }

async function buildAgent() {

  console.log(`Initializing Composio client...${COMPOSIO_USER_ID!}...`);
  console.log(`COMPOSIO_USER_ID: ${COMPOSIO_USER_ID!}...`);

  const composio = new Composio({
    apiKey: COMPOSIO_API_KEY,
    provider: new LlamaindexProvider(),
  });

  const session = await composio.create(
    COMPOSIO_USER_ID!,
    {
      toolkits: ["youtube"],
    },
  );

  const mcpUrl = session.mcp.url;
  console.log(`Composio Tool Router MCP URL: ${mcpUrl}`);

  const server = mcp({
    url: mcpUrl,
    clientName: "composio_tool_router_with_llamaindex",
    requestInit: {
      headers: {
        "x-api-key": COMPOSIO_API_KEY!,
      },
    },
    // verbose: true,
  });

  const tools = await server.tools();

  const llm = openai({ apiKey: OPENAI_API_KEY, model: "gpt-5" });

  const agent = createAgent({
    name: "composio_tool_router_with_llamaindex",
    description:
      "An agent that uses Composio Tool Router MCP tools to perform actions.",
    systemPrompt:
      "You are a helpful assistant connected to Composio Tool Router."+
"Use the available tools to answer user queries and perform Youtube actions." ,
    llm,
    tools,
  });

  return agent;
}

async function chatLoop(agent: ReturnType<typeof createAgent>) {
  const rl = readline.createInterface({ input, output });

  console.log("Type 'quit' or 'exit' to stop.");

  while (true) {
    let userInput: string;

    try {
      userInput = (await rl.question("\nYou: ")).trim();
    } catch {
      console.log("\nAgent: Bye!");
      break;
    }

    if (!userInput) {
      continue;
    }

    const lower = userInput.toLowerCase();
    if (lower === "quit" || lower === "exit") {
      console.log("Agent: Bye!");
      break;
    }

    try {
      process.stdout.write("Agent: ");

      const stream = agent.runStream(userInput);
      let finalResult: any = null;

      for await (const event of stream) {
        // The event.data contains the streamed content
        const data: any = event.data;

        // Check for streaming delta content
        if (data?.delta) {
          process.stdout.write(data.delta);
        }

        // Store final result for fallback
        if (data?.result || data?.message) {
          finalResult = data;
        }
      }

      // If no streaming happened, show the final result
      if (finalResult) {
        const answer =
          finalResult.result ??
          finalResult.message?.content ??
          finalResult.message ??
          "";
        if (answer && typeof answer === "string" && !answer.includes("[object")) {
          process.stdout.write(answer);
        }
      }

      console.log(); // New line after streaming completes
    } catch (err: any) {
      console.error("\nAgent error:", err?.message ?? err);
    }
  }

  rl.close();
}

async function main() {
  try {
    const agent = await buildAgent();
    await chatLoop(agent);
  } catch (err: any) {
    console.error("Failed to start agent:", err?.message ?? err);
    process.exit(1);
  }
}

main();

Conclusion

You've successfully connected Youtube to LlamaIndex through Composio's Tool Router MCP layer. Key takeaways:
  • Tool Router dynamically exposes Youtube tools through an MCP endpoint
  • LlamaIndex's ReActAgent handles reasoning and orchestration; Composio handles integrations
  • The agent becomes more capable without increasing prompt size
  • Async Python provides clean, efficient execution of agent workflows
You can easily extend this to other toolkits like Gmail, Notion, Stripe, GitHub, and more by adding them to the toolkits parameter.
TOOLS & TRIGGERS

Supported Tools and Triggers

Every Youtube action and event your agent gets out of the box.

Add Video to Playlist

Tool to add a video to a playlist by inserting a playlist item.

Insert Channel Section

Tool to create a new channel section for the authenticated user's YouTube channel.

Insert Comment Reply

Tool to create a reply to an existing YouTube comment.

Create Playlist

Tool to create a new YouTube playlist on the authenticated user's channel.

Delete Channel Section

Tool to delete a YouTube channel section.

Delete Comment

Tool to delete a YouTube comment owned by the authenticated user or channel.

Delete Playlist

Tool to delete a YouTube playlist owned by the authenticated user/channel.

Delete Playlist Item

Tool to delete a playlist item (remove a video from a playlist).

Delete Video

Tool to delete a YouTube video owned by the authenticated user/channel.

Get Channel Activities

Gets recent activities from a YouTube channel including video uploads, playlist additions, likes, and other channel events.

Get channel ID by handle

Retrieves the YouTube Channel ID for a specific YouTube channel handle.

Get Channel Statistics

Gets detailed statistics for YouTube channels including subscriber counts, view counts, and video counts.

Video Details Batch

Retrieves multiple YouTube video resource parts in a single batch call.

Get Video Rating

Retrieves the ratings that the authorized user gave to a list of specified videos.

List captions

Retrieves a list of caption tracks for a YouTube video.

List Channel Sections

Tool to retrieve channel sections from YouTube.

List channel videos

Lists videos from a specified YouTube channel.

List Comments

List individual comments from YouTube videos.

List Comment Threads

Tool to retrieve comment threads from YouTube videos or channels matching API request parameters.

List I18n Languages

Returns a list of application languages that the YouTube website supports.

List I18n Regions

Tool to retrieve a list of content regions that the YouTube website supports.

List Live Chat Messages

Tool to list live chat messages for a specific chat.

List Playlist Images

Tool to retrieve playlist images associated with a specific playlist.

List Playlist Items

Tool to list videos in a playlist, with pagination support.

List Super Chat Events

Lists Super Chat events for a channel, showing supporter purchases during live streams.

List user playlists

Retrieves playlists owned by the authenticated user, implicitly using mine=True.

List user subscriptions

Retrieves the authenticated user's YouTube channel subscriptions, allowing specification of response parts and pagination.

List Video Abuse Report Reasons

Tool to retrieve a list of abuse report reasons that can be used to report abusive videos on YouTube.

List Video Categories

Tool to list YouTube video categories that can be associated with videos.

Download YouTube caption track

Downloads a specific YouTube caption track, which must be owned by the authenticated user, and returns its content as text.

Multipart upload video

Uploads a video to YouTube using multipart upload in a single request.

Post Comment on Video

Tool to post a new top-level comment on a YouTube video.

Rate Video

Tool to add a like or dislike rating to a YouTube video, or remove an existing rating.

Report Video for Abuse

Tool to report a YouTube video for containing abusive content.

Search YouTube

Searches YouTube for videos, channels, or playlists using a query term, returning the raw API response.

Set Comment Moderation Status

Tool to set the moderation status of one or more YouTube comments.

Subscribe to channel

Subscribes the authenticated user to a specified YouTube channel, identified by its unique `channelId` which must be valid and existing.

Unsubscribe from channel

Tool to unsubscribe the authenticated user from a YouTube channel by deleting a subscription.

Update caption track

Updates a YouTube caption track's metadata such as name, language, or draft status.

Update channel

Updates a channel's metadata including branding settings and localizations.

Update Channel Section

Tool to update an existing YouTube channel section by ID.

Update Comment

Tool to modify the text of an existing YouTube comment.

Update Playlist

Tool to modify an existing YouTube playlist's metadata (title, description, privacy status).

Update Playlist Item

Tool to modify a playlist item's properties such as position or note.

Update thumbnail

Sets the custom thumbnail for a YouTube video using an image from a URL.

Update video

Updates metadata for a YouTube video identified by videoId, which must exist; an empty list for tags removes all existing tags.

Upload video

Uploads a video from a local file path to a YouTube channel; the video file must be in a YouTube-supported format.

FAQ

Frequently asked questions

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

Yes, you can. LlamaIndex 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 Youtube tools.

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

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 Youtube data and credentials are handled as safely as possible.

Start with Youtube.It takes 30 seconds.

Managed auth, hosted MCP servers, and every Youtube tool your agent needs.Free to start.

Start building