import json import os import argparse from typing import List, Dict from mcp.server.fastmcp import FastMCP # Inicializa o servidor FastMCP mcp = FastMCP("Fluig Technical Wiki") # Caminhos dos arquivos CHUNKS_FILE = "fluig_chunks.json" SNIPPETS_DIR = os.path.join("fluig_rag_docs", "Biblioteca de Snippets") def load_chunks() -> List[Dict]: if os.path.exists(CHUNKS_FILE): with open(CHUNKS_FILE, "r", encoding="utf-8") as f: return json.load(f) return [] @mcp.tool() def search_docs(query: str) -> str: """ Busca profunda na documentação técnica do Fluig. Retorna trechos exatos sobre APIs, Eventos, Datasets e Configurações. """ chunks = load_chunks() results = [] query = query.lower() # Busca com prioridade em títulos for chunk in chunks: title = chunk.get("metadata", {}).get("title", "").lower() content = chunk.get("content", "").lower() if query in title: results.insert(0, f"### [ALTA RELEVÂNCIA] {chunk['metadata'].get('title')}\n{chunk['content']}\n---\n") elif query in content: results.append(f"### {chunk['metadata'].get('title')}\n{chunk['content']}\n---\n") if len(results) >= 8: # Limite expandido para busca mais rica break if not results: return f"Nenhuma informação técnica encontrada para: {query}. Tente termos como 'createDataset', 'hAPI', 'OAuth' ou 'BPM'." return "\n".join(results) @mcp.tool() def get_code_snippets(language: str) -> str: """ Recupera a biblioteca completa de exemplos de código para Fluig (javascript, java ou sql). """ lang = language.lower() file_map = { "javascript": "Snippets JAVASCRIPT.md", "js": "Snippets JAVASCRIPT.md", "java": "Snippets JAVA.md", "sql": "Snippets SQL.md" } file_name = file_map.get(lang) if not file_name: return f"Linguagem '{language}' não suportada. Use: javascript, java ou sql." path = os.path.join(SNIPPETS_DIR, file_name) if os.path.exists(path): with open(path, "r", encoding="utf-8") as f: return f.read() return f"Arquivo de snippets para {language} não encontrado. Certifique-se de que o snippet_generator.py foi executado." @mcp.resource("docs://all_titles") def list_all_titles() -> str: """Lista todos os temas técnicos disponíveis na base de conhecimento.""" chunks = load_chunks() titles = sorted(list(set(chunk["metadata"].get("title") for chunk in chunks))) return "\n".join(titles) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Fluig MCP Server") parser.add_argument("--mode", choices=["stdio", "sse"], default="stdio", help="Modo de operação (padrão: stdio)") parser.add_argument("--port", type=int, default=8001, help="Porta para o modo SSE (padrão: 8001)") args = parser.parse_args() if args.mode == "sse": print(f"Iniciando servidor MCP em modo SSE na porta {args.port}...") mcp.run(transport="sse") else: # Modo STDIO (padrão para Claude Desktop e integração local) mcp.run(transport="stdio")