cast-code 1.0.1 → 1.0.3

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/main.js CHANGED
@@ -10,7 +10,9 @@ const _appmodule = require("./app.module");
10
10
  const _replservice = require("./modules/repl/services/repl.service");
11
11
  const _configmanagerservice = require("./modules/config/services/config-manager.service");
12
12
  const _initconfigservice = require("./modules/config/services/init-config.service");
13
- (0, _dotenv.config)();
13
+ (0, _dotenv.config)({
14
+ quiet: true
15
+ });
14
16
  async function checkAndRunSetup(configManager, initService) {
15
17
  const hasConfig = await configManager.configExists();
16
18
  if (!hasConfig) {
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'reflect-metadata';\nimport { config } from 'dotenv';\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { ReplService } from './modules/repl/services/repl.service';\nimport { ConfigManagerService } from './modules/config/services/config-manager.service';\nimport { InitConfigService } from './modules/config/services/init-config.service';\n\nconfig();\n\nasync function checkAndRunSetup(configManager: ConfigManagerService, initService: InitConfigService): Promise<boolean> {\n const hasConfig = await configManager.configExists();\n \n if (!hasConfig) {\n console.log('\\n👋 Bem-vindo ao Cast Code!\\n');\n console.log('Parece que esta é a primeira vez que você executa o Cast.');\n console.log('Vamos fazer a configuração inicial agora.\\n');\n\n try {\n await initService.runInitialSetup();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`\\n❌ Falha na configuração inicial: ${message}\\n`);\n return false;\n }\n\n const created = await configManager.configExists();\n if (!created) {\n console.log('\\n⚠️ Configuração não concluída. Rode: cast config init\\n');\n return false;\n }\n\n return true;\n }\n \n return true;\n}\n\nasync function bootstrap() {\n const args = process.argv.slice(2);\n const command = args[0];\n \n if (command === 'config' || command === 'init') {\n const app = await NestFactory.createApplicationContext(AppModule, {\n logger: false,\n });\n \n const configCommands = app.get(InitConfigService);\n try {\n await configCommands.runInitialSetup();\n } catch (error) {\n const message = error instanceof Error ? error.stack || error.message : String(error);\n console.error('\\nFailed to run initial setup:\\n', message);\n process.exitCode = 1;\n }\n await app.close();\n return;\n }\n\n const app = await NestFactory.createApplicationContext(AppModule, {\n logger: false,\n });\n\n const configManager = app.get(ConfigManagerService);\n const initService = app.get(InitConfigService);\n \n const ready = await checkAndRunSetup(configManager, initService);\n \n if (!ready) {\n await app.close();\n process.exit(1);\n }\n\n await configManager.loadConfig();\n\n const repl = app.get(ReplService);\n\n process.on('SIGINT', () => {\n repl.stop();\n app.close();\n process.exit(0);\n });\n\n try {\n await repl.start();\n } catch (error) {\n console.error('Failed to start:', (error as Error).message);\n process.exit(1);\n }\n}\n\nbootstrap().catch((error) => {\n const message = error instanceof Error ? error.stack || error.message : String(error);\n console.error('\\nFatal bootstrap error:\\n', message);\n process.exit(1);\n});\n"],"names":["config","checkAndRunSetup","configManager","initService","hasConfig","configExists","console","log","runInitialSetup","error","message","Error","String","created","bootstrap","args","process","argv","slice","command","app","NestFactory","createApplicationContext","AppModule","logger","configCommands","get","InitConfigService","stack","exitCode","close","ConfigManagerService","ready","exit","loadConfig","repl","ReplService","on","stop","start","catch"],"mappings":";;;;;QACO;wBACgB;sBACK;2BACF;6BACE;sCACS;mCACH;AAElCA,IAAAA,cAAM;AAEN,eAAeC,iBAAiBC,aAAmC,EAAEC,WAA8B;IACjG,MAAMC,YAAY,MAAMF,cAAcG,YAAY;IAElD,IAAI,CAACD,WAAW;QACdE,QAAQC,GAAG,CAAC;QACZD,QAAQC,GAAG,CAAC;QACZD,QAAQC,GAAG,CAAC;QAEZ,IAAI;YACF,MAAMJ,YAAYK,eAAe;QACnC,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAChEH,QAAQG,KAAK,CAAC,CAAC,mCAAmC,EAAEC,QAAQ,EAAE,CAAC;YAC/D,OAAO;QACT;QAEA,MAAMG,UAAU,MAAMX,cAAcG,YAAY;QAChD,IAAI,CAACQ,SAAS;YACZP,QAAQC,GAAG,CAAC;YACZ,OAAO;QACT;QAEA,OAAO;IACT;IAEA,OAAO;AACT;AAEA,eAAeO;IACb,MAAMC,OAAOC,QAAQC,IAAI,CAACC,KAAK,CAAC;IAChC,MAAMC,UAAUJ,IAAI,CAAC,EAAE;IAEvB,IAAII,YAAY,YAAYA,YAAY,QAAQ;QAC9C,MAAMC,MAAM,MAAMC,iBAAW,CAACC,wBAAwB,CAACC,oBAAS,EAAE;YAChEC,QAAQ;QACV;QAEA,MAAMC,iBAAiBL,IAAIM,GAAG,CAACC,oCAAiB;QAChD,IAAI;YACF,MAAMF,eAAejB,eAAe;QACtC,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMmB,KAAK,IAAInB,MAAMC,OAAO,GAAGE,OAAOH;YAC/EH,QAAQG,KAAK,CAAC,oCAAoCC;YAClDM,QAAQa,QAAQ,GAAG;QACrB;QACA,MAAMT,IAAIU,KAAK;QACf;IACF;IAEA,MAAMV,MAAM,MAAMC,iBAAW,CAACC,wBAAwB,CAACC,oBAAS,EAAE;QAChEC,QAAQ;IACV;IAEA,MAAMtB,gBAAgBkB,IAAIM,GAAG,CAACK,0CAAoB;IAClD,MAAM5B,cAAciB,IAAIM,GAAG,CAACC,oCAAiB;IAE7C,MAAMK,QAAQ,MAAM/B,iBAAiBC,eAAeC;IAEpD,IAAI,CAAC6B,OAAO;QACV,MAAMZ,IAAIU,KAAK;QACfd,QAAQiB,IAAI,CAAC;IACf;IAEA,MAAM/B,cAAcgC,UAAU;IAE9B,MAAMC,OAAOf,IAAIM,GAAG,CAACU,wBAAW;IAEhCpB,QAAQqB,EAAE,CAAC,UAAU;QACnBF,KAAKG,IAAI;QACTlB,IAAIU,KAAK;QACTd,QAAQiB,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAME,KAAKI,KAAK;IAClB,EAAE,OAAO9B,OAAO;QACdH,QAAQG,KAAK,CAAC,oBAAoB,AAACA,MAAgBC,OAAO;QAC1DM,QAAQiB,IAAI,CAAC;IACf;AACF;AAEAnB,YAAY0B,KAAK,CAAC,CAAC/B;IACjB,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMmB,KAAK,IAAInB,MAAMC,OAAO,GAAGE,OAAOH;IAC/EH,QAAQG,KAAK,CAAC,8BAA8BC;IAC5CM,QAAQiB,IAAI,CAAC;AACf"}
1
+ {"version":3,"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\nimport 'reflect-metadata';\nimport { config } from 'dotenv';\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { ReplService } from './modules/repl/services/repl.service';\nimport { ConfigManagerService } from './modules/config/services/config-manager.service';\nimport { InitConfigService } from './modules/config/services/init-config.service';\n\nconfig({ quiet: true });\n\nasync function checkAndRunSetup(configManager: ConfigManagerService, initService: InitConfigService): Promise<boolean> {\n const hasConfig = await configManager.configExists();\n \n if (!hasConfig) {\n console.log('\\n👋 Bem-vindo ao Cast Code!\\n');\n console.log('Parece que esta é a primeira vez que você executa o Cast.');\n console.log('Vamos fazer a configuração inicial agora.\\n');\n\n try {\n await initService.runInitialSetup();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`\\n❌ Falha na configuração inicial: ${message}\\n`);\n return false;\n }\n\n const created = await configManager.configExists();\n if (!created) {\n console.log('\\n⚠️ Configuração não concluída. Rode: cast config init\\n');\n return false;\n }\n\n return true;\n }\n \n return true;\n}\n\nasync function bootstrap() {\n const args = process.argv.slice(2);\n const command = args[0];\n \n if (command === 'config' || command === 'init') {\n const app = await NestFactory.createApplicationContext(AppModule, {\n logger: false,\n });\n \n const configCommands = app.get(InitConfigService);\n try {\n await configCommands.runInitialSetup();\n } catch (error) {\n const message = error instanceof Error ? error.stack || error.message : String(error);\n console.error('\\nFailed to run initial setup:\\n', message);\n process.exitCode = 1;\n }\n await app.close();\n return;\n }\n\n const app = await NestFactory.createApplicationContext(AppModule, {\n logger: false,\n });\n\n const configManager = app.get(ConfigManagerService);\n const initService = app.get(InitConfigService);\n \n const ready = await checkAndRunSetup(configManager, initService);\n \n if (!ready) {\n await app.close();\n process.exit(1);\n }\n\n await configManager.loadConfig();\n\n const repl = app.get(ReplService);\n\n process.on('SIGINT', () => {\n repl.stop();\n app.close();\n process.exit(0);\n });\n\n try {\n await repl.start();\n } catch (error) {\n console.error('Failed to start:', (error as Error).message);\n process.exit(1);\n }\n}\n\nbootstrap().catch((error) => {\n const message = error instanceof Error ? error.stack || error.message : String(error);\n console.error('\\nFatal bootstrap error:\\n', message);\n process.exit(1);\n});\n"],"names":["config","quiet","checkAndRunSetup","configManager","initService","hasConfig","configExists","console","log","runInitialSetup","error","message","Error","String","created","bootstrap","args","process","argv","slice","command","app","NestFactory","createApplicationContext","AppModule","logger","configCommands","get","InitConfigService","stack","exitCode","close","ConfigManagerService","ready","exit","loadConfig","repl","ReplService","on","stop","start","catch"],"mappings":";;;;;QACO;wBACgB;sBACK;2BACF;6BACE;sCACS;mCACH;AAElCA,IAAAA,cAAM,EAAC;IAAEC,OAAO;AAAK;AAErB,eAAeC,iBAAiBC,aAAmC,EAAEC,WAA8B;IACjG,MAAMC,YAAY,MAAMF,cAAcG,YAAY;IAElD,IAAI,CAACD,WAAW;QACdE,QAAQC,GAAG,CAAC;QACZD,QAAQC,GAAG,CAAC;QACZD,QAAQC,GAAG,CAAC;QAEZ,IAAI;YACF,MAAMJ,YAAYK,eAAe;QACnC,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAChEH,QAAQG,KAAK,CAAC,CAAC,mCAAmC,EAAEC,QAAQ,EAAE,CAAC;YAC/D,OAAO;QACT;QAEA,MAAMG,UAAU,MAAMX,cAAcG,YAAY;QAChD,IAAI,CAACQ,SAAS;YACZP,QAAQC,GAAG,CAAC;YACZ,OAAO;QACT;QAEA,OAAO;IACT;IAEA,OAAO;AACT;AAEA,eAAeO;IACb,MAAMC,OAAOC,QAAQC,IAAI,CAACC,KAAK,CAAC;IAChC,MAAMC,UAAUJ,IAAI,CAAC,EAAE;IAEvB,IAAII,YAAY,YAAYA,YAAY,QAAQ;QAC9C,MAAMC,MAAM,MAAMC,iBAAW,CAACC,wBAAwB,CAACC,oBAAS,EAAE;YAChEC,QAAQ;QACV;QAEA,MAAMC,iBAAiBL,IAAIM,GAAG,CAACC,oCAAiB;QAChD,IAAI;YACF,MAAMF,eAAejB,eAAe;QACtC,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMmB,KAAK,IAAInB,MAAMC,OAAO,GAAGE,OAAOH;YAC/EH,QAAQG,KAAK,CAAC,oCAAoCC;YAClDM,QAAQa,QAAQ,GAAG;QACrB;QACA,MAAMT,IAAIU,KAAK;QACf;IACF;IAEA,MAAMV,MAAM,MAAMC,iBAAW,CAACC,wBAAwB,CAACC,oBAAS,EAAE;QAChEC,QAAQ;IACV;IAEA,MAAMtB,gBAAgBkB,IAAIM,GAAG,CAACK,0CAAoB;IAClD,MAAM5B,cAAciB,IAAIM,GAAG,CAACC,oCAAiB;IAE7C,MAAMK,QAAQ,MAAM/B,iBAAiBC,eAAeC;IAEpD,IAAI,CAAC6B,OAAO;QACV,MAAMZ,IAAIU,KAAK;QACfd,QAAQiB,IAAI,CAAC;IACf;IAEA,MAAM/B,cAAcgC,UAAU;IAE9B,MAAMC,OAAOf,IAAIM,GAAG,CAACU,wBAAW;IAEhCpB,QAAQqB,EAAE,CAAC,UAAU;QACnBF,KAAKG,IAAI;QACTlB,IAAIU,KAAK;QACTd,QAAQiB,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAME,KAAKI,KAAK;IAClB,EAAE,OAAO9B,OAAO;QACdH,QAAQG,KAAK,CAAC,oBAAoB,AAACA,MAAgBC,OAAO;QAC1DM,QAAQiB,IAAI,CAAC;IACf;AACF;AAEAnB,YAAY0B,KAAK,CAAC,CAAC/B;IACjB,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMmB,KAAK,IAAInB,MAAMC,OAAO,GAAGE,OAAOH;IAC/EH,QAAQG,KAAK,CAAC,8BAA8BC;IAC5CM,QAAQiB,IAAI,CAAC;AACf"}
@@ -149,8 +149,19 @@ const MCP_TEMPLATES = {
149
149
  // ===== DESIGN =====
150
150
  figma: {
151
151
  id: 'figma',
152
- name: 'Figma',
153
- description: 'Acesse designs e componentes (OAuth)',
152
+ name: 'Figma Desktop',
153
+ description: 'Acesse designs via app desktop local (sem OAuth)',
154
+ category: 'design',
155
+ config: {
156
+ type: 'http',
157
+ endpoint: 'http://127.0.0.1:3845/mcp'
158
+ },
159
+ credentials: []
160
+ },
161
+ 'figma-remote': {
162
+ id: 'figma-remote',
163
+ name: 'Figma Remote (OAuth)',
164
+ description: 'Servidor remoto Figma — requer cliente pré-aprovado',
154
165
  category: 'design',
155
166
  config: {
156
167
  type: 'http',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/mcp/catalog/mcp-templates.ts"],"sourcesContent":["import { McpConfig } from '../types';\n\nexport type McpCategory = 'dev' | 'design' | 'data' | 'search' | 'cloud' | 'productivity' | 'payments' | 'browser' | 'filesystem';\n\nexport interface McpTemplate {\n id: string;\n name: string;\n description: string;\n category: McpCategory;\n config: McpConfig;\n credentials: {\n name: string;\n envVar: string;\n placeholder: string;\n required: boolean;\n isArg?: boolean;\n }[];\n}\n\nexport const MCP_TEMPLATES: Record<string, McpTemplate> = {\n // ===== DEV TOOLS =====\n github: {\n id: 'github',\n name: 'GitHub',\n description: 'Acesse repos, issues, PRs',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n env: {},\n },\n credentials: [\n {\n name: 'GitHub Token',\n envVar: 'GITHUB_PERSONAL_ACCESS_TOKEN',\n placeholder: 'ghp_...',\n required: true,\n },\n ],\n },\n\n linear: {\n id: 'linear',\n name: 'Linear',\n description: 'Gerencie issues e projetos',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@larryhudson/linear-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Linear API Key',\n envVar: 'LINEAR_API_KEY',\n placeholder: 'lin_api_...',\n required: true,\n },\n ],\n },\n\n jira: {\n id: 'jira',\n name: 'Jira',\n description: 'Gerencie issues e sprints',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@aashari/mcp-server-atlassian-jira'],\n env: {},\n },\n credentials: [\n {\n name: 'Jira Host',\n envVar: 'JIRA_HOST',\n placeholder: 'empresa.atlassian.net',\n required: true,\n },\n {\n name: 'Jira Email',\n envVar: 'JIRA_EMAIL',\n placeholder: 'você@empresa.com',\n required: true,\n },\n {\n name: 'Jira API Token',\n envVar: 'JIRA_API_TOKEN',\n placeholder: 'ATATT...',\n required: true,\n },\n ],\n },\n\n sentry: {\n id: 'sentry',\n name: 'Sentry',\n description: 'Monitore erros e performance',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@sentry/mcp-server'],\n env: {\n EMBEDDED_AGENT_PROVIDER: 'anthropic',\n },\n },\n credentials: [\n {\n name: 'Sentry Access Token',\n envVar: 'SENTRY_ACCESS_TOKEN',\n placeholder: 'sntrys_...',\n required: true,\n },\n ],\n },\n\n docker: {\n id: 'docker',\n name: 'Docker',\n description: 'Gerencie containers e images',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@0xshariq/docker-mcp-server'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== DESIGN =====\n figma: {\n id: 'figma',\n name: 'Figma',\n description: 'Acesse designs e componentes (OAuth)',\n category: 'design',\n config: {\n type: 'http',\n endpoint: 'https://mcp.figma.com/mcp',\n },\n credentials: [],\n },\n\n // ===== DATA =====\n postgres: {\n id: 'postgres',\n name: 'PostgreSQL',\n description: 'Consulte bancos de dados',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-postgres'],\n env: {},\n },\n credentials: [\n {\n name: 'Database URL',\n envVar: '',\n placeholder: 'postgresql://user:pass@host/db',\n required: true,\n isArg: true,\n },\n ],\n },\n\n mongodb: {\n id: 'mongodb',\n name: 'MongoDB',\n description: 'Consulte coleções e documentos',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@mongodb-js/mongodb-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Connection String',\n envVar: 'MDB_MCP_CONNECTION_STRING',\n placeholder: 'mongodb+srv://...',\n required: true,\n },\n ],\n },\n\n redis: {\n id: 'redis',\n name: 'Redis',\n description: 'Cache e key-value store',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-redis'],\n env: {},\n },\n credentials: [\n {\n name: 'Redis URL',\n envVar: 'REDIS_URL',\n placeholder: 'redis://localhost:6379',\n required: true,\n },\n ],\n },\n\n supabase: {\n id: 'supabase',\n name: 'Supabase',\n description: 'Banco de dados e backend',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@cloud9-labs/mcp-supabase'],\n env: {},\n },\n credentials: [\n {\n name: 'Supabase URL',\n envVar: 'SUPABASE_URL',\n placeholder: 'https://xyz.supabase.co',\n required: true,\n },\n {\n name: 'Service Key',\n envVar: 'SUPABASE_SERVICE_KEY',\n placeholder: 'eyJ...',\n required: true,\n },\n ],\n },\n\n // ===== SEARCH =====\n 'brave-search': {\n id: 'brave-search',\n name: 'Brave Search',\n description: 'Busca na web',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n env: {},\n },\n credentials: [\n {\n name: 'Brave API Key',\n envVar: 'BRAVE_API_KEY',\n placeholder: 'BSA...',\n required: true,\n },\n ],\n },\n\n exa: {\n id: 'exa',\n name: 'Exa Search',\n description: 'Busca semântica na web',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'exa-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Exa API Key',\n envVar: 'EXA_API_KEY',\n placeholder: 'exa_...',\n required: true,\n },\n ],\n },\n\n perplexity: {\n id: 'perplexity',\n name: 'Perplexity',\n description: 'Busca com IA',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@perplexity-ai/mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Perplexity API Key',\n envVar: 'PERPLEXITY_API_KEY',\n placeholder: 'pplx-...',\n required: true,\n },\n ],\n },\n\n context7: {\n id: 'context7',\n name: 'Context7',\n description: 'Busca em documentações técnicas',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@upstash/context7-mcp'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== CLOUD =====\n vercel: {\n id: 'vercel',\n name: 'Vercel',\n description: 'Deploy e gerenciamento',\n category: 'cloud',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@vercel/mcp-adapter'],\n env: {},\n },\n credentials: [],\n },\n\n cloudflare: {\n id: 'cloudflare',\n name: 'Cloudflare',\n description: 'Workers, KV, R2',\n category: 'cloud',\n config: {\n type: 'http',\n endpoint: 'https://mcp.cloudflare.com',\n },\n credentials: [],\n },\n\n 'aws-s3': {\n id: 'aws-s3',\n name: 'AWS S3',\n description: 'Armazenamento de objetos',\n category: 'cloud',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'aws-s3-mcp'],\n env: {},\n },\n credentials: [\n {\n name: 'Access Key ID',\n envVar: 'AWS_ACCESS_KEY_ID',\n placeholder: 'AKIA...',\n required: true,\n },\n {\n name: 'Secret Access Key',\n envVar: 'AWS_SECRET_ACCESS_KEY',\n placeholder: 'xxx',\n required: true,\n },\n {\n name: 'Region',\n envVar: 'AWS_REGION',\n placeholder: 'us-east-1',\n required: true,\n },\n ],\n },\n\n // ===== PRODUCTIVITY =====\n slack: {\n id: 'slack',\n name: 'Slack',\n description: 'Envie mensagens e gerencie canais',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'slack-mcp-server@latest', '--transport', 'stdio'],\n env: {},\n },\n credentials: [\n {\n name: 'Slack Bot Token',\n envVar: 'SLACK_BOT_TOKEN',\n placeholder: 'xoxb-...',\n required: true,\n },\n {\n name: 'Team ID',\n envVar: 'SLACK_TEAM_ID',\n placeholder: 'T...',\n required: true,\n },\n ],\n },\n\n notion: {\n id: 'notion',\n name: 'Notion',\n description: 'Gerencie páginas e databases',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@notionhq/notion-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Notion Token',\n envVar: 'NOTION_TOKEN',\n placeholder: 'secret_...',\n required: true,\n },\n ],\n },\n\n 'google-drive': {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Acesse arquivos e pastas (OAuth)',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-gdrive'],\n env: {},\n },\n credentials: [],\n },\n\n 'google-maps': {\n id: 'google-maps',\n name: 'Google Maps',\n description: 'Geocoding e rotas',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@googlemaps/code-assist-mcp@latest'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== PAYMENTS =====\n stripe: {\n id: 'stripe',\n name: 'Stripe',\n description: 'Pagamentos e assinaturas',\n category: 'payments',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@stripe/mcp', '--tools=all'],\n env: {},\n },\n credentials: [\n {\n name: 'Stripe Secret Key',\n envVar: 'STRIPE_SECRET_KEY',\n placeholder: 'sk_test_... ou rk_...',\n required: true,\n },\n ],\n },\n\n twilio: {\n id: 'twilio',\n name: 'Twilio',\n description: 'SMS e chamadas',\n category: 'payments',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@twilio-alpha/mcp'],\n env: {},\n },\n credentials: [\n {\n name: 'Account SID',\n envVar: '',\n placeholder: 'AC...',\n required: true,\n isArg: true,\n },\n {\n name: 'API Key:Secret',\n envVar: '',\n placeholder: 'SK...:...',\n required: true,\n isArg: true,\n },\n ],\n },\n\n // ===== BROWSER =====\n puppeteer: {\n id: 'puppeteer',\n name: 'Puppeteer',\n description: 'Automação de browser',\n category: 'browser',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-puppeteer'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== FILESYSTEM =====\n filesystem: {\n id: 'filesystem',\n name: 'Filesystem',\n description: 'Acesse arquivos locais',\n category: 'filesystem',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem'],\n env: {},\n },\n credentials: [\n {\n name: 'Diretório permitido',\n envVar: '',\n placeholder: '/caminho/para/diretório',\n required: true,\n isArg: true,\n },\n ],\n },\n};\n\nexport function getTemplatesByCategory(category: McpCategory): McpTemplate[] {\n return Object.values(MCP_TEMPLATES).filter(t => t.category === category);\n}\n\nexport function getAllTemplates(): McpTemplate[] {\n return Object.values(MCP_TEMPLATES);\n}\n\nexport function getTemplate(id: string): McpTemplate | undefined {\n return MCP_TEMPLATES[id];\n}\n"],"names":["MCP_TEMPLATES","getAllTemplates","getTemplate","getTemplatesByCategory","github","id","name","description","category","config","type","command","args","env","credentials","envVar","placeholder","required","linear","jira","sentry","EMBEDDED_AGENT_PROVIDER","docker","figma","endpoint","postgres","isArg","mongodb","redis","supabase","exa","perplexity","context7","vercel","cloudflare","slack","notion","stripe","twilio","puppeteer","filesystem","Object","values","filter","t"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/modules/mcp/catalog/mcp-templates.ts"],"sourcesContent":["import { McpConfig } from '../types';\n\nexport type McpCategory = 'dev' | 'design' | 'data' | 'search' | 'cloud' | 'productivity' | 'payments' | 'browser' | 'filesystem';\n\nexport interface McpTemplate {\n id: string;\n name: string;\n description: string;\n category: McpCategory;\n config: McpConfig;\n credentials: {\n name: string;\n envVar: string;\n placeholder: string;\n required: boolean;\n isArg?: boolean;\n }[];\n}\n\nexport const MCP_TEMPLATES: Record<string, McpTemplate> = {\n // ===== DEV TOOLS =====\n github: {\n id: 'github',\n name: 'GitHub',\n description: 'Acesse repos, issues, PRs',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n env: {},\n },\n credentials: [\n {\n name: 'GitHub Token',\n envVar: 'GITHUB_PERSONAL_ACCESS_TOKEN',\n placeholder: 'ghp_...',\n required: true,\n },\n ],\n },\n\n linear: {\n id: 'linear',\n name: 'Linear',\n description: 'Gerencie issues e projetos',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@larryhudson/linear-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Linear API Key',\n envVar: 'LINEAR_API_KEY',\n placeholder: 'lin_api_...',\n required: true,\n },\n ],\n },\n\n jira: {\n id: 'jira',\n name: 'Jira',\n description: 'Gerencie issues e sprints',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@aashari/mcp-server-atlassian-jira'],\n env: {},\n },\n credentials: [\n {\n name: 'Jira Host',\n envVar: 'JIRA_HOST',\n placeholder: 'empresa.atlassian.net',\n required: true,\n },\n {\n name: 'Jira Email',\n envVar: 'JIRA_EMAIL',\n placeholder: 'você@empresa.com',\n required: true,\n },\n {\n name: 'Jira API Token',\n envVar: 'JIRA_API_TOKEN',\n placeholder: 'ATATT...',\n required: true,\n },\n ],\n },\n\n sentry: {\n id: 'sentry',\n name: 'Sentry',\n description: 'Monitore erros e performance',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@sentry/mcp-server'],\n env: {\n EMBEDDED_AGENT_PROVIDER: 'anthropic',\n },\n },\n credentials: [\n {\n name: 'Sentry Access Token',\n envVar: 'SENTRY_ACCESS_TOKEN',\n placeholder: 'sntrys_...',\n required: true,\n },\n ],\n },\n\n docker: {\n id: 'docker',\n name: 'Docker',\n description: 'Gerencie containers e images',\n category: 'dev',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@0xshariq/docker-mcp-server'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== DESIGN =====\n figma: {\n id: 'figma',\n name: 'Figma Desktop',\n description: 'Acesse designs via app desktop local (sem OAuth)',\n category: 'design',\n config: {\n type: 'http',\n endpoint: 'http://127.0.0.1:3845/mcp',\n },\n credentials: [],\n },\n\n 'figma-remote': {\n id: 'figma-remote',\n name: 'Figma Remote (OAuth)',\n description: 'Servidor remoto Figma — requer cliente pré-aprovado',\n category: 'design',\n config: {\n type: 'http',\n endpoint: 'https://mcp.figma.com/mcp',\n },\n credentials: [],\n },\n\n // ===== DATA =====\n postgres: {\n id: 'postgres',\n name: 'PostgreSQL',\n description: 'Consulte bancos de dados',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-postgres'],\n env: {},\n },\n credentials: [\n {\n name: 'Database URL',\n envVar: '',\n placeholder: 'postgresql://user:pass@host/db',\n required: true,\n isArg: true,\n },\n ],\n },\n\n mongodb: {\n id: 'mongodb',\n name: 'MongoDB',\n description: 'Consulte coleções e documentos',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@mongodb-js/mongodb-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Connection String',\n envVar: 'MDB_MCP_CONNECTION_STRING',\n placeholder: 'mongodb+srv://...',\n required: true,\n },\n ],\n },\n\n redis: {\n id: 'redis',\n name: 'Redis',\n description: 'Cache e key-value store',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-redis'],\n env: {},\n },\n credentials: [\n {\n name: 'Redis URL',\n envVar: 'REDIS_URL',\n placeholder: 'redis://localhost:6379',\n required: true,\n },\n ],\n },\n\n supabase: {\n id: 'supabase',\n name: 'Supabase',\n description: 'Banco de dados e backend',\n category: 'data',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@cloud9-labs/mcp-supabase'],\n env: {},\n },\n credentials: [\n {\n name: 'Supabase URL',\n envVar: 'SUPABASE_URL',\n placeholder: 'https://xyz.supabase.co',\n required: true,\n },\n {\n name: 'Service Key',\n envVar: 'SUPABASE_SERVICE_KEY',\n placeholder: 'eyJ...',\n required: true,\n },\n ],\n },\n\n // ===== SEARCH =====\n 'brave-search': {\n id: 'brave-search',\n name: 'Brave Search',\n description: 'Busca na web',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n env: {},\n },\n credentials: [\n {\n name: 'Brave API Key',\n envVar: 'BRAVE_API_KEY',\n placeholder: 'BSA...',\n required: true,\n },\n ],\n },\n\n exa: {\n id: 'exa',\n name: 'Exa Search',\n description: 'Busca semântica na web',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'exa-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Exa API Key',\n envVar: 'EXA_API_KEY',\n placeholder: 'exa_...',\n required: true,\n },\n ],\n },\n\n perplexity: {\n id: 'perplexity',\n name: 'Perplexity',\n description: 'Busca com IA',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@perplexity-ai/mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Perplexity API Key',\n envVar: 'PERPLEXITY_API_KEY',\n placeholder: 'pplx-...',\n required: true,\n },\n ],\n },\n\n context7: {\n id: 'context7',\n name: 'Context7',\n description: 'Busca em documentações técnicas',\n category: 'search',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@upstash/context7-mcp'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== CLOUD =====\n vercel: {\n id: 'vercel',\n name: 'Vercel',\n description: 'Deploy e gerenciamento',\n category: 'cloud',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@vercel/mcp-adapter'],\n env: {},\n },\n credentials: [],\n },\n\n cloudflare: {\n id: 'cloudflare',\n name: 'Cloudflare',\n description: 'Workers, KV, R2',\n category: 'cloud',\n config: {\n type: 'http',\n endpoint: 'https://mcp.cloudflare.com',\n },\n credentials: [],\n },\n\n 'aws-s3': {\n id: 'aws-s3',\n name: 'AWS S3',\n description: 'Armazenamento de objetos',\n category: 'cloud',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'aws-s3-mcp'],\n env: {},\n },\n credentials: [\n {\n name: 'Access Key ID',\n envVar: 'AWS_ACCESS_KEY_ID',\n placeholder: 'AKIA...',\n required: true,\n },\n {\n name: 'Secret Access Key',\n envVar: 'AWS_SECRET_ACCESS_KEY',\n placeholder: 'xxx',\n required: true,\n },\n {\n name: 'Region',\n envVar: 'AWS_REGION',\n placeholder: 'us-east-1',\n required: true,\n },\n ],\n },\n\n // ===== PRODUCTIVITY =====\n slack: {\n id: 'slack',\n name: 'Slack',\n description: 'Envie mensagens e gerencie canais',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', 'slack-mcp-server@latest', '--transport', 'stdio'],\n env: {},\n },\n credentials: [\n {\n name: 'Slack Bot Token',\n envVar: 'SLACK_BOT_TOKEN',\n placeholder: 'xoxb-...',\n required: true,\n },\n {\n name: 'Team ID',\n envVar: 'SLACK_TEAM_ID',\n placeholder: 'T...',\n required: true,\n },\n ],\n },\n\n notion: {\n id: 'notion',\n name: 'Notion',\n description: 'Gerencie páginas e databases',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@notionhq/notion-mcp-server'],\n env: {},\n },\n credentials: [\n {\n name: 'Notion Token',\n envVar: 'NOTION_TOKEN',\n placeholder: 'secret_...',\n required: true,\n },\n ],\n },\n\n 'google-drive': {\n id: 'google-drive',\n name: 'Google Drive',\n description: 'Acesse arquivos e pastas (OAuth)',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-gdrive'],\n env: {},\n },\n credentials: [],\n },\n\n 'google-maps': {\n id: 'google-maps',\n name: 'Google Maps',\n description: 'Geocoding e rotas',\n category: 'productivity',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@googlemaps/code-assist-mcp@latest'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== PAYMENTS =====\n stripe: {\n id: 'stripe',\n name: 'Stripe',\n description: 'Pagamentos e assinaturas',\n category: 'payments',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@stripe/mcp', '--tools=all'],\n env: {},\n },\n credentials: [\n {\n name: 'Stripe Secret Key',\n envVar: 'STRIPE_SECRET_KEY',\n placeholder: 'sk_test_... ou rk_...',\n required: true,\n },\n ],\n },\n\n twilio: {\n id: 'twilio',\n name: 'Twilio',\n description: 'SMS e chamadas',\n category: 'payments',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@twilio-alpha/mcp'],\n env: {},\n },\n credentials: [\n {\n name: 'Account SID',\n envVar: '',\n placeholder: 'AC...',\n required: true,\n isArg: true,\n },\n {\n name: 'API Key:Secret',\n envVar: '',\n placeholder: 'SK...:...',\n required: true,\n isArg: true,\n },\n ],\n },\n\n // ===== BROWSER =====\n puppeteer: {\n id: 'puppeteer',\n name: 'Puppeteer',\n description: 'Automação de browser',\n category: 'browser',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-puppeteer'],\n env: {},\n },\n credentials: [],\n },\n\n // ===== FILESYSTEM =====\n filesystem: {\n id: 'filesystem',\n name: 'Filesystem',\n description: 'Acesse arquivos locais',\n category: 'filesystem',\n config: {\n type: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem'],\n env: {},\n },\n credentials: [\n {\n name: 'Diretório permitido',\n envVar: '',\n placeholder: '/caminho/para/diretório',\n required: true,\n isArg: true,\n },\n ],\n },\n};\n\nexport function getTemplatesByCategory(category: McpCategory): McpTemplate[] {\n return Object.values(MCP_TEMPLATES).filter(t => t.category === category);\n}\n\nexport function getAllTemplates(): McpTemplate[] {\n return Object.values(MCP_TEMPLATES);\n}\n\nexport function getTemplate(id: string): McpTemplate | undefined {\n return MCP_TEMPLATES[id];\n}\n"],"names":["MCP_TEMPLATES","getAllTemplates","getTemplate","getTemplatesByCategory","github","id","name","description","category","config","type","command","args","env","credentials","envVar","placeholder","required","linear","jira","sentry","EMBEDDED_AGENT_PROVIDER","docker","figma","endpoint","postgres","isArg","mongodb","redis","supabase","exa","perplexity","context7","vercel","cloudflare","slack","notion","stripe","twilio","puppeteer","filesystem","Object","values","filter","t"],"mappings":"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"}
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CastOAuthProvider", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CastOAuthProvider;
9
+ }
10
+ });
11
+ const _fs = /*#__PURE__*/ _interop_require_wildcard(require("fs"));
12
+ const _path = /*#__PURE__*/ _interop_require_wildcard(require("path"));
13
+ const _http = /*#__PURE__*/ _interop_require_wildcard(require("http"));
14
+ const _os = require("os");
15
+ const _child_process = require("child_process");
16
+ function _getRequireWildcardCache(nodeInterop) {
17
+ if (typeof WeakMap !== "function") return null;
18
+ var cacheBabelInterop = new WeakMap();
19
+ var cacheNodeInterop = new WeakMap();
20
+ return (_getRequireWildcardCache = function(nodeInterop) {
21
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
22
+ })(nodeInterop);
23
+ }
24
+ function _interop_require_wildcard(obj, nodeInterop) {
25
+ if (!nodeInterop && obj && obj.__esModule) {
26
+ return obj;
27
+ }
28
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
29
+ return {
30
+ default: obj
31
+ };
32
+ }
33
+ var cache = _getRequireWildcardCache(nodeInterop);
34
+ if (cache && cache.has(obj)) {
35
+ return cache.get(obj);
36
+ }
37
+ var newObj = {
38
+ __proto__: null
39
+ };
40
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
41
+ for(var key in obj){
42
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
43
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
44
+ if (desc && (desc.get || desc.set)) {
45
+ Object.defineProperty(newObj, key, desc);
46
+ } else {
47
+ newObj[key] = obj[key];
48
+ }
49
+ }
50
+ }
51
+ newObj.default = obj;
52
+ if (cache) {
53
+ cache.set(obj, newObj);
54
+ }
55
+ return newObj;
56
+ }
57
+ const CAST_AUTH_DIR = _path.join((0, _os.homedir)(), '.cast', 'mcp-auth');
58
+ let CastOAuthProvider = class CastOAuthProvider {
59
+ get redirectUrl() {
60
+ return `http://127.0.0.1:${this.port}/callback`;
61
+ }
62
+ get clientMetadata() {
63
+ return {
64
+ client_name: 'Cast Code',
65
+ redirect_uris: [
66
+ this.redirectUrl
67
+ ],
68
+ grant_types: [
69
+ 'authorization_code',
70
+ 'refresh_token'
71
+ ],
72
+ response_types: [
73
+ 'code'
74
+ ],
75
+ token_endpoint_auth_method: 'none'
76
+ };
77
+ }
78
+ clientInformation() {
79
+ const file = _path.join(this.authDir, 'client.json');
80
+ if (!_fs.existsSync(file)) return undefined;
81
+ try {
82
+ return JSON.parse(_fs.readFileSync(file, 'utf-8'));
83
+ } catch {
84
+ return undefined;
85
+ }
86
+ }
87
+ saveClientInformation(info) {
88
+ _fs.writeFileSync(_path.join(this.authDir, 'client.json'), JSON.stringify(info, null, 2));
89
+ }
90
+ tokens() {
91
+ const file = _path.join(this.authDir, 'tokens.json');
92
+ if (!_fs.existsSync(file)) return undefined;
93
+ try {
94
+ return JSON.parse(_fs.readFileSync(file, 'utf-8'));
95
+ } catch {
96
+ return undefined;
97
+ }
98
+ }
99
+ saveTokens(tokens) {
100
+ _fs.writeFileSync(_path.join(this.authDir, 'tokens.json'), JSON.stringify(tokens, null, 2));
101
+ }
102
+ redirectToAuthorization(url) {
103
+ try {
104
+ (0, _child_process.spawn)('xdg-open', [
105
+ url.toString()
106
+ ], {
107
+ detached: true,
108
+ stdio: 'ignore'
109
+ }).unref();
110
+ } catch {
111
+ // Silently ignore if xdg-open is not available
112
+ }
113
+ }
114
+ saveCodeVerifier(verifier) {
115
+ _fs.writeFileSync(_path.join(this.authDir, 'verifier.txt'), verifier);
116
+ }
117
+ codeVerifier() {
118
+ const file = _path.join(this.authDir, 'verifier.txt');
119
+ if (!_fs.existsSync(file)) throw new Error(`No PKCE code verifier saved for ${this.serverName}`);
120
+ return _fs.readFileSync(file, 'utf-8');
121
+ }
122
+ invalidateCredentials(scope) {
123
+ const remove = (name)=>{
124
+ const f = _path.join(this.authDir, name);
125
+ if (_fs.existsSync(f)) _fs.unlinkSync(f);
126
+ };
127
+ if (scope === 'all' || scope === 'tokens') remove('tokens.json');
128
+ if (scope === 'all' || scope === 'client') remove('client.json');
129
+ if (scope === 'all' || scope === 'verifier') remove('verifier.txt');
130
+ }
131
+ /**
132
+ * Starts a local HTTP server on the callback port.
133
+ * Returns a Promise that resolves with the authorization code when the user
134
+ * completes the OAuth flow in their browser.
135
+ *
136
+ * @param onListening Optional callback fired when the server is ready (before opening browser)
137
+ */ waitForCallback(onListening) {
138
+ return new Promise((resolve, reject)=>{
139
+ const server = _http.createServer((req, res)=>{
140
+ try {
141
+ const url = new URL(req.url ?? '/', `http://127.0.0.1:${this.port}`);
142
+ const code = url.searchParams.get('code');
143
+ const error = url.searchParams.get('error');
144
+ const successHtml = `
145
+ <html><body style="font-family:sans-serif;text-align:center;padding:40px;background:#f0fdf4">
146
+ <h2 style="color:#16a34a">✅ Autenticação concluída!</h2>
147
+ <p>Pode fechar esta aba e voltar ao terminal.</p>
148
+ </body></html>`;
149
+ const errorHtml = `
150
+ <html><body style="font-family:sans-serif;text-align:center;padding:40px;background:#fef2f2">
151
+ <h2 style="color:#dc2626">❌ Erro na autenticação</h2>
152
+ <p>${error ?? 'Erro desconhecido'}</p>
153
+ </body></html>`;
154
+ res.writeHead(200, {
155
+ 'Content-Type': 'text/html; charset=utf-8'
156
+ });
157
+ if (code) {
158
+ res.end(successHtml);
159
+ server.close();
160
+ resolve(code);
161
+ } else {
162
+ res.end(errorHtml);
163
+ server.close();
164
+ reject(new Error(`OAuth error: ${error ?? 'unknown'}`));
165
+ }
166
+ } catch (e) {
167
+ server.close();
168
+ reject(e);
169
+ }
170
+ });
171
+ server.on('error', (err)=>reject(err));
172
+ server.listen(this.port, '127.0.0.1', ()=>{
173
+ if (onListening) onListening();
174
+ });
175
+ });
176
+ }
177
+ constructor(serverName, port = 18090){
178
+ this.serverName = serverName;
179
+ this.authDir = _path.join(CAST_AUTH_DIR, serverName);
180
+ this.port = port;
181
+ _fs.mkdirSync(this.authDir, {
182
+ recursive: true
183
+ });
184
+ }
185
+ };
186
+
187
+ //# sourceMappingURL=cast-oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/mcp/services/cast-oauth-provider.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as http from 'http';\nimport { homedir } from 'os';\nimport { spawn } from 'child_process';\nimport type {\n OAuthClientProvider,\n OAuthClientMetadata,\n OAuthClientInformationMixed,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/client/auth.js';\n\nconst CAST_AUTH_DIR = path.join(homedir(), '.cast', 'mcp-auth');\n\n/**\n * Implements OAuthClientProvider for cast-code CLI.\n * Stores tokens and client info in ~/.cast/mcp-auth/<serverName>/\n */\nexport class CastOAuthProvider implements OAuthClientProvider {\n private readonly authDir: string;\n private readonly port: number;\n\n constructor(\n private readonly serverName: string,\n port = 18090,\n ) {\n this.authDir = path.join(CAST_AUTH_DIR, serverName);\n this.port = port;\n fs.mkdirSync(this.authDir, { recursive: true });\n }\n\n get redirectUrl(): string {\n return `http://127.0.0.1:${this.port}/callback`;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: 'Cast Code',\n redirect_uris: [this.redirectUrl],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method: 'none',\n };\n }\n\n clientInformation(): OAuthClientInformationMixed | undefined {\n const file = path.join(this.authDir, 'client.json');\n if (!fs.existsSync(file)) return undefined;\n try {\n return JSON.parse(fs.readFileSync(file, 'utf-8'));\n } catch {\n return undefined;\n }\n }\n\n saveClientInformation(info: OAuthClientInformationMixed): void {\n fs.writeFileSync(\n path.join(this.authDir, 'client.json'),\n JSON.stringify(info, null, 2),\n );\n }\n\n tokens(): OAuthTokens | undefined {\n const file = path.join(this.authDir, 'tokens.json');\n if (!fs.existsSync(file)) return undefined;\n try {\n return JSON.parse(fs.readFileSync(file, 'utf-8'));\n } catch {\n return undefined;\n }\n }\n\n saveTokens(tokens: OAuthTokens): void {\n fs.writeFileSync(\n path.join(this.authDir, 'tokens.json'),\n JSON.stringify(tokens, null, 2),\n );\n }\n\n redirectToAuthorization(url: URL): void {\n try {\n spawn('xdg-open', [url.toString()], { detached: true, stdio: 'ignore' }).unref();\n } catch {\n // Silently ignore if xdg-open is not available\n }\n }\n\n saveCodeVerifier(verifier: string): void {\n fs.writeFileSync(path.join(this.authDir, 'verifier.txt'), verifier);\n }\n\n codeVerifier(): string {\n const file = path.join(this.authDir, 'verifier.txt');\n if (!fs.existsSync(file)) throw new Error(`No PKCE code verifier saved for ${this.serverName}`);\n return fs.readFileSync(file, 'utf-8');\n }\n\n invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier'): void {\n const remove = (name: string) => {\n const f = path.join(this.authDir, name);\n if (fs.existsSync(f)) fs.unlinkSync(f);\n };\n if (scope === 'all' || scope === 'tokens') remove('tokens.json');\n if (scope === 'all' || scope === 'client') remove('client.json');\n if (scope === 'all' || scope === 'verifier') remove('verifier.txt');\n }\n\n /**\n * Starts a local HTTP server on the callback port.\n * Returns a Promise that resolves with the authorization code when the user\n * completes the OAuth flow in their browser.\n *\n * @param onListening Optional callback fired when the server is ready (before opening browser)\n */\n waitForCallback(onListening?: () => void): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const server = http.createServer((req, res) => {\n try {\n const url = new URL(req.url ?? '/', `http://127.0.0.1:${this.port}`);\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n\n const successHtml = `\n <html><body style=\"font-family:sans-serif;text-align:center;padding:40px;background:#f0fdf4\">\n <h2 style=\"color:#16a34a\">✅ Autenticação concluída!</h2>\n <p>Pode fechar esta aba e voltar ao terminal.</p>\n </body></html>`;\n\n const errorHtml = `\n <html><body style=\"font-family:sans-serif;text-align:center;padding:40px;background:#fef2f2\">\n <h2 style=\"color:#dc2626\">❌ Erro na autenticação</h2>\n <p>${error ?? 'Erro desconhecido'}</p>\n </body></html>`;\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n\n if (code) {\n res.end(successHtml);\n server.close();\n resolve(code);\n } else {\n res.end(errorHtml);\n server.close();\n reject(new Error(`OAuth error: ${error ?? 'unknown'}`));\n }\n } catch (e) {\n server.close();\n reject(e);\n }\n });\n\n server.on('error', (err) => reject(err));\n server.listen(this.port, '127.0.0.1', () => {\n if (onListening) onListening();\n });\n });\n }\n}\n"],"names":["CastOAuthProvider","CAST_AUTH_DIR","path","join","homedir","redirectUrl","port","clientMetadata","client_name","redirect_uris","grant_types","response_types","token_endpoint_auth_method","clientInformation","file","authDir","fs","existsSync","undefined","JSON","parse","readFileSync","saveClientInformation","info","writeFileSync","stringify","tokens","saveTokens","redirectToAuthorization","url","spawn","toString","detached","stdio","unref","saveCodeVerifier","verifier","codeVerifier","Error","serverName","invalidateCredentials","scope","remove","name","f","unlinkSync","waitForCallback","onListening","Promise","resolve","reject","server","http","createServer","req","res","URL","code","searchParams","get","error","successHtml","errorHtml","writeHead","end","close","e","on","err","listen","mkdirSync","recursive"],"mappings":"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"}
@@ -11,6 +11,8 @@ Object.defineProperty(exports, "McpClientService", {
11
11
  const _common = require("@nestjs/common");
12
12
  const _events = require("events");
13
13
  const _child_process = require("child_process");
14
+ const _auth = require("@modelcontextprotocol/sdk/client/auth.js");
15
+ const _castoauthprovider = require("./cast-oauth-provider");
14
16
  function _ts_decorate(decorators, target, key, desc) {
15
17
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
18
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -103,59 +105,86 @@ let McpClientService = class McpClientService extends _events.EventEmitter {
103
105
  }
104
106
  async connectHttp(name, connection) {
105
107
  const endpoint = connection.config.endpoint;
106
- const headers = {
107
- 'Content-Type': 'application/json'
108
- };
109
- if (connection.config.env?.AUTH_TOKEN) {
110
- headers['Authorization'] = `Bearer ${connection.config.env.AUTH_TOKEN}`;
111
- }
112
108
  try {
113
109
  new URL(endpoint);
114
110
  } catch {
115
111
  throw new Error(`Invalid MCP HTTP endpoint: ${endpoint}`);
116
112
  }
117
- const controller = new AbortController();
118
- const timeout = setTimeout(()=>controller.abort(), 10000);
119
- const initResponse = await fetch(endpoint, {
120
- method: 'POST',
121
- headers,
122
- body: JSON.stringify({
123
- jsonrpc: '2.0',
124
- id: this.nextId(),
125
- method: 'initialize',
126
- params: {
127
- protocolVersion: '2024-11-05',
128
- capabilities: {},
129
- clientInfo: {
130
- name: 'cast-code',
131
- version: '1.0.0'
132
- }
113
+ const headers = {
114
+ 'Content-Type': 'application/json'
115
+ };
116
+ const provider = new _castoauthprovider.CastOAuthProvider(name);
117
+ const cachedTokens = provider.tokens();
118
+ if (cachedTokens?.access_token) {
119
+ headers['Authorization'] = `Bearer ${cachedTokens.access_token}`;
120
+ }
121
+ const doFetch = async (body, hdrs = headers, timeoutMs = 15000)=>{
122
+ const controller = new AbortController();
123
+ const timer = setTimeout(()=>controller.abort(), timeoutMs);
124
+ try {
125
+ return await fetch(endpoint, {
126
+ method: 'POST',
127
+ headers: hdrs,
128
+ body: JSON.stringify(body),
129
+ signal: controller.signal
130
+ });
131
+ } finally{
132
+ clearTimeout(timer);
133
+ }
134
+ };
135
+ const initBody = {
136
+ jsonrpc: '2.0',
137
+ id: this.nextId(),
138
+ method: 'initialize',
139
+ params: {
140
+ protocolVersion: '2024-11-05',
141
+ capabilities: {},
142
+ clientInfo: {
143
+ name: 'cast-code',
144
+ version: '1.0.0'
133
145
  }
134
- }),
135
- signal: controller.signal
136
- });
137
- clearTimeout(timeout);
146
+ }
147
+ };
148
+ let initResponse = await doFetch(initBody);
149
+ if (initResponse.status === 401) {
150
+ provider.invalidateCredentials('tokens');
151
+ let authResult = await (0, _auth.auth)(provider, {
152
+ serverUrl: endpoint
153
+ });
154
+ if (authResult === 'REDIRECT') {
155
+ this.emit('oauth:browser-opened', name, provider.redirectUrl);
156
+ const code = await provider.waitForCallback();
157
+ authResult = await (0, _auth.auth)(provider, {
158
+ serverUrl: endpoint,
159
+ authorizationCode: code
160
+ });
161
+ }
162
+ if (authResult !== 'AUTHORIZED') {
163
+ throw new Error(`OAuth failed for ${name}`);
164
+ }
165
+ const tokens = provider.tokens();
166
+ if (!tokens?.access_token) {
167
+ throw new Error(`No access token for ${name} after OAuth`);
168
+ }
169
+ headers['Authorization'] = `Bearer ${tokens.access_token}`;
170
+ initResponse = await doFetch(initBody);
171
+ }
138
172
  if (!initResponse.ok) {
139
173
  throw new Error(`HTTP MCP init failed: ${initResponse.status} ${initResponse.statusText}`);
140
174
  }
141
- const toolsController = new AbortController();
142
- const toolsTimeout = setTimeout(()=>toolsController.abort(), 10000);
143
- const toolsResponse = await fetch(endpoint, {
144
- method: 'POST',
145
- headers,
146
- body: JSON.stringify({
147
- jsonrpc: '2.0',
148
- id: this.nextId(),
149
- method: 'tools/list',
150
- params: {}
151
- }),
152
- signal: toolsController.signal
175
+ const sessionId = initResponse.headers.get('mcp-session-id');
176
+ if (sessionId) headers['Mcp-Session-Id'] = sessionId;
177
+ const toolsResponse = await doFetch({
178
+ jsonrpc: '2.0',
179
+ id: this.nextId(),
180
+ method: 'tools/list',
181
+ params: {}
153
182
  });
154
- clearTimeout(toolsTimeout);
155
183
  if (toolsResponse.ok) {
156
184
  const data = await toolsResponse.json();
157
185
  connection.tools = data.result?.tools || data.tools || [];
158
186
  }
187
+ connection._httpHeaders = headers;
159
188
  }
160
189
  sendRequest(name, method, params) {
161
190
  const connection = this.connections.get(name);
@@ -202,12 +231,9 @@ let McpClientService = class McpClientService extends _events.EventEmitter {
202
231
  }
203
232
  if (connection.config.type === 'http') {
204
233
  const endpoint = connection.config.endpoint;
205
- const headers = {
234
+ const headers = connection._httpHeaders ?? {
206
235
  'Content-Type': 'application/json'
207
236
  };
208
- if (connection.config.env?.AUTH_TOKEN) {
209
- headers['Authorization'] = `Bearer ${connection.config.env.AUTH_TOKEN}`;
210
- }
211
237
  const response = await fetch(endpoint, {
212
238
  method: 'POST',
213
239
  headers,
@@ -232,6 +258,9 @@ let McpClientService = class McpClientService extends _events.EventEmitter {
232
258
  getStatus(name) {
233
259
  return this.connections.get(name)?.status || 'unknown';
234
260
  }
261
+ getAuthUrl(name) {
262
+ return this.connections.get(name)?.authUrl;
263
+ }
235
264
  getAllStatuses() {
236
265
  const statuses = new Map();
237
266
  for (const [name, conn] of this.connections){
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/mcp/services/mcp-client.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { EventEmitter } from 'events';\nimport { spawn, ChildProcess } from 'child_process';\nimport { McpConfig, McpTool, McpConnection } from '../types';\n\n@Injectable()\nexport class McpClientService extends EventEmitter {\n private connections: Map<string, McpConnection> = new Map();\n private stdioBuffers: Map<string, string> = new Map();\n private requestIdCounter = 0;\n\n async connect(name: string, config: McpConfig): Promise<boolean> {\n if (this.connections.has(name)) {\n const existing = this.connections.get(name)!;\n if (existing.status === 'connected') {\n return true;\n }\n }\n\n const connection: McpConnection = {\n config,\n tools: [],\n status: 'connecting',\n };\n\n this.connections.set(name, connection);\n\n try {\n if (config.type === 'stdio' && config.command) {\n await this.connectStdio(name, connection);\n } else if (config.type === 'sse' && config.endpoint) {\n throw new Error('SSE transport not yet supported. Use stdio or http instead.');\n } else if (config.type === 'http' && config.endpoint) {\n await this.connectHttp(name, connection);\n }\n\n connection.status = 'connected';\n return true;\n } catch (error) {\n connection.status = 'error';\n return false;\n }\n }\n\n private async connectStdio(name: string, connection: McpConnection): Promise<void> {\n const { command, args = [], env = {} } = connection.config;\n\n const proc = spawn(command!, args, {\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n connection.process = proc;\n this.stdioBuffers.set(name, '');\n\n proc.stdout?.on('data', (data: Buffer) => {\n const buffer = (this.stdioBuffers.get(name) || '') + data.toString();\n const lines = buffer.split('\\n');\n\n this.stdioBuffers.set(name, lines.pop() || '');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const parsed = JSON.parse(trimmed);\n this.emit(`response:${name}`, parsed);\n } catch {\n }\n }\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (msg && !msg.startsWith('Debugger') && !msg.startsWith('Warning')) {\n console.error(`MCP ${name} stderr:`, msg);\n }\n });\n\n proc.on('close', (code) => {\n connection.status = 'disconnected';\n this.stdioBuffers.delete(name);\n this.emit('disconnected', name);\n\n if (code !== null && code !== 0) {\n setTimeout(() => {\n this.reconnect(name).catch(() => {});\n }, 3000);\n }\n });\n\n await this.sendRequest(name, 'initialize', {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'cast-code', version: '1.0.0' },\n });\n\n const toolsResponse = await this.sendRequest(name, 'tools/list', {});\n connection.tools = toolsResponse?.tools || [];\n }\n\n private async connectHttp(name: string, connection: McpConnection): Promise<void> {\n const endpoint = connection.config.endpoint!;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (connection.config.env?.AUTH_TOKEN) {\n headers['Authorization'] = `Bearer ${connection.config.env.AUTH_TOKEN}`;\n }\n\n try {\n new URL(endpoint);\n } catch {\n throw new Error(`Invalid MCP HTTP endpoint: ${endpoint}`);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10000);\n\n const initResponse = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'initialize',\n params: {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'cast-code', version: '1.0.0' },\n },\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!initResponse.ok) {\n throw new Error(`HTTP MCP init failed: ${initResponse.status} ${initResponse.statusText}`);\n }\n\n const toolsController = new AbortController();\n const toolsTimeout = setTimeout(() => toolsController.abort(), 10000);\n\n const toolsResponse = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'tools/list',\n params: {},\n }),\n signal: toolsController.signal,\n });\n\n clearTimeout(toolsTimeout);\n\n if (toolsResponse.ok) {\n const data = await toolsResponse.json();\n connection.tools = data.result?.tools || data.tools || [];\n }\n }\n\n private sendRequest(\n name: string,\n method: string,\n params: Record<string, unknown>,\n ): Promise<any> {\n const connection = this.connections.get(name);\n\n if (!connection?.process) {\n return Promise.resolve(null);\n }\n\n return new Promise((resolve) => {\n const id = this.nextId();\n const request = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n let resolved = false;\n\n const handler = (response: any) => {\n if (response.id === id && !resolved) {\n resolved = true;\n this.off(`response:${name}`, handler);\n resolve(response.result);\n }\n };\n\n this.on(`response:${name}`, handler);\n (connection.process as ChildProcess).stdin?.write(request + '\\n');\n\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n this.off(`response:${name}`, handler);\n resolve(null);\n }\n }, 15000);\n });\n }\n\n async callTool(\n mcpName: string,\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<any> {\n const connection = this.connections.get(mcpName);\n\n if (!connection || connection.status !== 'connected') {\n throw new Error(`MCP ${mcpName} not connected`);\n }\n\n if (connection.config.type === 'stdio') {\n return this.sendRequest(mcpName, 'tools/call', { name: toolName, arguments: args });\n }\n\n if (connection.config.type === 'http') {\n const endpoint = connection.config.endpoint!;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (connection.config.env?.AUTH_TOKEN) {\n headers['Authorization'] = `Bearer ${connection.config.env.AUTH_TOKEN}`;\n }\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'tools/call',\n params: { name: toolName, arguments: args },\n }),\n });\n\n const data = await response.json();\n return data.result || data;\n }\n\n return null;\n }\n\n getTools(name: string): McpTool[] {\n return this.connections.get(name)?.tools || [];\n }\n\n getStatus(name: string): string {\n return this.connections.get(name)?.status || 'unknown';\n }\n\n getAllStatuses(): Map<string, string> {\n const statuses = new Map<string, string>();\n for (const [name, conn] of this.connections) {\n statuses.set(name, conn.status);\n }\n return statuses;\n }\n\n private async reconnect(name: string): Promise<boolean> {\n const connection = this.connections.get(name);\n if (!connection) return false;\n\n if (connection.process) {\n try {\n (connection.process as ChildProcess).kill();\n } catch {}\n }\n\n connection.status = 'connecting';\n try {\n if (connection.config.type === 'stdio') {\n await this.connectStdio(name, connection);\n } else if (connection.config.type === 'http') {\n await this.connectHttp(name, connection);\n }\n connection.status = 'connected';\n this.emit('reconnected', name);\n return true;\n } catch {\n connection.status = 'error';\n return false;\n }\n }\n\n disconnect(name: string) {\n const connection = this.connections.get(name);\n\n if (connection?.process) {\n (connection.process as ChildProcess).kill();\n }\n\n this.stdioBuffers.delete(name);\n this.connections.delete(name);\n }\n\n disconnectAll() {\n for (const name of this.connections.keys()) {\n this.disconnect(name);\n }\n }\n\n private nextId(): string {\n return `${++this.requestIdCounter}`;\n }\n}\n"],"names":["McpClientService","EventEmitter","connect","name","config","connections","has","existing","get","status","connection","tools","set","type","command","connectStdio","endpoint","Error","connectHttp","error","args","env","proc","spawn","process","stdio","stdioBuffers","stdout","on","data","buffer","toString","lines","split","pop","line","trimmed","trim","parsed","JSON","parse","emit","stderr","msg","startsWith","console","code","delete","setTimeout","reconnect","catch","sendRequest","protocolVersion","capabilities","clientInfo","version","toolsResponse","headers","AUTH_TOKEN","URL","controller","AbortController","timeout","abort","initResponse","fetch","method","body","stringify","jsonrpc","id","nextId","params","signal","clearTimeout","ok","statusText","toolsController","toolsTimeout","json","result","Promise","resolve","request","resolved","handler","response","off","stdin","write","callTool","mcpName","toolName","arguments","getTools","getStatus","getAllStatuses","statuses","Map","conn","kill","disconnect","disconnectAll","keys","requestIdCounter"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/modules/mcp/services/mcp-client.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { EventEmitter } from 'events';\nimport { spawn, ChildProcess } from 'child_process';\nimport { McpConfig, McpTool, McpConnection } from '../types';\nimport { auth } from '@modelcontextprotocol/sdk/client/auth.js';\nimport { CastOAuthProvider } from './cast-oauth-provider';\n\n@Injectable()\nexport class McpClientService extends EventEmitter {\n private connections: Map<string, McpConnection> = new Map();\n private stdioBuffers: Map<string, string> = new Map();\n private requestIdCounter = 0;\n\n async connect(name: string, config: McpConfig): Promise<boolean> {\n if (this.connections.has(name)) {\n const existing = this.connections.get(name)!;\n if (existing.status === 'connected') {\n return true;\n }\n }\n\n const connection: McpConnection = {\n config,\n tools: [],\n status: 'connecting',\n };\n\n this.connections.set(name, connection);\n\n try {\n if (config.type === 'stdio' && config.command) {\n await this.connectStdio(name, connection);\n } else if (config.type === 'sse' && config.endpoint) {\n throw new Error('SSE transport not yet supported. Use stdio or http instead.');\n } else if (config.type === 'http' && config.endpoint) {\n await this.connectHttp(name, connection);\n }\n\n connection.status = 'connected';\n return true;\n } catch (error) {\n connection.status = 'error';\n return false;\n }\n }\n\n private async connectStdio(name: string, connection: McpConnection): Promise<void> {\n const { command, args = [], env = {} } = connection.config;\n\n const proc = spawn(command!, args, {\n env: { ...process.env, ...env },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n connection.process = proc;\n this.stdioBuffers.set(name, '');\n\n proc.stdout?.on('data', (data: Buffer) => {\n const buffer = (this.stdioBuffers.get(name) || '') + data.toString();\n const lines = buffer.split('\\n');\n\n this.stdioBuffers.set(name, lines.pop() || '');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const parsed = JSON.parse(trimmed);\n this.emit(`response:${name}`, parsed);\n } catch {\n }\n }\n });\n\n proc.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (msg && !msg.startsWith('Debugger') && !msg.startsWith('Warning')) {\n console.error(`MCP ${name} stderr:`, msg);\n }\n });\n\n proc.on('close', (code) => {\n connection.status = 'disconnected';\n this.stdioBuffers.delete(name);\n this.emit('disconnected', name);\n\n if (code !== null && code !== 0) {\n setTimeout(() => {\n this.reconnect(name).catch(() => {});\n }, 3000);\n }\n });\n\n await this.sendRequest(name, 'initialize', {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'cast-code', version: '1.0.0' },\n });\n\n const toolsResponse = await this.sendRequest(name, 'tools/list', {});\n connection.tools = toolsResponse?.tools || [];\n }\n\n private async connectHttp(name: string, connection: McpConnection): Promise<void> {\n const endpoint = connection.config.endpoint!;\n\n try {\n new URL(endpoint);\n } catch {\n throw new Error(`Invalid MCP HTTP endpoint: ${endpoint}`);\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\n const provider = new CastOAuthProvider(name);\n const cachedTokens = provider.tokens();\n if (cachedTokens?.access_token) {\n headers['Authorization'] = `Bearer ${cachedTokens.access_token}`;\n }\n\n const doFetch = async (body: object, hdrs = headers, timeoutMs = 15000): Promise<Response> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetch(endpoint, {\n method: 'POST',\n headers: hdrs,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n };\n\n const initBody = {\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'initialize',\n params: {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'cast-code', version: '1.0.0' },\n },\n };\n\n let initResponse = await doFetch(initBody);\n\n if (initResponse.status === 401) {\n provider.invalidateCredentials('tokens');\n\n let authResult = await auth(provider, { serverUrl: endpoint });\n\n if (authResult === 'REDIRECT') {\n this.emit('oauth:browser-opened', name, provider.redirectUrl);\n const code = await provider.waitForCallback();\n authResult = await auth(provider, { serverUrl: endpoint, authorizationCode: code });\n }\n\n if (authResult !== 'AUTHORIZED') {\n throw new Error(`OAuth failed for ${name}`);\n }\n\n const tokens = provider.tokens();\n if (!tokens?.access_token) {\n throw new Error(`No access token for ${name} after OAuth`);\n }\n\n headers['Authorization'] = `Bearer ${tokens.access_token}`;\n initResponse = await doFetch(initBody);\n }\n\n if (!initResponse.ok) {\n throw new Error(`HTTP MCP init failed: ${initResponse.status} ${initResponse.statusText}`);\n }\n\n const sessionId = initResponse.headers.get('mcp-session-id');\n if (sessionId) headers['Mcp-Session-Id'] = sessionId;\n\n const toolsResponse = await doFetch({\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'tools/list',\n params: {},\n });\n\n if (toolsResponse.ok) {\n const data = await toolsResponse.json();\n connection.tools = data.result?.tools || data.tools || [];\n }\n\n (connection as any)._httpHeaders = headers;\n }\n\n private sendRequest(\n name: string,\n method: string,\n params: Record<string, unknown>,\n ): Promise<any> {\n const connection = this.connections.get(name);\n\n if (!connection?.process) {\n return Promise.resolve(null);\n }\n\n return new Promise((resolve) => {\n const id = this.nextId();\n const request = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n let resolved = false;\n\n const handler = (response: any) => {\n if (response.id === id && !resolved) {\n resolved = true;\n this.off(`response:${name}`, handler);\n resolve(response.result);\n }\n };\n\n this.on(`response:${name}`, handler);\n (connection.process as ChildProcess).stdin?.write(request + '\\n');\n\n setTimeout(() => {\n if (!resolved) {\n resolved = true;\n this.off(`response:${name}`, handler);\n resolve(null);\n }\n }, 15000);\n });\n }\n\n async callTool(\n mcpName: string,\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<any> {\n const connection = this.connections.get(mcpName);\n\n if (!connection || connection.status !== 'connected') {\n throw new Error(`MCP ${mcpName} not connected`);\n }\n\n if (connection.config.type === 'stdio') {\n return this.sendRequest(mcpName, 'tools/call', { name: toolName, arguments: args });\n }\n\n if (connection.config.type === 'http') {\n const endpoint = connection.config.endpoint!;\n const headers: Record<string, string> = (connection as any)._httpHeaders ?? {\n 'Content-Type': 'application/json',\n };\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId(),\n method: 'tools/call',\n params: { name: toolName, arguments: args },\n }),\n });\n\n const data = await response.json();\n return data.result || data;\n }\n\n return null;\n }\n\n getTools(name: string): McpTool[] {\n return this.connections.get(name)?.tools || [];\n }\n\n getStatus(name: string): string {\n return this.connections.get(name)?.status || 'unknown';\n }\n\n getAuthUrl(name: string): string | undefined {\n return this.connections.get(name)?.authUrl;\n }\n\n getAllStatuses(): Map<string, string> {\n const statuses = new Map<string, string>();\n for (const [name, conn] of this.connections) {\n statuses.set(name, conn.status);\n }\n return statuses;\n }\n\n private async reconnect(name: string): Promise<boolean> {\n const connection = this.connections.get(name);\n if (!connection) return false;\n\n if (connection.process) {\n try {\n (connection.process as ChildProcess).kill();\n } catch {}\n }\n\n connection.status = 'connecting';\n try {\n if (connection.config.type === 'stdio') {\n await this.connectStdio(name, connection);\n } else if (connection.config.type === 'http') {\n await this.connectHttp(name, connection);\n }\n connection.status = 'connected';\n this.emit('reconnected', name);\n return true;\n } catch {\n connection.status = 'error';\n return false;\n }\n }\n\n disconnect(name: string) {\n const connection = this.connections.get(name);\n\n if (connection?.process) {\n (connection.process as ChildProcess).kill();\n }\n\n this.stdioBuffers.delete(name);\n this.connections.delete(name);\n }\n\n disconnectAll() {\n for (const name of this.connections.keys()) {\n this.disconnect(name);\n }\n }\n\n private nextId(): string {\n return `${++this.requestIdCounter}`;\n }\n}\n"],"names":["McpClientService","EventEmitter","connect","name","config","connections","has","existing","get","status","connection","tools","set","type","command","connectStdio","endpoint","Error","connectHttp","error","args","env","proc","spawn","process","stdio","stdioBuffers","stdout","on","data","buffer","toString","lines","split","pop","line","trimmed","trim","parsed","JSON","parse","emit","stderr","msg","startsWith","console","code","delete","setTimeout","reconnect","catch","sendRequest","protocolVersion","capabilities","clientInfo","version","toolsResponse","URL","headers","provider","CastOAuthProvider","cachedTokens","tokens","access_token","doFetch","body","hdrs","timeoutMs","controller","AbortController","timer","abort","fetch","method","stringify","signal","clearTimeout","initBody","jsonrpc","id","nextId","params","initResponse","invalidateCredentials","authResult","auth","serverUrl","redirectUrl","waitForCallback","authorizationCode","ok","statusText","sessionId","json","result","_httpHeaders","Promise","resolve","request","resolved","handler","response","off","stdin","write","callTool","mcpName","toolName","arguments","getTools","getStatus","getAuthUrl","authUrl","getAllStatuses","statuses","Map","conn","kill","disconnect","disconnectAll","keys","requestIdCounter"],"mappings":"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"}