index.js•12 kB
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { ProductsDB } from "./src/database/products.js";
import { initializeDatabase } from "./src/database/connection.js";
// Inicializar o banco de dados antes de criar o servidor
async function initializeApp() {
try {
await initializeDatabase();
console.log("Aplicação inicializada com sucesso!");
} catch (error) {
console.error("Erro ao inicializar aplicação:", error);
process.exit(1);
}
}
// CRIAR SERVIDOR MCP
const server = new Server(
{
name: "mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// Listar ferramentas disponíveis
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get-products",
description: "Retorna todos os produtos do banco de dados.",
inputSchema: {
type: "object",
properties: {},
},
},
{
name: "get-product-by-id",
description: "Retorna um produto específico pelo ID (UUID).",
inputSchema: {
type: "object",
properties: {
id: {
type: "string",
description:
"O UUID do produto a ser buscado (exemplo: 0008f49b-5bfc-4473-b97e-3977c3d0ebca)",
pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
},
},
required: ["id"],
},
},
{
name: "search-products-by-name",
description: "Busca produtos pelo nome (busca parcial).",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "O nome ou parte do nome do produto a ser buscado.",
},
},
required: ["name"],
},
},
{
name: "create-product",
description: "Cria um novo produto no banco de dados.",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "Nome do produto" },
description: { type: "string", description: "Descrição do produto", nullable: true },
amount: { type: "integer", description: "Quantidade", default: 0 },
averageCost: { type: "number", description: "Custo médio", nullable: true },
unit: { type: "string", description: "Unidade", nullable: true },
active: { type: "boolean", description: "Ativo?", default: true },
companyId: { type: "string", description: "UUID da empresa", nullable: true },
createdBy: { type: "string", description: "Criado por", nullable: true },
updatedBy: { type: "string", description: "Atualizado por", nullable: true },
validity: { type: "string", format: "date", description: "Validade", nullable: true },
},
required: ["name"],
},
},
{
name: "update-product",
description: "Atualiza um produto existente.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "UUID do produto" },
name: { type: "string", description: "Nome do produto", nullable: true },
description: { type: "string", description: "Descrição do produto", nullable: true },
amount: { type: "integer", description: "Quantidade", nullable: true },
averageCost: { type: "number", description: "Custo médio", nullable: true },
unit: { type: "string", description: "Unidade", nullable: true },
active: { type: "boolean", description: "Ativo?", nullable: true },
companyId: { type: "string", description: "UUID da empresa", nullable: true },
createdBy: { type: "string", description: "Criado por", nullable: true },
updatedBy: { type: "string", description: "Atualizado por", nullable: true },
validity: { type: "string", format: "date", description: "Validade", nullable: true },
},
required: ["id"],
},
},
{
name: "delete-product",
description: "Remove (soft delete) um produto pelo ID.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "UUID do produto" },
},
required: ["id"],
},
},
],
};
});
// Executar a ferramenta
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name: toolName, arguments: args } = request.params;
switch (toolName) {
case "tabnews-articles":
const { limit = 5 } = args || {};
return await buscarArtigosTabNews(limit);
case "get-products":
const produtos = await ProductsDB.getAllProducts();
return {
content: [
{
type: "text",
text: JSON.stringify(produtos, null, 2),
},
],
};
case "get-product-by-id":
const { id } = args;
if (!id) {
return {
content: [
{
type: "text",
text: JSON.stringify(
{
success: false,
error: "ID não fornecido",
details: "O ID do produto é obrigatório",
},
null,
2
),
},
],
};
}
const produto = await ProductsDB.getProductById(id);
return {
content: [
{
type: "text",
text: JSON.stringify(produto, null, 2),
},
],
};
case "search-products-by-name":
const { name } = args;
if (!name) {
return {
content: [
{
type: "text",
text: JSON.stringify(
{
success: false,
error: "Nome não fornecido",
details: "O nome do produto é obrigatório",
},
null,
2
),
},
],
};
}
const produtosPorNome = await ProductsDB.searchProductsByName(name);
return {
content: [
{
type: "text",
text: JSON.stringify(produtosPorNome, null, 2),
},
],
};
case "create-product":
const novoProduto = args;
const resultadoCriacao = await ProductsDB.createProduct(novoProduto);
return {
content: [
{
type: "text",
text: JSON.stringify(resultadoCriacao, null, 2),
},
],
};
case "update-product":
const { id: idUpdate, ...updateData } = args;
if (!idUpdate) {
return {
content: [
{
type: "text",
text: JSON.stringify(
{
success: false,
error: "ID não fornecido",
details: "O ID do produto é obrigatório",
},
null,
2
),
},
],
};
}
const resultadoAtualizacao = await ProductsDB.updateProduct(idUpdate, updateData);
return {
content: [
{
type: "text",
text: JSON.stringify(resultadoAtualizacao, null, 2),
},
],
};
case "delete-product":
const { id: idDelete } = args;
if (!idDelete) {
return {
content: [
{
type: "text",
text: JSON.stringify(
{
success: false,
error: "ID não fornecido",
details: "O ID do produto é obrigatório",
},
null,
2
),
},
],
};
}
const resultadoRemocao = await ProductsDB.deleteProduct(idDelete);
return {
content: [
{
type: "text",
text: JSON.stringify(resultadoRemocao, null, 2),
},
],
};
default:
return {
content: [
{
type: "text",
text: JSON.stringify(
{
success: false,
error: "Ferramenta desconhecida",
details: `A ferramenta "${toolName}" não existe`,
},
null,
2
),
},
],
};
}
});
// Função para iniciar o servidor
async function startServer() {
// Inicializar o banco de dados primeiro
await initializeApp();
const transport = new StdioServerTransport();
await server.connect(transport);
console.log("Servidor MCP TabNews e Produtos rodando...");
}
// Tratamento de erros
process.on("uncaughtException", (error) => {
console.error("Erro não tratado:", error);
process.exit(1);
});
// Iniciar o servidor
startServer().catch((error) => {
console.error("Erro ao iniciar o servidor:", error);
process.exit(1);
});