mcp-ts-template 2.2.5 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -117536,7 +117536,7 @@ var ErrorSchema = z.object({
117536
117536
  // package.json
117537
117537
  var package_default = {
117538
117538
  name: "mcp-ts-template",
117539
- version: "2.2.4",
117539
+ version: "2.2.7",
117540
117540
  mcpName: "io.github.cyanheads/mcp-ts-template",
117541
117541
  description: "The definitive, production-grade template for building powerful and scalable Model Context Protocol (MCP) servers with TypeScript, featuring built-in observability (OpenTelemetry), declarative tooling, robust error handling, and a modular, DI-driven architecture.",
117542
117542
  main: "dist/index.js",
@@ -117619,9 +117619,10 @@ var package_default = {
117619
117619
  jose: "^6.1.0",
117620
117620
  "js-yaml": "^4.1.0",
117621
117621
  "node-cron": "^4.2.1",
117622
- openai: "^5.23.1",
117622
+ openai: "^6.0.0",
117623
117623
  papaparse: "^5.5.3",
117624
117624
  "partial-json": "^0.1.7",
117625
+ "pdf-lib": "^1.17.1",
117625
117626
  pino: "^9.12.0",
117626
117627
  "reflect-metadata": "^0.2.2",
117627
117628
  repomix: "^1.6.0",
@@ -117665,7 +117666,7 @@ var package_default = {
117665
117666
  "pino-pretty": "^13.1.1",
117666
117667
  prettier: "^3.6.2",
117667
117668
  typedoc: "^0.28.13",
117668
- typescript: "^5.9.2",
117669
+ typescript: "^5.9.3",
117669
117670
  "typescript-eslint": "8.45.0",
117670
117671
  vite: "^7.1.7",
117671
117672
  "vite-tsconfig-paths": "^5.1.4",
@@ -117848,7 +117849,26 @@ var ConfigSchema = z.object({
117848
117849
  }
117849
117850
  return str;
117850
117851
  }, z.enum(["NONE", "ERROR", "WARN", "INFO", "DEBUG", "VERBOSE", "ALL"])).default("INFO")
117851
- })
117852
+ }),
117853
+ speech: z.object({
117854
+ tts: z.object({
117855
+ enabled: z.coerce.boolean().default(false),
117856
+ provider: z.enum(["elevenlabs"]).default("elevenlabs"),
117857
+ apiKey: z.string().optional(),
117858
+ baseUrl: z.string().url().optional(),
117859
+ defaultVoiceId: z.string().optional(),
117860
+ defaultModelId: z.string().optional(),
117861
+ timeout: z.coerce.number().optional()
117862
+ }).optional(),
117863
+ stt: z.object({
117864
+ enabled: z.coerce.boolean().default(false),
117865
+ provider: z.enum(["openai-whisper"]).default("openai-whisper"),
117866
+ apiKey: z.string().optional(),
117867
+ baseUrl: z.string().url().optional(),
117868
+ defaultModelId: z.string().optional(),
117869
+ timeout: z.coerce.number().optional()
117870
+ }).optional()
117871
+ }).optional()
117852
117872
  });
