# YouTube MCP Server – Copilot Agent Instructions
## Overview
This project is an XMCP (Extended Model Context Protocol) server for YouTube integration. It exposes YouTube-related tools as structured MCP endpoints, using the XMCP framework for automatic tool discovery. All tools are auto-registered from `src/tools/` and exposed via HTTP on port 3002.
## Architecture & Key Patterns
### Tool Structure (Auto-Discovery)
Each tool in `src/tools/` follows this exact pattern:
```typescript
import { z } from "zod";
import { type InferSchema } from "xmcp";
export const schema = {
query: z.string().describe("Search query"),
maxResults: z.number().min(1).max(50).default(10).describe("Max results (1-50)")
};
export const metadata = {
name: "search_youtube",
description: "Search YouTube for videos",
annotations: {
title: "Search YouTube",
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
}
};
There is no entry point per say for the tools, they are loaded dynamically by the XMCP server from the "src/tools/" directory.
export default async function search_youtube({ query, maxResults }: InferSchema<typeof schema>) {
// Tool logic here
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
}
```
### Dual YouTube API Strategy
- **Innertube (`youtubei.js`)**: Primary API for transcripts, detailed video info. Use `withCache()` wrapper from `youtube-client.ts`
- **YouTube Data API v3**: Fallback for search/metadata. Use `youtubeApiRequest()` from `youtube-api.ts` (requires `YOUTUBE_API_KEY`)
- **Anti-Detection**: `youtube-client.ts` implements user agent rotation, realistic headers, random delays, and proxy support
### Authentication & Security
- API key auth via `x-api-key` header (see `src/middleware.ts`)
- Token validation against Supabase using SHA-256 hashes (`src/utils/token-auth.ts`)
- **Environment Variables**: `YOUTUBE_API_KEY` for Data API, Supabase config for auth
## Developer Workflows
### Essential Commands
- **Dev Server**: `pnpm dev` (hot reload on port 3002)
- **Production Build**: `pnpm build` → `dist/`
- **Run Built Server**: `pnpm start` (or `node dist/http.js`)
- **Test Suite**: `pnpm test` (integration tests via JSON-RPC calls)
### Testing Pattern
Tests in `test/youtube-mcp.test.js` make actual HTTP requests to running server:
```javascript
const response = await callTool('search_youtube', { query: 'test', maxResults: 5 });
// Validates JSON-RPC responses and tool behavior
```
### Error Handling & Logging
- **Logs**: Use `console.error()` (stderr) to avoid polluting MCP protocol
- **User Errors**: Throw descriptive errors; XMCP handles formatting
- **API Failures**: Graceful degradation between Innertube and Data API
## Project-Specific Conventions
### Parameter Validation
- All tools use Zod schemas with `.describe()` for auto-documentation
- Enforce realistic limits: `maxResults: z.number().min(1).max(50)`
- Default values in schema, not function parameters
### Response Format
Always return: `{ content: [{ type: "text", text: string }] }`
- Use `JSON.stringify(result, null, 2)` for structured data
- No markdown formatting in responses
### Caching Strategy
Use `withCache(cacheKey, async () => {...})` from `youtube-client.ts` for expensive operations
## Key Files & Integration Points
- `src/tools/` – Auto-discovered tool implementations
- `src/utils/youtube-client.ts` – Innertube setup with anti-detection
- `src/utils/youtube-api.ts` – YouTube Data API v3 wrapper
- `src/middleware.ts` – API key authentication
- `xmcp.config.ts` – Server configuration (port 3002)
- `test/youtube-mcp.test.js` – Integration test patterns
## Dependencies
- `xmcp` – MCP server framework with auto tool discovery
- `youtubei.js` – Unofficial YouTube API (primary)
- `zod` – Schema validation and documentation
- `https-proxy-agent` – Proxy support for rate limiting