使用说明
RLM MCP Server
Servidor MCP (Model Context Protocol) que implementa Recursive Language Models para análise de dados massivos fora do contexto do agente, compatível com Claude Code e Codex.
Baseado no paper "Recursive Language Models" do MIT CSAIL.
Instalação atual: servidor ssh magalu, stack Docker Compose em
/home/ubuntu/stack/rlm/compose.json (projeto rlm-magalu, serviço rlm-mcp).
O servidor novo não usa Dokploy: push para main não faz deploy. Preserve o
compose, suas credenciais e os diretórios persist/ e data/ do servidor. Publique
uma imagem do commit verificado e atualize somente esse serviço; mantenha a imagem
anterior e backup consistente do SQLite para reversão. As instruções Dokploy e o
script deploy-dokploy.sh abaixo pertencem à instalação antiga.
Consulta e referências
rlm_read devolve passagens paginadas com origem, linhas, páginas conhecidas e
versão SHA-256. Texto alterado por rlm_execute recebe origem derived:....
Ao continuar por offset, envie o expected_version da resposta anterior.
A busca lexical usa query_language="pt" por padrão. Use "en" para manter
“no” como negação inglesa. Qualificadores como vitamina A/D/E são preservados.
Coleções avisam quando alguma fonte não está carregada; recarregue-a antes de
considerar a consulta completa. A busca semântica/híbrida continua por fonte.
Por Que Usar?
Ao carregar documentos inteiros na conversa, o agente:
- Carrega todo output no contexto
- Precisa de compactação frequente
- Limita análise de arquivos grandes
Com RLM MCP:
- Dados ficam em variáveis fora do contexto
- Contexto permanece pequeno
- Analise arquivos de 100MB+ sem compact
Arquitetura
┌─────────────────────────────────────────────────────────────┐
│ Sua máquina local │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Claude Code / Codex │ │
│ │ Tools MCP: rlm_execute, rlm_load_data, etc. │ │
│ └──────────────────────┬──────────────────────────────┘ │
└─────────────────────────┼───────────────────────────────────┘
│ SSH Tunnel (porta 8765)
▼
┌─────────────────────────────────────────────────────────────┐
│ Seu Servidor (Digital Ocean, AWS, etc.) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Docker: rlm-mcp-server │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Python REPL Persistente │ │ │
│ │ │ variables = {"logs": <500MB>, ...} │ │ │
│ │ │ Dados em memória, NÃO no contexto │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Instalação
1. No Servidor (via Dokploy ou Docker)
# Clone o repositório
git clone https://github.com/seu-usuario/rlm-mcp-server.git
cd rlm-mcp-server
# Copie o .env
cp .env.example .env
# Edite .env com suas configurações
# Crie o diretório de dados
mkdir -p data
# Coloque seus arquivos em ./data/
# Build e start
docker-compose up -d --build
Via Dokploy
- No Dokploy, crie um novo Application
- Source: Git → URL do repositório
- Build: Docker Compose
- Deploy
2. Na Máquina Local
O servidor oferece /mcp (Streamable HTTP, usado pelo Codex) e /sse
(compatibilidade com clientes SSE). Na instalação do Dr. Alain, a conexão usa
HTTPS diretamente; o túnel abaixo é uma alternativa para instalações privadas.
Opção A: SSH Tunnel (Recomendado)
# Crie um túnel SSH para a porta do servidor
ssh -L 8765:localhost:8765 root@seu-servidor.com -N &
# O túnel fica rodando em background
Opção B: Uso Local (sem servidor remoto)
Se quiser rodar localmente para testes:
cd rlm-mcp-server
pip install -e .
# Teste manualmente
python -c "from rlm_mcp.http_server import main; main()"
3A. Configure o Codex
Nesta máquina, o RLM já está configurado em ~/.codex/config.toml. Para outra
instalação, adicione uma única entrada ao arquivo pessoal, usando o domínio do
seu servidor:
[mcp_servers.rlm]
url = "https://rlm.seudominio.com/mcp"
bearer_token_env_var = "RLM_API_KEY"
Defina RLM_API_KEY no ambiente que inicia o Codex, com o mesmo segredo configurado
no servidor. Não coloque chaves no repositório. Reinicie o Codex após configurar e
use codex mcp list para conferir o cadastro; uma consulta a rlm_help verifica
se o servidor responde.
Para desenvolver, abra rlm-mcp-server/ como projeto. AGENTS.md aponta para
CLAUDE.md, compartilhando as instruções entre os agentes. A pasta principal
massive-context-window/ também tem um arquivo de orientação e links locais para
trabalhar a partir dela. Esses arquivos externos não acompanham um clone do Git.
O arquivo .codex/config.toml deste checkout apenas desativa integrações opcionais
no projeto; ele herda a conexão RLM pessoal. Configurações locais exigem que o
projeto seja confiável para o Codex. .mcp.json não substitui essa configuração.
Referências oficiais: MCP no Codex e instruções AGENTS.md.
3B. Configure o Claude Code
Adicione ao ~/.claude/claude.json:
{
"mcpServers": {
"rlm": {
"type": "sse",
"url": "https://rlm.seudominio.com/sse",
"headers": {
"Authorization": "Bearer SUA_API_KEY_AQUI"
}
}
}
}
Nota: Substitua
rlm.seudominio.compelo domínio configurado no Traefik/Dokploy.
Alternativa - via SSH tunnel (se não quiser expor publicamente):
{
"mcpServers": {
"rlm": {
"command": "socat",
"args": ["TCP:localhost:8765", "STDIO"]
}
}
}
4. Reinicie o Claude Code
# Feche e abra novamente, ou:
claude --mcp-restart
Uso
Tools Disponíveis
| Tool | Descrição |
|---|---|
rlm_load_data |
Carrega dados diretamente em variável |
rlm_load_file |
Carrega arquivo do servidor (text, json, csv, lines, pdf, pdf_ocr) |
rlm_execute |
Executa código Python |
rlm_read |
Lê passagem exata com fonte, linhas, páginas conhecidas e versão |
rlm_list_vars |
Lista variáveis disponíveis |
rlm_var_info |
Info detalhada de uma variável |
rlm_clear |
Limpa variáveis |
rlm_memory |
Estatísticas de memória |
rlm_load_s3 |
Carrega arquivo do Minio/S3 (text, json, csv, lines, pdf, pdf_ocr) |
rlm_list_buckets |
Lista buckets do Minio |
rlm_list_s3 |
Lista objetos em um bucket |
rlm_upload_url |
Gera URL assinada para upload |
Funções Disponíveis Dentro do Código (RLM)
Dentro do código executado via rlm_execute, estas funções estão disponíveis:
| Função | Descrição |
|---|---|
llm_query(prompt, data=None, model=None) |
Faz sub-chamada a um LLM |
llm_stats() |
Retorna estatísticas de uso |
llm_reset_counter() |
Reseta contador de chamadas |
Ler e citar uma passagem
Depois de encontrar uma fonte e linha na busca:
rlm_read(var_name="livro", start_line=120, line_count=40, max_chars=12000)
A resposta contém o texto exato e a origem conhecida. pages usa os marcadores da
extração; uma lista vazia indica página desconhecida. next traz os argumentos para
continuar a leitura, incluindo a versão: a continuação é recusada se o texto mudar.
Isso evita o limite de 500 caracteres do modo compacto de rlm_execute.
As coleções se atualizam na próxima busca após a alteração de uma fonte. PDF bruto carregado como texto e corrupção evidente são rejeitados antes de substituir dados. A validação automática não substitui a conferência da extração e das referências.
Detalhes da revisão e medidas locais: plano e resultados.
Exemplos de Uso no Claude Code ou Codex
Analisar logs massivos:
Você: "Analise o log /data/app.log e encontre todos os erros"
Claude: [usa rlm_load_file para carregar em variável 'logs']
Claude: [usa rlm_execute com código Python para filtrar erros]
Claude: "Encontrei 1,234 erros. Os mais comuns são..."
Busca exata em código:
Você: "Quantas vezes 'TODO' aparece perto de 'FIXME' no código?"
Claude: [usa rlm_load_file para carregar código]
Claude: [usa rlm_execute]:
import re
matches = re.findall(r'TODO.{0,50}FIXME|FIXME.{0,50}TODO', data)
print(f"Encontrados: {len(matches)}")
Agregação de dados:
Você: "Agrupe os logs por hora e conte requests"
Claude: [usa rlm_execute]:
from collections import Counter
hours = [line.split()[0][:13] for line in logs if 'request' in line]
counts = Counter(hours)
for hour, count in counts.most_common(10):
print(f"{hour}: {count}")
Sub-chamadas LLM (Recursive Language Model):
Você: "Analise 1GB de logs e encontre padrões de erro"
Claude: [usa rlm_execute com llm_query]:
# Divide dados massivos em chunks
chunk_size = 50000
chunks = [logs[i:i+chunk_size] for i in range(0, len(logs), chunk_size)]
# Processa cada chunk com sub-LLM (padrão map-reduce)
summaries = []
for i, chunk in enumerate(chunks):
summary = llm_query(
"Liste os erros críticos encontrados neste log:",
data="\n".join(chunk)
)
summaries.append(summary)
print(f"Chunk {i+1}/{len(chunks)} processado")
# Sintetiza resultados
final = llm_query(
"Combine estes resumos em um relatório final:",
data="\n---\n".join(summaries)
)
print(final)
Este padrão implementa o paper "Recursive Language Models" do MIT CSAIL, permitindo processar dados que excedem a janela de contexto do LLM.
Processamento de PDFs
Use data_type="pdf" ou data_type="pdf_ocr" em rlm_load_file ou rlm_load_s3:
| data_type | Uso | Requer |
|---|---|---|
pdf |
Auto-detecta: tenta pdfplumber, fallback para OCR | MISTRAL_API_KEY para fallback |
pdf_ocr |
Força OCR (para escaneados/imagens) | MISTRAL_API_KEY |
Exemplo com Minio (recomendado):
# Upload via mc CLI
mc cp relatorio.pdf minio/docs/
# No Claude Code
rlm_load_s3(bucket="docs", key="relatorio.pdf", name="doc", data_type="pdf")
Forçando OCR para documentos escaneados:
rlm_load_s3(bucket="docs", key="escaneado.pdf", name="doc", data_type="pdf_ocr")
Segurança
Sandbox Python
O REPL executa em sandbox com:
- Imports permitidos:
re,json,math,collections,datetime,csv, etc. - Imports bloqueados:
os,subprocess,socket,requests, etc. - Funções bloqueadas:
exec,eval,open,__import__, etc.
Acesso a Arquivos
- Somente arquivos em
/data/são acessíveis - Volume montado como read-only
- Path traversal é bloqueado
Rede
- Container em rede isolada (sem acesso à internet)
- Conexão apenas via localhost (SSH tunnel)
Configuração
Variáveis de Ambiente
| Variável | Padrão | Descrição |
|---|---|---|
RLM_MAX_MEMORY_MB |
1024 | Limite de memória para variáveis |
RLM_API_KEY |
(vazio) | API key para autenticação (opcional) |
OPENAI_API_KEY |
(obrigatório para llm_query) | API key do OpenAI |
RLM_SUB_MODEL |
gpt-4o-mini | Modelo para sub-chamadas LLM |
RLM_MAX_SUB_CALLS |
100 | Limite de sub-chamadas por execução |
MISTRAL_API_KEY |
(opcional) | API key do Mistral para OCR de PDFs |
MINIO_ENDPOINT |
(opcional) | Endpoint do Minio/S3 |
MINIO_ACCESS_KEY |
(opcional) | Access key do Minio |
MINIO_SECRET_KEY |
(opcional) | Secret key do Minio |
MINIO_SECURE |
true | Usar HTTPS para Minio |
Limites de Recursos (Docker)
deploy:
resources:
limits:
cpus: '2'
memory: 2G
Troubleshooting
Claude Code não encontra o MCP
- Verifique se o túnel SSH está ativo:
ps aux | grep ssh - Teste conexão:
nc -zv localhost 8765 - Verifique logs:
docker logs rlm-mcp-server
Erro "SecurityError: Import bloqueado"
O sandbox bloqueia imports perigosos. Use apenas imports permitidos.
Memória insuficiente
- Aumente
RLM_MAX_MEMORY_MB - Use
rlm_clearpara limpar variáveis não usadas - Processe dados em chunks menores
Desenvolvimento
Execute na raiz de rlm-mcp-server/, usando o mesmo arquivo de versões do CI:
uv sync --frozen --extra dev
uv run pytest tests/ -q
uv run ruff check src/ tests/
Os testes usam persistência temporária e simulam serviços externos. Para executar
um servidor local, configure autenticação e um RLM_PERSIST_DIR gravável antes de
usar uv run rlm-mcp. A instância de uso diário roda na VPS.
Licença
MIT