117853
117873
  var parseConfig = () => {
117854
117874
  const env = process.env;
@@ -117915,6 +117935,25 @@ var parseConfig = () => {
117915
117935
  samplingRatio: env.OTEL_TRACES_SAMPLER_ARG,
117916
117936
  logLevel: env.OTEL_LOG_LEVEL
117917
117937
  },
117938
+ speech: env.SPEECH_TTS_ENABLED || env.SPEECH_STT_ENABLED ? {
117939
+ tts: env.SPEECH_TTS_ENABLED ? {
117940
+ enabled: env.SPEECH_TTS_ENABLED,
117941
+ provider: env.SPEECH_TTS_PROVIDER,
117942
+ apiKey: env.SPEECH_TTS_API_KEY,
117943
+ baseUrl: env.SPEECH_TTS_BASE_URL,
117944
+ defaultVoiceId: env.SPEECH_TTS_DEFAULT_VOICE_ID,
117945
+ defaultModelId: env.SPEECH_TTS_DEFAULT_MODEL_ID,
117946
+ timeout: env.SPEECH_TTS_TIMEOUT
117947
+ } : undefined,
117948
+ stt: env.SPEECH_STT_ENABLED ? {
117949
+ enabled: env.SPEECH_STT_ENABLED,
117950
+ provider: env.SPEECH_STT_PROVIDER,
117951
+ apiKey: env.SPEECH_STT_API_KEY,
117952
+ baseUrl: env.SPEECH_STT_BASE_URL,
117953
+ defaultModelId: env.SPEECH_STT_DEFAULT_MODEL_ID,
117954
+ timeout: env.SPEECH_STT_TIMEOUT
117955
+ } : undefined
117956
+ } : undefined,
117918
117957
  mcpServerName: env.MCP_SERVER_NAME,
117919
117958
  mcpServerVersion: env.MCP_SERVER_VERSION,
117920
117959
  mcpServerDescription: env.MCP_SERVER_DESCRIPTION
@@ -119310,6 +119349,7 @@ var CreateMcpServerInstance = Symbol("CreateMcpServerInstance");
119310
119349
  var RateLimiterService = Symbol("RateLimiterService");
119311
119350
  var TransportManagerToken = Symbol("TransportManager");
119312
119351
  var SupabaseAdminClient = Symbol("SupabaseAdminClient");
119352
+ var SpeechService = Symbol("SpeechService");
119313
119353
 
119314
119354
  // src/utils/security/rateLimiter.ts
119315
119355
  class RateLimiter {
@@ -119510,10 +119550,10 @@ async function fetchWithTimeout(url, timeoutMs, context, options) {
119510
119550
 
119511
119551
  // src/container/index.ts
119512
119552
  var import_reflect_metadata = __toESM(require_Reflect(), 1);
119513
- var import_tsyringe17 = __toESM(require_cjs3(), 1);
119553
+ var import_tsyringe19 = __toESM(require_cjs3(), 1);
119514
119554
 
119515
119555
  // src/container/registrations/core.ts
119516
- var import_tsyringe6 = __toESM(require_cjs3(), 1);
119556
+ var import_tsyringe8 = __toESM(require_cjs3(), 1);
119517
119557
  var import_supabase_js2 = __toESM(require_main6(), 1);
119518
119558
 
119519
119559
  // node_modules/openai/internal/tslib.mjs
@@ -119744,7 +119784,7 @@ var safeJSON = (text) => {
119744
119784
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
119745
119785
 
119746
119786
  // node_modules/openai/version.mjs
119747
- var VERSION = "5.23.1";
119787
+ var VERSION = "6.0.0";
119748
119788
 
119749
119789
  // node_modules/openai/internal/detect-platform.mjs
119750
119790
  var isRunningInBrowser = () => {
@@ -125145,8 +125185,378 @@ OpenRouterProvider = __legacyDecorateClassTS([
125145
125185
  ])
125146
125186
  ], OpenRouterProvider);
125147
125187
 
125148
- // src/storage/core/StorageService.ts
125188
+ // src/services/speech/providers/elevenlabs.provider.ts
125149
125189
  var import_tsyringe3 = __toESM(require_cjs3(), 1);
125190
+ class ElevenLabsProvider {
125191
+ name = "elevenlabs";
125192
+ supportsTTS = true;
125193
+ supportsSTT = false;
125194
+ apiKey;
125195
+ baseUrl;
125196
+ defaultVoiceId;
125197
+ defaultModelId;
125198
+ timeout;
125199
+ constructor(config2) {
125200
+ if (!config2.apiKey) {
125201
+ throw new McpError(-32602 /* InvalidParams */, "ElevenLabs API key is required");
125202
+ }
125203
+ this.apiKey = config2.apiKey;
125204
+ this.baseUrl = config2.baseUrl || "https://api.elevenlabs.io/v1";
125205
+ this.defaultVoiceId = config2.defaultVoiceId || "EXAVITQu4vr4xnSDxMaL";
125206
+ this.defaultModelId = config2.defaultModelId || "eleven_monolingual_v1";
125207
+ this.timeout = config2.timeout || 30000;
125208
+ logger.info(`ElevenLabs TTS provider initialized: ${this.baseUrl}, voice=${this.defaultVoiceId}`);
125209
+ }
125210
+ async textToSpeech(options) {
125211
+ const context = requestContextService.createRequestContext({
125212
+ operation: "elevenlabs-tts",
125213
+ ...options.context || {}
125214
+ });
125215
+ const voiceId = options.voice?.voiceId || this.defaultVoiceId;
125216
+ const modelId = options.modelId || this.defaultModelId;
125217
+ logger.debug("Converting text to speech with ElevenLabs", context);
125218
+ if (!options.text || options.text.trim().length === 0) {
125219
+ throw new McpError(-32602 /* InvalidParams */, "Text cannot be empty", context);
125220
+ }
125221
+ if (options.text.length > 5000) {
125222
+ throw new McpError(-32602 /* InvalidParams */, "Text exceeds maximum length of 5000 characters", context);
125223
+ }
125224
+ const url = `${this.baseUrl}/text-to-speech/${voiceId}`;
125225
+ const voiceSettings = {
125226
+ stability: options.voice?.stability ?? 0.5,
125227
+ similarity_boost: options.voice?.similarityBoost ?? 0.75,
125228
+ style: options.voice?.style ?? 0,
125229
+ use_speaker_boost: true
125230
+ };
125231
+ const requestBody = {
125232
+ text: options.text,
125233
+ model_id: modelId,
125234
+ voice_settings: voiceSettings
125235
+ };
125236
+ try {
125237
+ const response = await fetchWithTimeout(url, this.timeout, context, {
125238
+ method: "POST",
125239
+ headers: {
125240
+ "Content-Type": "application/json",
125241
+ "xi-api-key": this.apiKey
125242
+ },
125243
+ body: JSON.stringify(requestBody)
125244
+ });
125245
+ if (!response.ok) {
125246
+ const errorText = await response.text();
125247
+ logger.error(`ElevenLabs API error: ${response.status}`, context);
125248
+ throw new McpError(-32603 /* InternalError */, `ElevenLabs API error: ${response.status} - ${errorText}`, context);
125249
+ }
125250
+ const audioBuffer = Buffer.from(await response.arrayBuffer());
125251
+ logger.info(`Text-to-speech conversion successful (voice=${voiceId}, ${audioBuffer.length} bytes)`, context);
125252
+ return {
125253
+ audio: audioBuffer,
125254
+ format: "mp3",
125255
+ characterCount: options.text.length,
125256
+ metadata: {
125257
+ voiceId,
125258
+ modelId,
125259
+ provider: this.name
125260
+ }
125261
+ };
125262
+ } catch (error2) {
125263
+ if (error2 instanceof McpError) {
125264
+ throw error2;
125265
+ }
125266
+ logger.error("Failed to convert text to speech", error2 instanceof Error ? error2 : new Error(String(error2)), context);
125267
+ throw new McpError(-32603 /* InternalError */, `Failed to convert text to speech: ${error2 instanceof Error ? error2.message : "Unknown error"}`, context);
125268
+ }
125269
+ }
125270
+ speechToText(_options) {
125271
+ throw new McpError(-32601 /* MethodNotFound */, "Speech-to-text is not supported by ElevenLabs provider");
125272
+ }
125273
+ async getVoices() {
125274
+ const context = requestContextService.createRequestContext({
125275
+ operation: "elevenlabs-getVoices"
125276
+ });
125277
+ logger.debug("Fetching available voices from ElevenLabs", context);
125278
+ const url = `${this.baseUrl}/voices`;
125279
+ try {
125280
+ const response = await fetchWithTimeout(url, this.timeout, context, {
125281
+ method: "GET",
125282
+ headers: {
125283
+ "xi-api-key": this.apiKey
125284
+ }
125285
+ });
125286
+ if (!response.ok) {
125287
+ const errorText = await response.text();
125288
+ logger.error(`Failed to fetch voices: ${response.status}`, context);
125289
+ throw new McpError(-32603 /* InternalError */, `Failed to fetch voices: ${response.status} - ${errorText}`);
125290
+ }
125291
+ const data = await response.json();
125292
+ const voices = data.voices.map((v) => ({
125293
+ id: v.voice_id,
125294
+ name: v.name,
125295
+ ...v.description !== undefined && { description: v.description },
125296
+ ...v.category !== undefined && { category: v.category },
125297
+ ...v.preview_url !== undefined && { previewUrl: v.preview_url },
125298
+ ...v.labels?.gender !== undefined && {
125299
+ gender: v.labels.gender
125300
+ },
125301
+ metadata: {
125302
+ labels: v.labels
125303
+ }
125304
+ }));
125305
+ logger.info(`Successfully fetched ${voices.length} voices`, context);
125306
+ return voices;
125307
+ } catch (error2) {
125308
+ if (error2 instanceof McpError) {
125309
+ throw error2;
125310
+ }
125311
+ logger.error("Failed to fetch voices", error2 instanceof Error ? error2 : new Error(String(error2)), context);
125312
+ throw new McpError(-32603 /* InternalError */, `Failed to fetch voices: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
125313
+ }
125314
+ }
125315
+ async healthCheck() {
125316
+ try {
125317
+ await this.getVoices();
125318
+ return true;
125319
+ } catch (error2) {
125320
+ const context = requestContextService.createRequestContext({
125321
+ operation: "elevenlabs-healthCheck"
125322
+ });
125323
+ logger.error("ElevenLabs health check failed", error2 instanceof Error ? error2 : new Error(String(error2)), context);
125324
+ return false;
125325
+ }
125326
+ }
125327
+ }
125328
+ ElevenLabsProvider = __legacyDecorateClassTS([
125329
+ import_tsyringe3.injectable(),
125330
+ __legacyMetadataTS("design:paramtypes", [
125331
+ typeof SpeechProviderConfig === "undefined" ? Object : SpeechProviderConfig
125332
+ ])
125333
+ ], ElevenLabsProvider);
125334
+
125335
+ // src/services/speech/providers/whisper.provider.ts
125336
+ var import_tsyringe4 = __toESM(require_cjs3(), 1);
125337
+ class WhisperProvider {
125338
+ name = "openai-whisper";
125339
+ supportsTTS = false;
125340
+ supportsSTT = true;
125341
+ apiKey;
125342
+ baseUrl;
125343
+ defaultModelId;
125344
+ timeout;
125345
+ constructor(config2) {
125346
+ if (!config2.apiKey) {
125347
+ throw new McpError(-32602 /* InvalidParams */, "OpenAI API key is required");
125348
+ }
125349
+ this.apiKey = config2.apiKey;
125350
+ this.baseUrl = config2.baseUrl || "https://api.openai.com/v1";
125351
+ this.defaultModelId = config2.defaultModelId || "whisper-1";
125352
+ this.timeout = config2.timeout || 60000;
125353
+ logger.info(`OpenAI Whisper STT provider initialized: ${this.baseUrl}, model=${this.defaultModelId}`);
125354
+ }
125355
+ textToSpeech(_options) {
125356
+ throw new McpError(-32601 /* MethodNotFound */, "Text-to-speech is not supported by Whisper provider");
125357
+ }
125358
+ async speechToText(options) {
125359
+ const context = requestContextService.createRequestContext({
125360
+ operation: "whisper-stt",
125361
+ ...options.context || {}
125362
+ });
125363
+ const modelId = options.modelId || this.defaultModelId;
125364
+ logger.debug("Converting speech to text with Whisper", context);
125365
+ if (!options.audio) {
125366
+ throw new McpError(-32602 /* InvalidParams */, "Audio data is required", context);
125367
+ }
125368
+ let audioBuffer;
125369
+ if (typeof options.audio === "string") {
125370
+ try {
125371
+ audioBuffer = Buffer.from(options.audio, "base64");
125372
+ } catch (_error) {
125373
+ throw new McpError(-32602 /* InvalidParams */, "Invalid base64 audio data", context);
125374
+ }
125375
+ } else {
125376
+ audioBuffer = options.audio;
125377
+ }
125378
+ const maxSize = 25 * 1024 * 1024;
125379
+ if (audioBuffer.length > maxSize) {
125380
+ throw new McpError(-32602 /* InvalidParams */, `Audio file exceeds maximum size of 25MB (got ${Math.round(audioBuffer.length / 1024 / 1024)}MB)`, context);
125381
+ }
125382
+ const url = `${this.baseUrl}/audio/transcriptions`;
125383
+ const formData = new FormData;
125384
+ const extension = this.getFileExtension(options.format);
125385
+ const blob = new Blob([audioBuffer], {
125386
+ type: this.getMimeType(options.format)
125387
+ });
125388
+ formData.append("file", blob, `audio.${extension}`);
125389
+ formData.append("model", modelId);
125390
+ if (options.language) {
125391
+ formData.append("language", options.language);
125392
+ }
125393
+ if (options.temperature !== undefined) {
125394
+ formData.append("temperature", options.temperature.toString());
125395
+ }
125396
+ if (options.prompt) {
125397
+ formData.append("prompt", options.prompt);
125398
+ }
125399
+ formData.append("response_format", options.timestamps ? "verbose_json" : "json");
125400
+ if (options.timestamps) {
125401
+ formData.append("timestamp_granularities[]", "word");
125402
+ }
125403
+ try {
125404
+ const response = await fetchWithTimeout(url, this.timeout, context, {
125405
+ method: "POST",
125406
+ headers: {
125407
+ Authorization: `Bearer ${this.apiKey}`
125408
+ },
125409
+ body: formData
125410
+ });
125411
+ if (!response.ok) {
125412
+ const errorText = await response.text();
125413
+ logger.error(`Whisper API error: ${response.status}`, context);
125414
+ throw new McpError(-32603 /* InternalError */, `Whisper API error: ${response.status} - ${errorText}`, context);
125415
+ }
125416
+ const data = await response.json();
125417
+ const words = data.words?.map((w) => ({
125418
+ word: w.word,
125419
+ start: w.start,
125420
+ end: w.end
125421
+ }));
125422
+ logger.info(`Speech-to-text transcription successful (${data.text.length} chars)`, context);
125423
+ return {
125424
+ text: data.text,
125425
+ ...data.language !== undefined && { language: data.language },
125426
+ ...data.duration !== undefined && { duration: data.duration },
125427
+ ...words !== undefined && { words },
125428
+ metadata: {
125429
+ modelId,
125430
+ provider: this.name,
125431
+ ...data.task !== undefined && { task: data.task }
125432
+ }
125433
+ };
125434
+ } catch (error2) {
125435
+ if (error2 instanceof McpError) {
125436
+ throw error2;
125437
+ }
125438
+ logger.error("Failed to transcribe audio", error2 instanceof Error ? error2 : new Error(String(error2)), context);
125439
+ throw new McpError(-32603 /* InternalError */, `Failed to transcribe audio: ${error2 instanceof Error ? error2.message : "Unknown error"}`, context);
125440
+ }
125441
+ }
125442
+ getVoices() {
125443
+ throw new McpError(-32601 /* MethodNotFound */, "Voice listing is not supported by Whisper provider (STT only)");
125444
+ }
125445
+ async healthCheck() {
125446
+ try {
125447
+ const context = requestContextService.createRequestContext({
125448
+ operation: "whisper-healthCheck"
125449
+ });
125450
+ const response = await fetchWithTimeout(`${this.baseUrl}/models`, 5000, context, {
125451
+ method: "GET",
125452
+ headers: {
125453
+ Authorization: `Bearer ${this.apiKey}`
125454
+ }
125455
+ });
125456
+ return response.ok;
125457
+ } catch (error2) {
125458
+ const context = requestContextService.createRequestContext({
125459
+ operation: "whisper-healthCheck"
125460
+ });
125461
+ logger.error("Whisper health check failed", error2 instanceof Error ? error2 : new Error(String(error2)), context);
125462
+ return false;
125463
+ }
125464
+ }
125465
+ getFileExtension(format) {
125466
+ const formatMap = {
125467
+ mp3: "mp3",
125468
+ wav: "wav",
125469
+ ogg: "ogg",
125470
+ flac: "flac",
125471
+ webm: "webm",
125472
+ m4a: "m4a"
125473
+ };
125474
+ return format && formatMap[format] ? formatMap[format] : "mp3";
125475
+ }
125476
+ getMimeType(format) {
125477
+ const mimeMap = {
125478
+ mp3: "audio/mpeg",
125479
+ wav: "audio/wav",
125480
+ ogg: "audio/ogg",
125481
+ flac: "audio/flac",
125482
+ webm: "audio/webm",
125483
+ m4a: "audio/mp4"
125484
+ };
125485
+ return format && mimeMap[format] ? mimeMap[format] : "audio/mpeg";
125486
+ }
125487
+ }
125488
+ WhisperProvider = __legacyDecorateClassTS([
125489
+ import_tsyringe4.injectable(),
125490
+ __legacyMetadataTS("design:paramtypes", [
125491
+ typeof SpeechProviderConfig === "undefined" ? Object : SpeechProviderConfig
125492
+ ])
125493
+ ], WhisperProvider);
125494
+
125495
+ // src/services/speech/index.ts
125496
+ function createSpeechProvider(config2) {
125497
+ logger.debug(`Creating speech provider: ${config2.provider}`);
125498
+ switch (config2.provider) {
125499
+ case "elevenlabs":
125500
+ return new ElevenLabsProvider(config2);
125501
+ case "openai-whisper":
125502
+ return new WhisperProvider(config2);
125503
+ case "mock":
125504
+ throw new McpError(-32602 /* InvalidParams */, "Mock provider not yet implemented");
125505
+ default: {
125506
+ const _exhaustive = config2.provider;
125507
+ throw new McpError(-32602 /* InvalidParams */, `Unknown speech provider: ${String(_exhaustive)}`);
125508
+ }
125509
+ }
125510
+ }
125511
+
125512
+ class SpeechService2 {
125513
+ ttsProvider;
125514
+ sttProvider;
125515
+ constructor(ttsConfig, sttConfig) {
125516
+ if (ttsConfig) {
125517
+ this.ttsProvider = createSpeechProvider(ttsConfig);
125518
+ if (!this.ttsProvider.supportsTTS) {
125519
+ logger.warning(`TTS provider ${ttsConfig.provider} does not support text-to-speech`);
125520
+ }
125521
+ }
125522
+ if (sttConfig) {
125523
+ this.sttProvider = createSpeechProvider(sttConfig);
125524
+ if (!this.sttProvider.supportsSTT) {
125525
+ logger.warning(`STT provider ${sttConfig.provider} does not support speech-to-text`);
125526
+ }
125527
+ }
125528
+ logger.info(`Speech service initialized: TTS=${this.ttsProvider?.name ?? "none"}, STT=${this.sttProvider?.name ?? "none"}`);
125529
+ }
125530
+ getTTSProvider() {
125531
+ if (!this.ttsProvider) {
125532
+ throw new McpError(-32600 /* InvalidRequest */, "No TTS provider configured");
125533
+ }
125534
+ return this.ttsProvider;
125535
+ }
125536
+ getSTTProvider() {
125537
+ if (!this.sttProvider) {
125538
+ throw new McpError(-32600 /* InvalidRequest */, "No STT provider configured");
125539
+ }
125540
+ return this.sttProvider;
125541
+ }
125542
+ hasTTS() {
125543
+ return this.ttsProvider?.supportsTTS ?? false;
125544
+ }
125545
+ hasSTT() {
125546
+ return this.sttProvider?.supportsSTT ?? false;
125547
+ }
125548
+ async healthCheck() {
125549
+ const ttsHealth = this.ttsProvider ? await this.ttsProvider.healthCheck() : false;
125550
+ const sttHealth = this.sttProvider ? await this.sttProvider.healthCheck() : false;
125551
+ return {
125552
+ tts: ttsHealth,
125553
+ stt: sttHealth
125554
+ };
125555
+ }
125556
+ }
125557
+
125558
+ // src/storage/core/StorageService.ts
125559
+ var import_tsyringe5 = __toESM(require_cjs3(), 1);
125150
125560
  function requireTenantId(context) {
125151
125561
  if (!context.tenantId) {
125152
125562
  throw new McpError(-32603 /* InternalError */, "Tenant ID is required for storage operations but was not found in the request context.", {
@@ -125196,15 +125606,15 @@ class StorageService2 {
125196
125606
  }
125197
125607
  }
125198
125608
  StorageService2 = __legacyDecorateClassTS([
125199
- import_tsyringe3.injectable(),
125200
- __legacyDecorateParamTS(0, import_tsyringe3.inject(StorageProvider)),
125609
+ import_tsyringe5.injectable(),
125610
+ __legacyDecorateParamTS(0, import_tsyringe5.inject(StorageProvider)),
125201
125611
  __legacyMetadataTS("design:paramtypes", [
125202
125612
  typeof IStorageProvider === "undefined" ? Object : IStorageProvider
125203
125613
  ])
125204
125614
  ], StorageService2);
125205
125615
 
125206
125616
  // src/storage/core/storageFactory.ts
125207
- var import_tsyringe5 = __toESM(require_cjs3(), 1);
125617
+ var import_tsyringe7 = __toESM(require_cjs3(), 1);
125208
125618
 
125209
125619
  // src/storage/providers/fileSystem/fileSystemProvider.ts
125210
125620
  import { existsSync, mkdirSync } from "fs";
@@ -125551,7 +125961,7 @@ class InMemoryProvider {
125551
125961
  }
125552
125962
 
125553
125963
  // src/storage/providers/supabase/supabaseProvider.ts
125554
- var import_tsyringe4 = __toESM(require_cjs3(), 1);
125964
+ var import_tsyringe6 = __toESM(require_cjs3(), 1);
125555
125965
  var import_supabase_js = __toESM(require_main6(), 1);
125556
125966
  var TABLE_NAME = "kv_store";
125557
125967
  var DEFAULT_LIST_LIMIT3 = 1000;
@@ -125713,8 +126123,8 @@ class SupabaseProvider {
125713
126123
  }
125714
126124
  }
125715
126125
  SupabaseProvider = __legacyDecorateClassTS([
125716
- import_tsyringe4.injectable(),
125717
- __legacyDecorateParamTS(0, import_tsyringe4.inject(SupabaseAdminClient)),
126126
+ import_tsyringe6.injectable(),
126127
+ __legacyDecorateParamTS(0, import_tsyringe6.inject(SupabaseAdminClient)),
125718
126128
  __legacyMetadataTS("design:paramtypes", [
125719
126129
  typeof import_supabase_js.SupabaseClient === "undefined" ? Object : import_supabase_js.SupabaseClient
125720
126130
  ])
@@ -126107,7 +126517,7 @@ function createStorageProvider(config2, deps = {}) {
126107
126517
  if (deps.supabaseClient) {
126108
126518
  return new SupabaseProvider(deps.supabaseClient);
126109
126519
  }
126110
- return import_tsyringe5.container.resolve(SupabaseProvider);
126520
+ return import_tsyringe7.container.resolve(SupabaseProvider);
126111
126521
  case "cloudflare-r2":
126112
126522
  if (isServerless3) {
126113
126523
  const bucket = deps.r2Bucket ?? globalThis.R2_BUCKET;
@@ -126130,9 +126540,9 @@ function createStorageProvider(config2, deps = {}) {
126130
126540
  // src/container/registrations/core.ts
126131
126541
  var registerCoreServices = () => {
126132
126542
  const config2 = parseConfig();
126133
- import_tsyringe6.container.register(AppConfig, { useValue: config2 });
126134
- import_tsyringe6.container.register(Logger2, { useValue: logger });
126135
- import_tsyringe6.container.register(SupabaseAdminClient, {
126543
+ import_tsyringe8.container.register(AppConfig, { useValue: config2 });
126544
+ import_tsyringe8.container.register(Logger2, { useValue: logger });
126545
+ import_tsyringe8.container.register(SupabaseAdminClient, {
126136
126546
  useFactory: (c) => {
126137
126547
  const cfg = c.resolve(AppConfig);
126138
126548
  if (!cfg.supabase?.url || !cfg.supabase?.serviceRoleKey) {
@@ -126143,22 +126553,57 @@ var registerCoreServices = () => {
126143
126553
  });
126144
126554
  }
126145
126555
  });
126146
- import_tsyringe6.container.register(StorageProvider, {
126556
+ import_tsyringe8.container.register(StorageProvider, {
126147
126557
  useFactory: (c) => createStorageProvider(c.resolve(AppConfig))
126148
126558
  });
126149
- import_tsyringe6.container.register(StorageService, { useClass: StorageService2 }, { lifecycle: import_tsyringe6.Lifecycle.Singleton });
126150
- import_tsyringe6.container.register(LlmProvider, {
126559
+ import_tsyringe8.container.register(StorageService, { useClass: StorageService2 }, { lifecycle: import_tsyringe8.Lifecycle.Singleton });
126560
+ import_tsyringe8.container.register(LlmProvider, {
126151
126561
  useClass: OpenRouterProvider
126152
126562
  });
126153
- import_tsyringe6.container.register(RateLimiterService, { useClass: RateLimiter }, { lifecycle: import_tsyringe6.Lifecycle.Singleton });
126563
+ import_tsyringe8.container.register(RateLimiterService, { useClass: RateLimiter }, { lifecycle: import_tsyringe8.Lifecycle.Singleton });
126564
+ import_tsyringe8.container.register(SpeechService, {
126565
+ useFactory: (c) => {
126566
+ const cfg = c.resolve(AppConfig);
126567
+ const ttsConfig = cfg.speech?.tts?.enabled && cfg.speech.tts.apiKey ? {
126568
+ provider: "elevenlabs",
126569
+ apiKey: cfg.speech.tts.apiKey,
126570
+ ...cfg.speech.tts.baseUrl && {
126571
+ baseUrl: cfg.speech.tts.baseUrl
126572
+ },
126573
+ ...cfg.speech.tts.defaultVoiceId && {
126574
+ defaultVoiceId: cfg.speech.tts.defaultVoiceId
126575
+ },
126576
+ ...cfg.speech.tts.defaultModelId && {
126577
+ defaultModelId: cfg.speech.tts.defaultModelId
126578
+ },
126579
+ ...cfg.speech.tts.timeout && {
126580
+ timeout: cfg.speech.tts.timeout
126581
+ }
126582
+ } : undefined;
126583
+ const sttConfig = cfg.speech?.stt?.enabled && cfg.speech.stt.apiKey ? {
126584
+ provider: "openai-whisper",
126585
+ apiKey: cfg.speech.stt.apiKey,
126586
+ ...cfg.speech.stt.baseUrl && {
126587
+ baseUrl: cfg.speech.stt.baseUrl
126588
+ },
126589
+ ...cfg.speech.stt.defaultModelId && {
126590
+ defaultModelId: cfg.speech.stt.defaultModelId
126591
+ },
126592
+ ...cfg.speech.stt.timeout && {
126593
+ timeout: cfg.speech.stt.timeout
126594
+ }
126595
+ } : undefined;
126596
+ return new SpeechService2(ttsConfig, sttConfig);
126597
+ }
126598
+ });
126154
126599
  logger.info("Core services registered with the DI container.");
126155
126600
  };
126156
126601
 
126157
126602
  // src/container/registrations/mcp.ts
126158
- var import_tsyringe16 = __toESM(require_cjs3(), 1);
126603
+ var import_tsyringe18 = __toESM(require_cjs3(), 1);
126159
126604
 
126160
126605
  // src/mcp-server/resources/resource-registration.ts
126161
- var import_tsyringe7 = __toESM(require_cjs3(), 1);
126606
+ var import_tsyringe9 = __toESM(require_cjs3(), 1);
126162
126607
 
126163
126608
  // src/mcp-server/transports/auth/lib/authUtils.ts
126164
126609
  function withRequiredScopes(requiredScopes) {
@@ -129553,8 +129998,8 @@ class ResourceRegistry {
129553
129998
  }
129554
129999
  }
129555
130000
  ResourceRegistry = __legacyDecorateClassTS([
129556
- import_tsyringe7.injectable(),
129557
- __legacyDecorateParamTS(0, import_tsyringe7.injectAll(ResourceDefinitions)),
130001
+ import_tsyringe9.injectable(),
130002
+ __legacyDecorateParamTS(0, import_tsyringe9.injectAll(ResourceDefinitions)),
129558
130003
  __legacyMetadataTS("design:paramtypes", [
129559
130004
  Array
129560
130005
  ])
@@ -129566,10 +130011,10 @@ var registerResources = (container3) => {
129566
130011
  };
129567
130012
 
129568
130013
  // src/mcp-server/server.ts
129569
- var import_tsyringe11 = __toESM(require_cjs3(), 1);
130014
+ var import_tsyringe13 = __toESM(require_cjs3(), 1);
129570
130015
 
129571
130016
  // src/mcp-server/prompts/prompt-registration.ts
129572
- var import_tsyringe8 = __toESM(require_cjs3(), 1);
130017
+ var import_tsyringe10 = __toESM(require_cjs3(), 1);
129573
130018
 
129574
130019
  // src/mcp-server/prompts/definitions/code-review.prompt.ts
129575
130020
  var PROMPT_NAME = "code_review";
@@ -129661,15 +130106,15 @@ class PromptRegistry {
129661
130106
  }
129662
130107
  }
129663
130108
  PromptRegistry = __legacyDecorateClassTS([
129664
- import_tsyringe8.injectable(),
129665
- __legacyDecorateParamTS(0, import_tsyringe8.inject(Logger2)),
130109
+ import_tsyringe10.injectable(),
130110
+ __legacyDecorateParamTS(0, import_tsyringe10.inject(Logger2)),
129666
130111
  __legacyMetadataTS("design:paramtypes", [
129667
130112
  Object
129668
130113
  ])
129669
130114
  ], PromptRegistry);
129670
130115
 
129671
130116
  // src/mcp-server/roots/roots-registration.ts
129672
- var import_tsyringe9 = __toESM(require_cjs3(), 1);
130117
+ var import_tsyringe11 = __toESM(require_cjs3(), 1);
129673
130118
  class RootsRegistry {
129674
130119
  logger;
129675
130120
  constructor(logger2) {
@@ -129684,15 +130129,15 @@ class RootsRegistry {
129684
130129
  }
129685
130130
  }
129686
130131
  RootsRegistry = __legacyDecorateClassTS([
129687
- import_tsyringe9.injectable(),
129688
- __legacyDecorateParamTS(0, import_tsyringe9.inject(Logger2)),
130132
+ import_tsyringe11.injectable(),
130133
+ __legacyDecorateParamTS(0, import_tsyringe11.inject(Logger2)),
129689
130134
  __legacyMetadataTS("design:paramtypes", [
129690
130135
  Object
129691
130136
  ])
129692
130137
  ], RootsRegistry);
129693
130138
 
129694
130139
  // src/mcp-server/tools/tool-registration.ts
129695
- var import_tsyringe10 = __toESM(require_cjs3(), 1);
130140
+ var import_tsyringe12 = __toESM(require_cjs3(), 1);
129696
130141
 
129697
130142
  // src/mcp-server/tools/definitions/template-cat-fact.tool.ts
129698
130143
  var TOOL_NAME = "template_cat_fact";
@@ -130255,8 +130700,8 @@ class ToolRegistry {
130255
130700
  }
130256
130701
  }
130257
130702
  ToolRegistry = __legacyDecorateClassTS([
130258
- import_tsyringe10.injectable(),
130259
- __legacyDecorateParamTS(0, import_tsyringe10.injectAll(ToolDefinitions)),
130703
+ import_tsyringe12.injectable(),
130704
+ __legacyDecorateParamTS(0, import_tsyringe12.injectAll(ToolDefinitions)),
130260
130705
  __legacyMetadataTS("design:paramtypes", [
130261
130706
  Array
130262
130707
  ])
@@ -130295,13 +130740,13 @@ async function createMcpServerInstance() {
130295
130740
  });
130296
130741
  try {
130297
130742
  logger.debug("Registering all MCP capabilities via registries...", context);
130298
- const toolRegistry = import_tsyringe11.container.resolve(ToolRegistry);
130743
+ const toolRegistry = import_tsyringe13.container.resolve(ToolRegistry);
130299
130744
  await toolRegistry.registerAll(server);
130300
- const resourceRegistry = import_tsyringe11.container.resolve(ResourceRegistry);
130745
+ const resourceRegistry = import_tsyringe13.container.resolve(ResourceRegistry);
130301
130746
  await resourceRegistry.registerAll(server);
130302
- const promptRegistry = import_tsyringe11.container.resolve(PromptRegistry);
130747
+ const promptRegistry = import_tsyringe13.container.resolve(PromptRegistry);
130303
130748
  promptRegistry.registerAll(server);
130304
- const rootsRegistry = import_tsyringe11.container.resolve(RootsRegistry);
130749
+ const rootsRegistry = import_tsyringe13.container.resolve(RootsRegistry);
130305
130750
  rootsRegistry.registerAll(server);
130306
130751
  logger.info("All MCP capabilities registered successfully", context);
130307
130752
  } catch (err) {
@@ -130316,7 +130761,7 @@ async function createMcpServerInstance() {
130316
130761
  }
130317
130762
 
130318
130763
  // src/mcp-server/transports/manager.ts
130319
- var import_tsyringe15 = __toESM(require_cjs3(), 1);
130764
+ var import_tsyringe17 = __toESM(require_cjs3(), 1);
130320
130765
 
130321
130766
  // node_modules/hono/dist/http-exception.js
130322
130767
  var HTTPException = class extends Error {
@@ -132984,7 +133429,7 @@ var cors = (options) => {
132984
133429
  import http from "http";
132985
133430
  import { randomUUID } from "node:crypto";
132986
133431
  // src/mcp-server/transports/auth/authFactory.ts
132987
- var import_tsyringe14 = __toESM(require_cjs3(), 1);
133432
+ var import_tsyringe16 = __toESM(require_cjs3(), 1);
132988
133433
 
132989
133434
  // node_modules/jose/dist/webapi/lib/buffer_utils.js
132990
133435
  var encoder = new TextEncoder;
@@ -134502,7 +134947,7 @@ function createRemoteJWKSet(url, options) {
134502
134947
  return remoteJWKSet;
134503
134948
  }
134504
134949
  // src/mcp-server/transports/auth/strategies/jwtStrategy.ts
134505
- var import_tsyringe12 = __toESM(require_cjs3(), 1);
134950
+ var import_tsyringe14 = __toESM(require_cjs3(), 1);
134506
134951
  class JwtStrategy {
134507
134952
  config;
134508
134953
  logger;
@@ -134605,9 +135050,9 @@ class JwtStrategy {
134605
135050
  }
134606
135051
  }
134607
135052
  JwtStrategy = __legacyDecorateClassTS([
134608
- import_tsyringe12.injectable(),
134609
- __legacyDecorateParamTS(0, import_tsyringe12.inject(AppConfig)),
134610
- __legacyDecorateParamTS(1, import_tsyringe12.inject(Logger2)),
135053
+ import_tsyringe14.injectable(),
135054
+ __legacyDecorateParamTS(0, import_tsyringe14.inject(AppConfig)),
135055
+ __legacyDecorateParamTS(1, import_tsyringe14.inject(Logger2)),
134611
135056
  __legacyMetadataTS("design:paramtypes", [
134612
135057
  Object,
134613
135058
  Object
@@ -134615,7 +135060,7 @@ JwtStrategy = __legacyDecorateClassTS([
134615
135060
  ], JwtStrategy);
134616
135061
 
134617
135062
  // src/mcp-server/transports/auth/strategies/oauthStrategy.ts
134618
- var import_tsyringe13 = __toESM(require_cjs3(), 1);
135063
+ var import_tsyringe15 = __toESM(require_cjs3(), 1);
134619
135064
  class OauthStrategy {
134620
135065
  config;
134621
135066
  logger;
@@ -134732,9 +135177,9 @@ class OauthStrategy {
134732
135177
  }
134733
135178
  }
134734
135179
  OauthStrategy = __legacyDecorateClassTS([
134735
- import_tsyringe13.injectable(),
134736
- __legacyDecorateParamTS(0, import_tsyringe13.inject(AppConfig)),
134737
- __legacyDecorateParamTS(1, import_tsyringe13.inject(Logger2)),
135180
+ import_tsyringe15.injectable(),
135181
+ __legacyDecorateParamTS(0, import_tsyringe15.inject(AppConfig)),
135182
+ __legacyDecorateParamTS(1, import_tsyringe15.inject(Logger2)),
134738
135183
  __legacyMetadataTS("design:paramtypes", [
134739
135184
  Object,
134740
135185
  Object
@@ -134742,8 +135187,8 @@ OauthStrategy = __legacyDecorateClassTS([
134742
135187
  ], OauthStrategy);
134743
135188
 
134744
135189
  // src/mcp-server/transports/auth/authFactory.ts
134745
- import_tsyringe14.container.register(JwtStrategy, { useClass: JwtStrategy });
134746
- import_tsyringe14.container.register(OauthStrategy, { useClass: OauthStrategy });
135190
+ import_tsyringe16.container.register(JwtStrategy, { useClass: JwtStrategy });
135191
+ import_tsyringe16.container.register(OauthStrategy, { useClass: OauthStrategy });
134747
135192
  function createAuthStrategy() {
134748
135193
  const context = requestContextService.createRequestContext({
134749
135194
  operation: "createAuthStrategy",
@@ -134753,10 +135198,10 @@ function createAuthStrategy() {
134753
135198
  switch (config.mcpAuthMode) {
134754
135199
  case "jwt":
134755
135200
  logger.debug("Resolving JWT strategy from container.", context);
134756
- return import_tsyringe14.container.resolve(JwtStrategy);
135201
+ return import_tsyringe16.container.resolve(JwtStrategy);
134757
135202
  case "oauth":
134758
135203
  logger.debug("Resolving OAuth strategy from container.", context);
134759
- return import_tsyringe14.container.resolve(OauthStrategy);
135204
+ return import_tsyringe16.container.resolve(OauthStrategy);
134760
135205
  case "none":
134761
135206
  logger.info("Authentication is disabled ('none' mode).", context);
134762
135207
  return null;
@@ -135270,10 +135715,10 @@ class TransportManager {
135270
135715
  }
135271
135716
  }
135272
135717
  TransportManager = __legacyDecorateClassTS([
135273
- import_tsyringe15.injectable(),
135274
- __legacyDecorateParamTS(0, import_tsyringe15.inject(AppConfig)),
135275
- __legacyDecorateParamTS(1, import_tsyringe15.inject(Logger2)),
135276
- __legacyDecorateParamTS(2, import_tsyringe15.inject(CreateMcpServerInstance)),
135718
+ import_tsyringe17.injectable(),
135719
+ __legacyDecorateParamTS(0, import_tsyringe17.inject(AppConfig)),
135720
+ __legacyDecorateParamTS(1, import_tsyringe17.inject(Logger2)),
135721
+ __legacyDecorateParamTS(2, import_tsyringe17.inject(CreateMcpServerInstance)),
135277
135722
  __legacyMetadataTS("design:paramtypes", [
135278
135723
  typeof AppConfigType === "undefined" ? Object : AppConfigType,
135279
135724
  Object,
@@ -135283,14 +135728,14 @@ TransportManager = __legacyDecorateClassTS([
135283
135728
 
135284
135729
  // src/container/registrations/mcp.ts
135285
135730
  var registerMcpServices = () => {
135286
- import_tsyringe16.container.registerSingleton(ToolRegistry);
135287
- import_tsyringe16.container.registerSingleton(ResourceRegistry);
135288
- registerTools(import_tsyringe16.container);
135289
- registerResources(import_tsyringe16.container);
135290
- import_tsyringe16.container.register(CreateMcpServerInstance, {
135731
+ import_tsyringe18.container.registerSingleton(ToolRegistry);
135732
+ import_tsyringe18.container.registerSingleton(ResourceRegistry);
135733
+ registerTools(import_tsyringe18.container);
135734
+ registerResources(import_tsyringe18.container);
135735
+ import_tsyringe18.container.register(CreateMcpServerInstance, {
135291
135736
  useValue: createMcpServerInstance
135292
135737
  });
135293
- import_tsyringe16.container.registerSingleton(TransportManagerToken, TransportManager);
135738
+ import_tsyringe18.container.registerSingleton(TransportManagerToken, TransportManager);
135294
135739
  logger.info("MCP services and factories registered with the DI container.");
135295
135740
  };
135296
135741
 
@@ -135304,7 +135749,7 @@ function composeContainer() {
135304
135749
  registerMcpServices();
135305
135750
  isContainerComposed = true;
135306
135751
  }
135307
- var container_default = import_tsyringe17.container;
135752
+ var container_default = import_tsyringe19.container;
135308
135753
 
135309
135754
  // src/index.ts
135310
135755
  var config2;