@ria-sys/mcp
Version:
MCP Server para integração com WhatsApp
193 lines (186 loc) • 7.32 kB
JavaScript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import { MessageService } from './services/MessageService.js';
// Tipos inferidos dos schemas
const SendMessageSchema = z.object({
phones: z.array(z.string()).describe("Lista de números de telefone com DDI e DDD (ex: ['5547999999999'])"),
message: z.string().describe("Texto da mensagem a ser enviada"),
sessionName: z.string().describe("Nome da sessão do WhatsApp onde a mensagem será enviada")
});
const FormatPhoneSchema = z.object({
phones: z.array(z.string()).describe("Lista de números de telefone para formatar no padrão E.164 (ex: ['5547999999999'])"),
removeNinthDigit: z.boolean().optional().default(false).describe("Se verdadeiro, remove o nono dígito do número de telefone brasileiro")
});
// Serviço de mensagens
const messageService = new MessageService();
// Configuração do servidor MCP
const server = new McpServer({
name: "ria-sys",
version: "3.0.3",
description: "Sistema de envio e formatação de mensagens via WhatsApp"
});
// Adicionar um recurso de documentação
server.resource("Documentação de Formato de Telefone", "docs://formato-telefone", {
mimeType: "text/plain"
}, async (uri) => {
return {
contents: [{
uri: uri.href,
text: `
Formatos de Telefone Suportados:
1. Formato Internacional E.164:
- Formato: +[código do país][código de área][número do telefone]
- Exemplo: +5547999999999
2. Formato Nacional:
- Formato: [código de área][número do telefone]
- Exemplo: 47999999999
3. Formato com separadores (será normalizado automaticamente):
- Exemplos: (47) 99999-9999, 47-99999-9999
Observações:
- O nono dígito para celulares brasileiros (9) pode ser removido se necessário
- O sistema faz a normalização automática dos números antes do envio
`
}]
};
});
// Função para formatar erros de maneira padronizada
function formatError(error) {
if (error instanceof Error) {
return `Erro: ${error.message}`;
}
return `Erro desconhecido: ${String(error)}`;
}
// Handler para envio de mensagens
server.tool("sendMessage", "Envia uma mensagem via WhatsApp para uma lista de destinatários", {
phones: z.array(z.string()).describe("Lista de números de telefone com DDI e DDD (ex: ['5547999999999'])"),
message: z.string().describe("Texto da mensagem a ser enviada"),
sessionName: z.string().describe("Nome da sessão do WhatsApp onde a mensagem será enviada")
}, async (args) => {
try {
console.error(`[DEBUG] Tentando enviar mensagem para ${args.phones.length} destinatários`);
const result = await messageService.sendMessage(args.phones, args.message, args.sessionName);
console.error(`[DEBUG] Resultado do envio: ${result.success ? 'Sucesso' : 'Falha'}`);
return {
content: [
{
type: "text",
text: result.message
}
],
isError: !result.success,
metadata: {
recipients: args.phones.length,
sessionName: args.sessionName,
timestamp: new Date().toISOString()
}
};
}
catch (error) {
console.error(`[ERROR] Falha ao enviar mensagem:`, error);
return {
content: [
{
type: "text",
text: formatError(error)
}
],
isError: true,
metadata: {
errorType: error instanceof Error ? error.name : 'UnknownError',
timestamp: new Date().toISOString()
}
};
}
});
// Handler para formatação de números
server.tool("formatPhone", "Formata números de telefone para o padrão E.164 internacional", {
phones: z.array(z.string()).describe("Lista de números de telefone para formatar no padrão E.164 (ex: ['5547999999999'])"),
removeNinthDigit: z.boolean().optional().default(false).describe("Se verdadeiro, remove o nono dígito do número de telefone brasileiro")
}, async (args) => {
try {
console.error(`[DEBUG] Formatando ${args.phones.length} números de telefone`);
console.error(`[DEBUG] Remover nono dígito: ${args.removeNinthDigit}`);
const formattedPhones = args.phones.map((phone) => {
const result = messageService.formatPhone(phone, args.removeNinthDigit || false);
return result.success ? result.phone : `Erro: ${result.message}`;
});
console.error(`[DEBUG] Formatação concluída com sucesso`);
return {
content: [
{
type: "text",
text: JSON.stringify(formattedPhones, null, 2)
}
],
metadata: {
totalProcessed: args.phones.length,
removeNinthDigit: args.removeNinthDigit,
timestamp: new Date().toISOString()
}
};
}
catch (error) {
console.error(`[ERROR] Falha ao formatar números:`, error);
return {
content: [
{
type: "text",
text: formatError(error)
}
],
isError: true,
metadata: {
errorType: error instanceof Error ? error.name : 'UnknownError',
timestamp: new Date().toISOString()
}
};
}
});
// Adicionar um prompt de modelo para envio de mensagens
server.prompt("enviar-mensagem", "Modelo para criar uma mensagem WhatsApp para envio", {
destinatarios: z.string().describe("Lista de números separados por vírgula"),
mensagem: z.string().describe("Texto da mensagem a ser enviada"),
sessao: z.string().describe("Nome da sessão do WhatsApp a ser usada")
}, ({ destinatarios, mensagem, sessao }) => {
const phoneList = destinatarios.split(',').map(phone => phone.trim());
return {
description: "Modelo para envio de mensagem via WhatsApp",
messages: [
{
role: "assistant",
content: {
type: "text",
text: `Preparando para enviar uma mensagem pelo WhatsApp.
Destinatários: ${phoneList.join(', ')}
Sessão: ${sessao}
Total de destinatários: ${phoneList.length}
Você pode usar a ferramenta 'mcp_ria_sys_sendMessage' para enviar esta mensagem diretamente.
`
}
},
{
role: "user",
content: {
type: "text",
text: `Mensagem a ser enviada: "${mensagem}"`
}
}
]
};
});
// Inicia o servidor
async function runServer() {
try {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("RIA System MCP Server rodando via stdio");
}
catch (error) {
console.error("Erro fatal ao iniciar servidor:", error);
process.exit(1);
}
}
// Executa o servidor
runServer();