Skip to main content
Glama

Evolution API MCP Server

by PabloBispo
server.py13 kB
"""MCP Server para Evolution API.""" import sys from pathlib import Path # Adiciona o diretório src ao path para permitir importações src_dir = Path(__file__).parent.parent if str(src_dir) not in sys.path: sys.path.insert(0, str(src_dir)) from mcp.server.fastmcp import FastMCP from evoapi_mcp.config import load_config from evoapi_mcp.client import EvolutionClient # Inicializa o MCP server mcp = FastMCP("Evolution API") # Carrega configuração e inicializa cliente try: config = load_config() client = EvolutionClient(config) except Exception as e: print(f"Falha ao inicializar o servidor: {e}", file=sys.stderr) sys.exit(1) # ============================================================================ # TOOLS - Envio de Mensagens # ============================================================================ @mcp.tool() def send_text_message( number: str, text: str, link_preview: bool = True ) -> dict: """Envia uma mensagem de texto para um número WhatsApp. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) text: Texto da mensagem a ser enviada link_preview: Se deve mostrar preview de links (padrão: True) Returns: dict: Resposta da API com informações sobre a mensagem enviada Example: send_text_message( number="5511999999999", text="Olá! Esta é uma mensagem de teste." ) """ return client.send_text( number=number, text=text, link_preview=link_preview ) @mcp.tool() def send_image( number: str, image_url: str, caption: str | None = None ) -> dict: """Envia uma imagem para um número WhatsApp. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) image_url: URL pública da imagem (jpg, png, etc.) caption: Legenda da imagem (opcional) Returns: dict: Resposta da API Example: send_image( number="5511999999999", image_url="https://example.com/image.jpg", caption="Confira esta imagem!" ) """ return client.send_media( number=number, media_url=image_url, media_type="image", caption=caption ) @mcp.tool() def send_document( number: str, document_url: str, filename: str | None = None, caption: str | None = None ) -> dict: """Envia um documento para um número WhatsApp. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) document_url: URL pública do documento (pdf, docx, xlsx, etc.) filename: Nome do arquivo a ser exibido (opcional) caption: Legenda do documento (opcional) Returns: dict: Resposta da API Example: send_document( number="5511999999999", document_url="https://example.com/relatorio.pdf", filename="Relatório Mensal.pdf", caption="Segue o relatório solicitado" ) """ return client.send_media( number=number, media_url=document_url, media_type="document", caption=caption, filename=filename ) @mcp.tool() def send_video( number: str, video_url: str, caption: str | None = None ) -> dict: """Envia um vídeo para um número WhatsApp. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) video_url: URL pública do vídeo (mp4, etc.) caption: Legenda do vídeo (opcional) Returns: dict: Resposta da API Example: send_video( number="5511999999999", video_url="https://example.com/video.mp4", caption="Veja este vídeo" ) """ return client.send_media( number=number, media_url=video_url, media_type="video", caption=caption ) @mcp.tool() def send_audio( number: str, audio_url: str ) -> dict: """Envia um áudio para um número WhatsApp. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) audio_url: URL pública do áudio (mp3, ogg, etc.) Returns: dict: Resposta da API Example: send_audio( number="5511999999999", audio_url="https://example.com/audio.mp3" ) """ return client.send_media( number=number, media_url=audio_url, media_type="audio" ) # ============================================================================ # TOOLS - Gerenciamento de Chats e Mensagens # ============================================================================ @mcp.tool() def get_chat_messages( number: str, limit: int = 50 ) -> dict: """Obtém mensagens de uma conversa específica por número de telefone. Use esta ferramenta quando o usuário pedir: - "mostre as mensagens do número X" - "últimas 20 mensagens de fulano" - "conversa com 5511999999999" Args: number: Número no formato internacional sem '+' (ex: 5511999999999) limit: Número máximo de mensagens a retornar. SEMPRE ajuste este valor quando o usuário especificar quantidade (ex: "últimas 20", "50 mensagens") Padrão: 50 mensagens Returns: dict: Lista de mensagens da conversa Example: # Últimas 50 mensagens (padrão) messages = get_chat_messages(number="5511999999999") # Últimas 20 mensagens messages = get_chat_messages(number="5511999999999", limit=20) """ return client.get_messages_by_number(number=number, limit=limit) @mcp.tool() def list_chats(limit: int | None = None) -> list: """Lista conversas ativas do WhatsApp ordenadas por data de atualização. Use esta ferramenta quando o usuário pedir: - "liste minhas conversas" - "mostre minhas conversas mais recentes" - "quais são meus últimos chats" Args: limit: Número máximo de conversas a retornar. SEMPRE use este parâmetro quando o usuário especificar uma quantidade (ex: "5 conversas", "10 chats") Returns: list: Lista de conversas, cada uma com: - remoteJid: ID do chat - pushName: Nome do contato (ou null) - lastMessage: Última mensagem trocada - unreadCount: Número de mensagens não lidas Example: # Listar todas as conversas chats = list_chats() # Listar apenas as 10 mais recentes (IMPORTANTE: sempre passar limit quando especificado) chats = list_chats(limit=10) """ chats = client.find_chats() # Aplica limit se fornecido if limit is not None and isinstance(chats, list): chats = chats[:limit] return chats @mcp.tool() def find_messages( query: str | None = None, chat_id: str | None = None, limit: int = 50 ) -> dict: """Busca mensagens com filtros avançados em todas as conversas. Use esta ferramenta quando o usuário pedir: - "busque mensagens com a palavra X" - "encontre mensagens sobre pedido" - "mensagens que contenham reunião" Args: query: Termo de busca nas mensagens. Use quando o usuário pedir para buscar/encontrar mensagens com palavras específicas chat_id: ID do chat específico no formato WhatsApp (ex: 5511999999999@s.whatsapp.net) Raramente usado - prefira usar number com get_chat_messages() limit: Número máximo de mensagens a retornar. SEMPRE ajuste quando o usuário especificar quantidade Padrão: 50 mensagens Returns: dict: Lista de mensagens encontradas Example: # Buscar por termo em todas as conversas messages = find_messages(query="pedido") # Buscar apenas 10 mensagens com "reunião" messages = find_messages(query="reunião", limit=10) # Buscar em chat específico messages = find_messages(chat_id="5511999999999@s.whatsapp.net", limit=20) """ return client.find_messages(query=query, chat_id=chat_id, limit=limit) @mcp.tool() def get_contacts(limit: int | None = None) -> list: """Busca contatos salvos no WhatsApp. Use esta ferramenta quando o usuário pedir: - "liste meus contatos" - "mostre 10 contatos" - "quais são meus contatos salvos" Args: limit: Número máximo de contatos a retornar. SEMPRE use este parâmetro quando o usuário especificar uma quantidade (ex: "10 contatos", "5 primeiros") Se não especificado, retorna TODOS os contatos (pode ser muitos!) Returns: list: Lista de contatos onde cada contato tem: - remoteJid: ID do contato (ex: 5511999999999@s.whatsapp.net) - pushName: Nome do contato - isGroup: Se é grupo ou contato individual Example: # Buscar todos os contatos (pode retornar centenas!) contacts = get_contacts() # Buscar apenas os primeiros 10 contatos (RECOMENDADO quando há quantidade) contacts = get_contacts(limit=10) """ contacts = client.fetch_contacts() # Aplica limit se fornecido if limit is not None and isinstance(contacts, list): contacts = contacts[:limit] return contacts @mcp.tool() def find_contact( contact_id: str | None = None, limit: int | None = None ) -> list: """Busca contatos com filtros opcionais. Args: contact_id: ID do contato no formato WhatsApp (ex: 5511999999999@s.whatsapp.net) limit: Número máximo de contatos a retornar (opcional, padrão: todos) Returns: list: Lista de contatos encontrados Example: # Buscar todos os contatos all_contacts = find_contact() # Buscar apenas 5 contatos contacts = find_contact(limit=5) # Buscar contato específico contact = find_contact(contact_id="5511999999999@s.whatsapp.net") """ contacts = client.find_contacts(contact_id=contact_id) # Aplica limit se fornecido if limit is not None and isinstance(contacts, list): contacts = contacts[:limit] return contacts @mcp.tool() def get_contact_name_by_number(number: str) -> dict: """Obtém o nome de um contato pelo número de telefone. Args: number: Número no formato internacional sem '+' (ex: 5511999999999) Returns: dict: {"number": "5511999999999", "name": "Nome do Contato" ou None} Example: info = get_contact_name_by_number("5511999999999") if info['name']: print(f"Contato: {info['name']}") else: print(f"Número não salvo: {info['number']}") """ name = client.get_contact_name(number) return { "number": number, "name": name } # ============================================================================ # TOOLS - Status e Presença # ============================================================================ @mcp.tool() def get_connection_status() -> dict: """Verifica o status da conexão da instância WhatsApp. Returns: dict: Estado da conexão contendo informações sobre a instância Example: status = get_connection_status() if status.get('state') == 'open': print("WhatsApp conectado!") """ return client.get_connection_state() @mcp.tool() def set_presence( status: str, number: str | None = None ) -> dict: """Define o status de presença da instância WhatsApp. Args: status: Status de presença (available, unavailable, composing, recording) number: Número para enviar presença específica (opcional) Returns: dict: Confirmação da alteração de presença Example: set_presence("available") # Fica online set_presence("unavailable") # Fica offline """ valid_statuses = ["available", "unavailable", "composing", "recording"] if status not in valid_statuses: raise ValueError( f"Status inválido: '{status}'. " f"Valores válidos: {', '.join(valid_statuses)}" ) return client.set_presence(status=status, number=number) @mcp.tool() def get_instance_info() -> dict: """Obtém informações detalhadas da instância WhatsApp. Returns: dict: Informações completas da instância incluindo status e configuração Example: info = get_instance_info() print(f"Instância: {info['instance_name']}") print(f"Status: {info['status']}") """ return client.get_instance_info() # ============================================================================ # Entry Point # ============================================================================ if __name__ == "__main__": # Executa o servidor MCP mcp.run()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PabloBispo/evoapi-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server