require('dotenv').config();
const fetch = require('node-fetch');
const DEFAULT_URL = 'http://127.0.0.1:3002/mcp';
const MCP_URL = process.env.MCP_URL || DEFAULT_URL;
async function callTool(name, args = {}) {
const body = {
jsonrpc: '2.0',
id: Math.floor(Math.random() * 100000),
method: 'tools/call',
params: { name, arguments: args }
};
const res = await fetch(MCP_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': process.env.YOUTUBE_MCP_API_KEY || 'test-key'
},
body: JSON.stringify(body)
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
return res.json();
}
function parseToolResponse(resp, toolName) {
if (resp.error) {
throw new Error(`Tool ${toolName} returned error: ${resp.error.message}`);
}
const text = resp.result?.content?.[0]?.text;
if (!text) {
throw new Error(`Tool ${toolName} returned no content`);
}
// Check if it's a YouTube API error by looking for common error patterns
if (text.includes('YouTube API error') || text.includes('403 Forbidden')) {
try {
const errorObj = JSON.parse(text);
throw new Error(`YouTube API key issue: ${errorObj.message}. Please check your YOUTUBE_API_KEY in .env file.`);
} catch (parseError) {
throw new Error(`YouTube API key issue: ${text}. Please check your YOUTUBE_API_KEY in .env file.`);
}
}
try {
return JSON.parse(text);
} catch (parseError) {
throw new Error(`Tool ${toolName} returned invalid JSON: ${text.substring(0, 100)}...`);
}
}
async function ensureServer() {
try {
const health = await fetch(MCP_URL.replace('/mcp', ''));
if (!health.ok) throw new Error('Server not healthy');
} catch (e) {
throw new Error(`Cannot connect to server at ${MCP_URL}. Start it with: npm run dev`);
}
}
module.exports = { callTool, parseToolResponse, ensureServer, MCP_URL };