递归语言模型 MCP 服务器

RLM MCP Server 是一个通过 MCP 协议为 Claude Code 和 Codex 提供递归语言模型能力的开发服务,可在代理上下文之外加载、查询和分析大规模日志、代码、PDF 等数据,适用于超大数据集与超长文档的离线分析场景。

  • by delonsp
  • Python
  • 混合部署
  • 更新于
在 GitHub 查看 delonsp/rlm-mcp-server

使用说明

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

  1. No Dokploy, crie um novo Application
  2. Source: Git → URL do repositório
  3. Build: Docker Compose
  4. 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.com pelo 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

  1. Verifique se o túnel SSH está ativo: ps aux | grep ssh
  2. Teste conexão: nc -zv localhost 8765
  3. Verifique logs: docker logs rlm-mcp-server

Erro "SecurityError: Import bloqueado"

O sandbox bloqueia imports perigosos. Use apenas imports permitidos.

Memória insuficiente

  1. Aumente RLM_MAX_MEMORY_MB
  2. Use rlm_clear para limpar variáveis não usadas
  3. 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

Referências