# Stage 1: Build stage FROM node:22-alpine AS build WORKDIR /app RUN apk add --no-cache git RUN git clone https://github.com/ZubeidHendricks/youtube-mcp-server.git . RUN npm install RUN npm run build # Stage 2: Runtime stage FROM node:22-alpine AS runtime WORKDIR /app ENV NODE_ENV=production ENV MCP_TRANSPORT=http ENV MCP_HOST=0.0.0.0 ENV MCP_PORT=8088 ENV MCP_STATELESS=true COPY --from=build /app/package*.json ./ RUN npm install --omit=dev && npm cache clean --force COPY --from=build /app/dist ./dist # Create the Advanced Security & Transcript Bypass Gateway RUN cat << 'EOF' > /app/proxy.cjs const http = require('http'); const url = require('url'); const TARGET_PORT = 8088; const PROXY_PORT = 7860; const AUTH_TOKEN = process.env.ACCESS_TOKEN; if (!AUTH_TOKEN) { console.error("CRITICAL ERROR: ACCESS_TOKEN secret environment variable is missing!"); process.exit(1); } // Bypasses HF data center block using a dedicated public edge-cached transcript API async function fetchTranscript(videoId) { try { const res = await fetch(`https://youtube-transcript.ai/transcript/${videoId}.txt`); if (!res.ok) { throw new Error(`Bypass endpoint responded with status ${res.status}`); } const text = await res.text(); if (!text || text.trim().length === 0) { throw new Error("Bypass endpoint returned an empty transcript."); } return text.trim(); } catch (err) { throw new Error(`All bypass routes blocked: ${err.message}`); } } const server = http.createServer((req, res) => { const parsedUrl = url.parse(req.url, true); if (parsedUrl.pathname === '/ready') { const proxyReq = http.request({ host: '127.0.0.1', port: TARGET_PORT, path: req.url, method: req.method, headers: req.headers }, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); proxyReq.on('error', () => { res.writeHead(502); res.end(); }); proxyReq.end(); return; } // Authenticate using Header or URL Query Parameter const customHeader = req.headers['x-access-token']; const authHeader = req.headers['authorization']; const queryToken = parsedUrl.query.token; const isCustomHeaderValid = customHeader === AUTH_TOKEN; const isHeaderValid = authHeader === `Bearer ${AUTH_TOKEN}`; const isQueryValid = queryToken === AUTH_TOKEN; if (!isCustomHeaderValid && !isHeaderValid && !isQueryValid) { res.writeHead(401, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: "Unauthorized: Invalid or missing access token." })); return; } // Intercept POST requests to check for the transcript tool call if (req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk; }); req.on('end', async () => { try { const json = JSON.parse(body); if (json.method === 'tools/call' && json.params && json.params.name === 'transcripts_getTranscript') { const videoId = json.params.arguments.videoId; try { const text = await fetchTranscript(videoId); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ jsonrpc: "2.0", result: { content: [{ type: "text", text: text }], isError: false }, id: json.id })); return; } catch (err) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ jsonrpc: "2.0", result: { content: [{ type: "text", text: `Error: Failed to bypass data-center block: ${err.message}` }], isError: true }, id: json.id })); return; } } forwardBody(req, res, body); } catch (e) { forwardBody(req, res, body); } }); } else { const proxyReq = http.request({ host: '127.0.0.1', port: TARGET_PORT, path: req.url, method: req.method, headers: req.headers }, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); proxyReq.on('error', () => { res.writeHead(502); res.end(); }); req.pipe(proxyReq); } }); function forwardBody(req, res, body) { const proxyReq = http.request({ host: '127.0.0.1', port: TARGET_PORT, path: req.url, method: req.method, headers: req.headers }, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); proxyReq.on('error', () => { res.writeHead(502); res.end(); }); proxyReq.write(body); proxyReq.end(); } server.listen(PROXY_PORT, '0.0.0.0', () => { console.log(`Security & Transcript Bypass Gateway active on port ${PROXY_PORT}.`); }); EOF EXPOSE 7860 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 CMD node -e "fetch('http://127.0.0.1:7860/ready').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))" CMD ["sh", "-c", "node ./dist/index.js & node /app/proxy.cjs"]