From 4d689ad6f3a2fef6062f1c7efd0b9eb08d98fd67 Mon Sep 17 00:00:00 2001 From: rodolpho Date: Thu, 7 May 2026 18:47:17 -0300 Subject: [PATCH] feat: implement MCP server for Fluig technical documentation --- mcp_server.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ 2 files changed, 79 insertions(+) create mode 100644 mcp_server.py diff --git a/mcp_server.py b/mcp_server.py new file mode 100644 index 0000000..4f65bfb --- /dev/null +++ b/mcp_server.py @@ -0,0 +1,77 @@ +import json +import os +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 informações técnicas na documentação do Fluig por palavras-chave. + Retorna os chunks mais relevantes. + """ + chunks = load_chunks() + results = [] + query = query.lower() + + for chunk in chunks: + content = chunk.get("content", "").lower() + title = chunk.get("metadata", {}).get("title", "").lower() + + if query in content or query in title: + results.append(f"### {chunk['metadata'].get('title')}\n{chunk['content']}\n---\n") + + if len(results) >= 5: # Limita a 5 resultados para não estourar contexto + break + + if not results: + return f"Nenhuma informação encontrada para: {query}" + + return "\n".join(results) + +@mcp.tool() +def get_code_snippets(language: str) -> str: + """ + Recupera exemplos de código (snippets) para uma linguagem específica (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." + +@mcp.resource("docs://all_titles") +def list_all_titles() -> str: + """Lista todos os títulos de documentos disponíveis na wiki.""" + chunks = load_chunks() + titles = sorted(list(set(chunk["metadata"].get("title") for chunk in chunks))) + return "\n".join(titles) + +if __name__ == "__main__": + # Rodar o servidor (padrão usa STDIO para integração com Claude/IDEs) + mcp.run() diff --git a/requirements.txt b/requirements.txt index 5da2d4f..26229a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,6 @@ aiohttp mkdocs-material mkdocs-with-pdf mkdocs-mermaid2-plugin +mcp +langchain-community # crawl4ai # Opcional, mas recomendado se o usuário tiver as dependências de sistema (Playwright)