UNPKG

assembly-ai-mcp

Version:

Model Context Protocol server for AssemblyAI transcription services

218 lines 8.33 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const assemblyai_1 = require("assemblyai"); const zod_1 = require("zod"); // Initialize AssemblyAI client const apiKey = process.env.ASSEMBLYAI_API_KEY; if (!apiKey) { console.error("ASSEMBLYAI_API_KEY environment variable is required"); process.exit(1); } const assemblyai = new assemblyai_1.AssemblyAI({ apiKey }); // Create MCP server const server = new mcp_js_1.McpServer({ name: "assemblyai-mcp-server", version: "1.0.0" }); // Zod schemas for input validation const TranscriptionOptionsSchema = zod_1.z.object({ speaker_labels: zod_1.z.boolean().optional(), language_code: zod_1.z.string().optional(), punctuate: zod_1.z.boolean().optional(), format_text: zod_1.z.boolean().optional() }).optional(); // Transcript resource - provides access to transcript content by ID server.registerResource("transcript", new mcp_js_1.ResourceTemplate("transcript://{id}", { list: undefined }), { title: "Transcript Resource", description: "Access AssemblyAI transcript content by ID", mimeType: "application/json" }, async (uri, { id }) => { try { const transcript = await assemblyai.transcripts.get(id); return { contents: [{ uri: uri.href, text: JSON.stringify({ id: transcript.id, status: transcript.status, text: transcript.text, audio_url: transcript.audio_url, confidence: transcript.confidence, words: transcript.words, utterances: transcript.utterances }, null, 2) }] }; } catch (error) { throw new Error(`Failed to get transcript ${id}: ${error instanceof Error ? error.message : String(error)}`); } }); // Tool: Transcribe from URL server.registerTool("transcribe_url", { title: "Transcribe Audio from URL", description: "Transcribe audio from a remote URL using AssemblyAI", inputSchema: { audioUrl: zod_1.z.string().url().describe("The URL of the audio file to transcribe"), options: TranscriptionOptionsSchema.describe("Optional transcription settings") } }, async ({ audioUrl, options = {} }) => { try { const transcript = await assemblyai.transcripts.transcribe({ audio: audioUrl, ...options }); return { content: [{ type: "text", text: `Transcription completed successfully!\n\nTranscript ID: ${transcript.id}\nStatus: ${transcript.status}\nText: ${transcript.text || 'No text available'}\n\nConfidence: ${transcript.confidence || 'N/A'}` }] }; } catch (error) { return { content: [{ type: "text", text: `Error transcribing audio: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }); // Tool: Transcribe from local file server.registerTool("transcribe_file", { title: "Transcribe Local Audio File", description: "Transcribe audio from a local file path using AssemblyAI", inputSchema: { filePath: zod_1.z.string().describe("The local file path of the audio file to transcribe"), options: TranscriptionOptionsSchema.describe("Optional transcription settings") } }, async ({ filePath, options = {} }) => { try { const transcript = await assemblyai.transcripts.transcribe({ audio: filePath, ...options }); return { content: [{ type: "text", text: `Transcription completed successfully!\n\nTranscript ID: ${transcript.id}\nStatus: ${transcript.status}\nText: ${transcript.text || 'No text available'}\n\nConfidence: ${transcript.confidence || 'N/A'}` }] }; } catch (error) { return { content: [{ type: "text", text: `Error transcribing file: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }); // Tool: Submit transcription (async, returns immediately) server.registerTool("submit_transcription", { title: "Submit Audio for Transcription", description: "Submit audio for transcription without waiting for completion", inputSchema: { audio: zod_1.z.string().describe("The URL or local file path of the audio to transcribe"), options: TranscriptionOptionsSchema.describe("Optional transcription settings") } }, async ({ audio, options = {} }) => { try { const transcript = await assemblyai.transcripts.submit({ audio, ...options }); return { content: [{ type: "text", text: `Transcription job submitted successfully!\n\nTranscript ID: ${transcript.id}\nStatus: ${transcript.status}\n\nUse the get_transcript tool with ID ${transcript.id} to check progress and get results.` }] }; } catch (error) { return { content: [{ type: "text", text: `Error submitting transcription: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }); // Tool: Get transcript by ID server.registerTool("get_transcript", { title: "Get Transcript by ID", description: "Retrieve transcription results by transcript ID", inputSchema: { transcriptId: zod_1.z.string().describe("The transcript ID to retrieve") } }, async ({ transcriptId }) => { try { const transcript = await assemblyai.transcripts.get(transcriptId); let statusMessage = ''; switch (transcript.status) { case 'completed': statusMessage = 'Transcription completed successfully!'; break; case 'processing': statusMessage = 'Transcription is still processing...'; break; case 'queued': statusMessage = 'Transcription is queued for processing...'; break; case 'error': statusMessage = `Transcription failed: ${transcript.error || 'Unknown error'}`; break; default: statusMessage = `Status: ${transcript.status}`; } return { content: [{ type: "text", text: `${statusMessage}\n\nTranscript ID: ${transcript.id}\nStatus: ${transcript.status}\nText: ${transcript.text || 'No text available yet'}\nConfidence: ${transcript.confidence || 'N/A'}\nAudio URL: ${transcript.audio_url || 'N/A'}` }] }; } catch (error) { return { content: [{ type: "text", text: `Error retrieving transcript: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }); // Connect to stdio transport and start the server async function main() { const transport = new stdio_js_1.StdioServerTransport(); // Handle graceful shutdown process.on('SIGINT', async () => { console.error('Received SIGINT, shutting down gracefully...'); await transport.close(); process.exit(0); }); process.on('SIGTERM', async () => { console.error('Received SIGTERM, shutting down gracefully...'); await transport.close(); process.exit(0); }); try { await server.connect(transport); console.error('AssemblyAI MCP Server started successfully'); } catch (error) { console.error('Failed to start server:', error); process.exit(1); } } main().catch((error) => { console.error('Server error:', error); process.exit(1); }); //# sourceMappingURL=index.js.map