mcp-booster
Version:
Servidor MCP com CoConuT (Continuous Chain of Thought) para uso com Cursor IDE - Pacote Global NPM
764 lines (763 loc) • 34.6 kB
JavaScript
"use strict";
/**
* MCP-Booster - Servidor MCP
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getApiKey = exports.setApiKey = exports.getConfig = exports.updateConfig = void 0;
exports.initializeServer = initializeServer;
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const coconut_1 = require("./modules/coconut");
const booster_steps_1 = require("./modules/booster-steps");
const types_1 = require("./modules/types");
const logger_1 = require("./modules/logger");
const config_1 = require("./config");
Object.defineProperty(exports, "updateConfig", { enumerable: true, get: function () { return config_1.updateConfig; } });
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_1.getConfig; } });
Object.defineProperty(exports, "setApiKey", { enumerable: true, get: function () { return config_1.setApiKey; } });
Object.defineProperty(exports, "getApiKey", { enumerable: true, get: function () { return config_1.getApiKey; } });
const zod_1 = require("zod");
const open_1 = __importDefault(require("open"));
// Instância do logger
let logger;
// Instância do servidor MCP
let server = null;
// Instância do serviço CoConuT_Storage
let coconutService = null;
// Instância do serviço Booster_Steps
let boosterStepsService = null;
// Estado global para as funções lambda
let coconutState = {
thoughtHistory: [],
interactionCount: 0,
branches: { 'main': [] },
currentBranch: 'main',
lastProblemStatus: '',
lastSavedFiles: [],
analysisCache: []
};
/**
* Processa argumentos de linha de comando
* @param useLogger Se deve usar o logger para exibir mensagens (se false, usa console)
*/
function processCommandLineArgs(useLogger = false) {
const args = process.argv.slice(2);
for (let i = 0; i < args.length; i++) {
if (args[i] === '--api-key' && i + 1 < args.length) {
const apiKey = args[i + 1];
// Armazenar a chave sem validação
(0, config_1.setApiKey)(apiKey);
// Log apropriado dependendo se o logger já foi inicializado
if (useLogger && logger) {
logger.info('API Key configured via command line');
}
else {
console.log('API Key configured via command line');
}
// Pular o próximo argumento, pois ele é o valor da chave
i++;
}
}
}
/**
* Tipos de erro de verificação LLMBooster
*/
var VerificationErrorType;
(function (VerificationErrorType) {
VerificationErrorType["NONE"] = "none";
VerificationErrorType["API_KEY"] = "api_key";
VerificationErrorType["VERSION"] = "version";
VerificationErrorType["NETWORK"] = "network";
VerificationErrorType["UNKNOWN"] = "unknown";
})(VerificationErrorType || (VerificationErrorType = {}));
/**
* Função para chamar o endpoint CoConuT
*/
async function callCoConuTEndpoint(params) {
try {
// Preparar o corpo da requisição
const lambdaInput = {
params,
state: coconutState,
config: config_1.config.coconut
};
// Preparar cabeçalhos
const headers = {
'Content-Type': 'application/json',
};
// Adicionar cabeçalho de autorização se a API key estiver configurada
const apiKey = (0, config_1.getApiKey)();
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`;
}
// Fazer a chamada ao endpoint externo
const response = await fetch('https://api.llmbooster.com/booster', {
method: 'POST',
headers,
body: JSON.stringify(lambdaInput)
});
// Verificar se a resposta foi bem-sucedida
if (!response.ok) {
// Criar mensagem de erro simples
const errorMessage = `Network error: Unable to reach server (${response.status})`;
throw new Error(errorMessage);
}
// Analisar a resposta
const result = await response.json();
// Se a resposta contém um erro simples, propagar
if (result.error) {
throw new Error(result.error);
}
return result;
}
catch (error) {
logger.error("Error calling CoConuT endpoint", { error });
// Criar mensagem de erro simples
let simpleMessage = error.message;
if (!simpleMessage || simpleMessage.includes('fetch')) {
simpleMessage = 'Network error. Please check your connection and try again.';
}
throw new Error(simpleMessage);
}
}
/**
* Função para chamar o endpoint CoConuT_Analyser
*/
async function callCoConuTAnalyserEndpoint(thoughts, projectPath, userQuery) {
try {
// Preparar o corpo da requisição
const requestBody = {
thoughts: thoughts.map(t => ({
...t,
score: t.score || 0 // Garantir que score nunca é undefined
})),
projectPath,
userQuery
};
// Preparar cabeçalhos
const headers = {
'Content-Type': 'application/json',
};
// Adicionar cabeçalho de autorização se a API key estiver configurada
const apiKey = (0, config_1.getApiKey)();
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`;
}
// Fazer a chamada ao endpoint externo
const response = await fetch('https://api.llmbooster.com/analyser', {
method: 'POST',
headers,
body: JSON.stringify(requestBody)
});
// Verificar se a resposta foi bem-sucedida
if (!response.ok) {
// Criar mensagem de erro simples
const errorMessage = `Network error: Unable to reach analyser server (${response.status})`;
throw new Error(errorMessage);
}
// Analisar a resposta
const result = await response.json();
// Se a resposta contém um erro simples, propagar
if (result.error) {
throw new Error(result.error);
}
return result;
}
catch (error) {
logger.error("Error calling CoConuT_Analyser endpoint", { error });
// Criar mensagem de erro simples
let simpleMessage = error.message;
if (!simpleMessage || simpleMessage.includes('fetch')) {
simpleMessage = 'Network error. Please check your connection and try again.';
}
throw new Error(simpleMessage);
}
}
/**
* Inicializa o logger
*/
function initializeLogger() {
logger = logger_1.Logger.getInstance({
minLevel: logger_1.Logger.getLevelFromName(config_1.config.logging.minLevel),
enableConsole: config_1.config.logging.enableConsole,
includeTimestamp: config_1.config.logging.includeTimestamp,
logFilePath: config_1.config.logging.logFilePath
});
}
/**
* Configura o servidor MCP e as ferramentas CoConuT
*/
function setupServer() {
// Criar e configurar o servidor MCP
server = new mcp_js_1.McpServer({
name: config_1.config.server.name,
version: config_1.config.server.version
});
// Instanciar o serviço CoConuT_Storage
coconutService = new coconut_1.CoConuTService({
persistenceEnabled: true
// Sem projectPath - o modelo deve fornecer em cada interação
});
// Inicializar o serviço Booster_Steps
boosterStepsService = new booster_steps_1.BoosterStepsService();
// Log de configuração aplicada
logger.info("Configuração do CoConuT:", {
persistenceEnabled: true,
transport: config_1.config.server.transport,
protocolVersion: config_1.config.server.protocolVersion
});
// Log específico sobre o status do armazenamento
logger.info("Armazenamento de pensamentos configurado com validação. O modelo DEVE fornecer um caminho válido em cada interação!");
// Configurar ferramentas CoConuT, CoConuT_Storage e CoConuT_Analyser
setupCoConuTTools();
}
/**
* Configura as ferramentas CoConuT no servidor MCP
*/
function setupCoConuTTools() {
if (!server || !coconutService) {
throw new Error("Servidor MCP ou serviço CoConuT não inicializados");
}
const service = coconutService; // Criar referência não-null
// Implementação da ferramenta CoConuT
server.tool("Booster", types_1.CoConuTParamsSchema.shape, async (params, extra) => {
try {
// Chamar o endpoint externo com os parâmetros e o estado
const lambdaResult = await callCoConuTEndpoint(params);
// Atualizar o estado global com o retornado pelo endpoint
coconutState = lambdaResult.state;
// Retornar resposta no formato esperado pelo MCP
return {
content: [{
type: "text",
text: JSON.stringify(lambdaResult.response, null, 2)
}],
_meta: {
description: "Ferramenta de raciocínio contínuo em cadeia (Continuous Chain of Thought)",
readOnly: true,
category: "reasoning",
descriptionShort: "Processa pensamentos em cadeia com ramificações e análise de qualidade",
descriptionLong: "Permite modelos de linguagem raciocinar passo a passo, mantendo histórico de pensamentos e possibilitando ramificações. Suporta revisão de pensamentos anteriores, análise automática da qualidade do raciocínio, detecção de ciclos, e ajustes dinâmicos no número total de pensamentos. Retorna resultado em formato JSON com análise integrada.",
schemaVersion: config_1.config.server.protocolVersion
}
};
}
catch (error) {
logger.error("Error in CoConuT tool", { error });
// Criar mensagem de erro simples
const simpleErrorMessage = error.message || 'An error occurred while processing your request.';
// Retornar erro em formato compatível e simples
return {
content: [{
type: "text",
text: JSON.stringify({
error: simpleErrorMessage,
thoughtNumber: params.thoughtNumber,
totalThoughts: params.totalThoughts,
nextThoughtNeeded: false,
analysis: {
isOnRightTrack: false,
needsMoreUserInfo: true,
suggestedTotalThoughts: params.totalThoughts,
userInfoNeeded: [simpleErrorMessage],
suggestions: ['Fix the error and try again']
}
}, null, 2)
}]
};
}
});
// Implementação da ferramenta CoConuT_Storage
server.tool("Booster_Storage", types_1.CoConuTStorageParamsSchema.shape, async (params) => {
try {
// Validar os parâmetros obrigatórios
if (!params.projectPath) {
throw new Error("The project path cannot be empty");
}
if (!params.WhyChange) {
throw new Error("The reason for change cannot be empty");
}
if (!params.WhatChange) {
throw new Error("The change description cannot be empty");
}
// Chamar o método saveWithStorage do serviço CoConuT com todos os parâmetros
const savedFiles = await service.saveWithStorage(params.projectPath, params.WhyChange, params.WhatChange, {
// Passar os parâmetros opcionais para enriquecer a conclusão
category: params.category,
subCategories: params.subCategories,
tags: params.tags,
impactLevel: params.impactLevel,
affectedFiles: params.affectedFiles,
codeSnippets: params.codeSnippets,
relatedConclusions: params.relatedConclusions,
ticketReference: params.ticketReference,
businessContext: params.businessContext,
alternativesConsidered: params.alternativesConsidered,
testingPerformed: params.testingPerformed,
technicalContext: params.technicalContext
});
// Iniciar armazenamento de interações futuras se configurado
if (config_1.config.coconut.persistenceEnabled) {
coconutService?.setProjectPath(params.projectPath);
}
// Construir resultado da operação
const result = {
success: true,
message: "Thoughts and conclusion saved successfully",
savedFiles,
timestamp: Date.now()
};
// Retornar resposta no formato esperado pelo MCP
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}],
_meta: {
description: "Ferramenta de armazenamento persistente para cadeias de pensamento do CoConuT",
readOnly: false,
isDestructive: true,
category: "storage",
descriptionShort: "Salva pensamentos, conclusões e histórico de interações em armazenamento persistente",
descriptionLong: "Permite salvar a cadeia de pensamentos gerada em arquivos persistentes, criar conclusões estruturadas e enriquecidas e manter um histórico de interações. A ferramenta cria ou atualiza arquivos no sistema de arquivos com base no caminho fornecido, gera uma conclusão formatada com metadados, seções padronizadas, categorização e contextualização a partir dos parâmetros fornecidos, e configura o salvamento automático de futuras interações no arquivo conclusion.md. Fornece respostas detalhadas sobre os arquivos salvos, incluindo contagem, timestamps e caminhos. Inclui suporte para categorização, tags, níveis de impacto, snippets de código, referências cruzadas e outros metadados que otimizam o retrieval pelo modelo.",
requiresUserAction: true,
schemaVersion: config_1.config.server.protocolVersion
}
};
}
catch (error) {
logger.error("Error in CoConuT_Storage tool", { error });
// Criar mensagem de erro simples
const simpleErrorMessage = error.message || 'An error occurred while saving data.';
// Retornar erro em formato compatível
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
error: simpleErrorMessage
}, null, 2)
}]
};
}
});
// Esquema Zod para validação de estrutura de ThoughtEntry
const ThoughtEntrySchema = zod_1.z.object({
thought: zod_1.z.string().describe("The current thought text in the reasoning process"),
thoughtNumber: zod_1.z.number().positive().describe("Sequential number of this thought in the chain"),
branchId: zod_1.z.string().describe("Unique identifier of the current branch"),
timestamp: zod_1.z.number().positive().describe("Unix timestamp when the thought was created"),
score: zod_1.z.number().min(0).max(10).optional().describe("Score or confidence associated with this thought (0-10)"),
metadata: zod_1.z.record(zod_1.z.any()).optional().describe("Additional metadata associated with this thought")
});
// Esquema Zod para parâmetros do Booster_Analyser
const BoosterAnalyserParamsSchema = zod_1.z.object({
thoughts: zod_1.z.array(ThoughtEntrySchema).min(1).describe("Array of thoughts to analyze. Each thought must contain text, number, branchId, timestamp, and optionally score and metadata."),
projectPath: zod_1.z.string().optional().describe("Project path for additional context"),
userQuery: zod_1.z.string().describe("Original user query to check alignment - required for proper analysis")
});
// Implementação da ferramenta Booster_Analyser
server.tool("Booster_Analyser", BoosterAnalyserParamsSchema.shape, async (params) => {
// Função helper para retornar erro diretamente
const returnError = (errorMessage) => {
return {
content: [{
type: "text",
text: JSON.stringify({
error: errorMessage,
isOnRightTrack: false,
needsMoreUserInfo: true,
suggestedTotalThoughts: 5,
userInfoNeeded: [errorMessage],
suggestions: ['Fix the error and try again'],
metadata: {
errorTimestamp: new Date().toISOString()
}
}, null, 2)
}]
};
};
// Validação manual para parâmetros obrigatórios
// Verificar se userQuery existe (agora obrigatório)
if (!params.userQuery || typeof params.userQuery !== 'string' || params.userQuery.trim() === '') {
return returnError("The 'userQuery' parameter is required and must be a non-empty string");
}
// As validações detalhadas do array thoughts agora são feitas pelo schema Zod
// Se chegou até aqui, significa que thoughts está válido conforme ThoughtEntrySchema
try {
// Chamar o endpoint externo
const result = await callCoConuTAnalyserEndpoint(params.thoughts, params.projectPath, params.userQuery);
// Retornar resposta no formato esperado pelo MCP
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}],
_meta: {
description: "Ferramenta de análise para cadeias de pensamentos do Booster",
readOnly: true,
category: "analysis",
descriptionShort: "Analisa a qualidade de uma cadeia de pensamentos",
descriptionLong: "Permite avaliar a qualidade de uma cadeia de pensamentos, verificando se o raciocínio está no caminho certo, se mais informações são necessárias do usuário, e sugerindo um número total de pensamentos adequado para o problema. Fornece sugestões para aprimoramento do raciocínio e identificação de desvios no caminho do raciocínio. Recebe um array de pensamentos (opcionalmente com um caminho de projeto e uma consulta do usuário) e retorna uma análise detalhada em formato JSON.",
schemaVersion: config_1.config.server.protocolVersion
}
};
}
catch (error) {
logger.error("Error in Booster_Analyser tool", { error });
// Criar mensagem de erro simples
const simpleErrorMessage = error.message || 'An error occurred while analyzing thoughts.';
// Retornar erro em formato simples e compatível
return {
content: [{
type: "text",
text: JSON.stringify({
error: simpleErrorMessage,
isOnRightTrack: false,
needsMoreUserInfo: true,
suggestedTotalThoughts: 5,
userInfoNeeded: [simpleErrorMessage],
suggestions: ['Fix the error and try again'],
metadata: {
errorTimestamp: new Date().toISOString()
}
}, null, 2)
}]
};
}
});
// Implementação da ferramenta Booster_Steps
server.tool("Booster_Steps", types_1.BoosterStepsParamsSchema.shape, async (params) => {
try {
// Validar se o serviço foi inicializado
if (!boosterStepsService) {
throw new Error("Booster_Steps service not initialized");
}
// Validar parâmetros obrigatórios
if (!params.title || params.title.trim().length < 3) {
throw new Error("Task title must be at least 3 characters long");
}
if (!params.taskDescription || params.taskDescription.trim().length < 10) {
throw new Error("Task description must be at least 10 characters long");
}
if (!params.projectPath || params.projectPath.trim().length < 1) {
throw new Error("Project path is required and cannot be empty");
}
if (!params.steps || params.steps.length === 0) {
throw new Error("At least one step must be provided");
}
// Processar a tarefa
const result = await boosterStepsService.processTask(params);
// Retornar resposta no formato esperado pelo MCP
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}],
_meta: {
description: "Ferramenta para decomposição de tarefas em passos menores e gerenciáveis",
readOnly: false,
category: "planning",
descriptionShort: "Decompõe tarefas complexas em passos menores, organizados e priorizados",
descriptionLong: "Permite que modelos de linguagem decomponham tarefas complexas em uma série de passos menores, mais gerenciáveis e organizados. A ferramenta analisa a descrição da tarefa, identifica o tipo (desenvolvimento, pesquisa, design, teste, deployment), considera a complexidade e gera um plano estruturado com passos sequenciais, dependências, estimativas de tempo, prioridades e recomendações. Opcionalmente salva o plano em arquivo markdown para referência futura. Inclui análise de fatores de risco e sugestões para otimizar a execução.",
requiresUserAction: params.projectPath ? true : false,
schemaVersion: config_1.config.server.protocolVersion
}
};
}
catch (error) {
logger.error("Error in Booster_Steps tool", { error });
// Criar mensagem de erro simples
const simpleErrorMessage = error.message || 'An error occurred while processing the task decomposition.';
// Retornar erro em formato compatível
return {
content: [{
type: "text",
text: JSON.stringify({
success: false,
error: simpleErrorMessage,
taskTitle: params.taskDescription ? params.taskDescription.substring(0, 50) + '...' : 'Unknown Task',
totalSteps: 0,
steps: [],
summary: `Error processing task: ${simpleErrorMessage}`,
recommendations: ['Fix the error and try again'],
riskFactors: ['Task processing failed']
}, null, 2)
}]
};
}
});
}
/**
* Trata sinais do sistema para encerramento adequado
*/
function setupSignalHandlers() {
process.on('SIGINT', () => {
logger.info('SIGINT recebido, encerrando servidor...');
process.exit(0);
});
process.on('SIGTERM', () => {
logger.info('SIGTERM recebido, encerrando servidor...');
process.exit(0);
});
}
/**
* Abre o changelog do LLMBooster no navegador padrão
* @param useLogger Se deve usar o logger para exibir mensagens (se false, usa console)
*/
async function openLLMBoosterChangelog(useLogger = true) {
const url = 'https://llmbooster.com/changelog?update=true';
// Verificar se o redirecionamento automático está habilitado
if (!config_1.config.api.autoRedirectOnError) {
const message = `Por favor, visite ${url} para ver as atualizações disponíveis`;
if (useLogger && logger) {
logger.warn(message);
}
else {
console.warn(`\n⚠️ ${message}\n`);
}
return;
}
try {
const message = `Redirecionando para ${url} para ver as atualizações disponíveis`;
if (useLogger && logger) {
logger.info(message);
}
else {
console.log(`\n\n📢 ${message}...\n`);
}
// Abrir o URL no navegador padrão
await (0, open_1.default)(url);
}
catch (error) {
const errorMessage = `Não foi possível abrir o navegador automaticamente. Por favor, visite ${url} para ver as atualizações disponíveis`;
if (useLogger && logger) {
logger.error(errorMessage);
}
else {
console.error(`\n❌ ${errorMessage}\n`);
}
}
}
/**
* Abre o site llmbooster.com no navegador padrão
* @param reason Motivo pelo qual o redirecionamento está sendo feito
* @param useLogger Se deve usar o logger para exibir mensagens (se false, usa console)
*/
async function openLLMBoosterWebsite(reason, useLogger = true) {
const apiKey = (0, config_1.getApiKey)();
const url = apiKey
? `https://llmbooster.com/error/api-key?key=${apiKey}`
: 'https://llmbooster.com/error/api-key';
// Verificar se o redirecionamento automático está habilitado
if (!config_1.config.api.autoRedirectOnError) {
const message = `Por favor, visite ${url} para ${reason}`;
if (useLogger && logger) {
logger.warn(message);
}
else {
console.warn(`\n⚠️ ${message}\n`);
}
return;
}
try {
const message = `Redirecionando para ${url} para ${reason}`;
if (useLogger && logger) {
logger.info(message);
}
else {
console.log(`\n\n⚠️ ${message}...\n`);
}
// Abrir o URL no navegador padrão
await (0, open_1.default)(url);
}
catch (error) {
const errorMessage = `Não foi possível abrir o navegador automaticamente. Por favor, visite ${url} para ${reason}`;
if (useLogger && logger) {
logger.error(errorMessage);
}
else {
console.error(`\n❌ ${errorMessage}\n`);
}
}
}
/**
* Verifica se a API key é válida e se há novas versões disponíveis fazendo uma chamada para o endpoint de verificação
* @param useLogger Se deve usar o logger para exibir mensagens (se false, usa console)
* @returns Promise<VerificationResult> Resultado da verificação com tipo de erro específico
*/
async function verifyLLMBooster(useLogger = true) {
const apiKey = (0, config_1.getApiKey)();
if (!apiKey) {
return {
success: false,
errorType: VerificationErrorType.API_KEY,
message: 'API key não configurada'
};
}
try {
// Preparar cabeçalhos com a API key e Content-Type
const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
// Preparar o body com a versão atual do servidor
const body = JSON.stringify({
version: config_1.config.server.version
});
// Fazer a chamada ao endpoint de verificação
const response = await fetch('https://api.llmbooster.com', {
method: 'POST',
headers,
body
});
// Analisar resposta baseada no código de status
if (response.ok) {
// Sucesso
return {
success: true,
errorType: VerificationErrorType.NONE,
statusCode: response.status
};
}
else if (response.status === 401 || response.status === 403) {
// Erro de API key inválida
return {
success: false,
errorType: VerificationErrorType.API_KEY,
statusCode: response.status,
message: 'API key inválida ou sem permissões'
};
}
else if (response.status === 426) {
// Versão desatualizada (Upgrade Required)
return {
success: false,
errorType: VerificationErrorType.VERSION,
statusCode: response.status,
message: 'Versão do servidor desatualizada'
};
}
else {
// Outro tipo de erro
return {
success: false,
errorType: VerificationErrorType.UNKNOWN,
statusCode: response.status,
message: `Erro HTTP ${response.status}`
};
}
}
catch (error) {
// Em caso de erro na chamada (problema de rede, etc.)
if (useLogger && logger) {
logger.error('Erro ao verificar LLMBooster', { error });
}
else {
console.error('Erro ao verificar LLMBooster:', error);
}
return {
success: false,
errorType: VerificationErrorType.NETWORK,
message: 'Erro de rede ou conexão'
};
}
}
/**
* Inicializa o servidor MCP com as configurações fornecidas
* @param options Opções de inicialização
*/
async function initializeServer(options = {}) {
try {
// Processar argumentos de linha de comando antes da inicialização do logger
// Passamos false para indicar que deve usar console.log em vez de logger
processCommandLineArgs(false);
// Verificar se a variável de ambiente para desativar redirecionamento automático está definida
if (process.env.MCP_COCONUT_NO_REDIRECT === 'true') {
(0, config_1.updateConfig)({
api: {
autoRedirectOnError: false
}
});
}
// Atualizar configurações com as opções fornecidas
if (options.config) {
(0, config_1.updateConfig)(options.config);
}
// Configurar API key se fornecida nas opções
if (options.apiKey) {
(0, config_1.setApiKey)(options.apiKey);
}
// Verificar se a API key foi configurada via variável de ambiente
const envApiKey = process.env.MCP_COCONUT_API_KEY;
if (envApiKey && !(0, config_1.getApiKey)()) {
(0, config_1.setApiKey)(envApiKey);
console.log('API Key configurada via variável de ambiente');
}
// Inicializar o logger
initializeLogger();
// Se a API key não foi configurada, exibir aviso e redirecionar para o site
if (!(0, config_1.getApiKey)()) {
logger.error("API Key não configurada. Para usar API key, configure-a via opções, variável de ambiente ou linha de comando.");
await openLLMBoosterWebsite('obter uma API key válida', true);
}
else {
logger.info("API Key configurada.");
// Verificar se a API key é válida
logger.info("Verificando validade da API key...");
const verificationResult = await verifyLLMBooster();
if (verificationResult.success) {
logger.info("API Key verificada com sucesso!");
}
else {
// Tratar diferentes tipos de erro
switch (verificationResult.errorType) {
case VerificationErrorType.API_KEY:
logger.error(`Erro de API key: ${verificationResult.message}. As chamadas à API podem falhar.`);
await openLLMBoosterWebsite('resolver problemas com sua API key atual', true);
break;
case VerificationErrorType.VERSION:
logger.warn(`Nova versão disponível: ${verificationResult.message}. Considere atualizar para a versão mais recente.`);
await openLLMBoosterChangelog(true);
break;
case VerificationErrorType.NETWORK:
logger.error(`Erro de rede: ${verificationResult.message}. Verifique sua conexão com a internet.`);
break;
default:
logger.error(`Erro na verificação: ${verificationResult.message}. As chamadas à API podem falhar.`);
await openLLMBoosterWebsite('resolver problemas com o serviço', true);
break;
}
}
}
// Configurar o servidor e as ferramentas
setupServer();
// Configurar handlers de sinais
setupSignalHandlers();
// Conectar o servidor ao transporte
if (server) {
const transport = new stdio_js_1.StdioServerTransport();
await server.connect(transport);
logger.info('Servidor MCP iniciado com sucesso');
}
else {
throw new Error("Falha ao inicializar o servidor MCP");
}
}
catch (error) {
if (logger) {
logger.error('Erro ao iniciar servidor MCP', { error });
}
else {
console.error('Erro ao iniciar servidor MCP:', error);
}
process.exit(1);
}
}
// Se o módulo for executado diretamente (não importado), iniciar o servidor
if (require.main === module) {
initializeServer();
}