LangWizard MCP

Saudações.

Apresento a vocês o projeto LangWizard MCP (LW-MCP), um software simples e pontual que oferece um servidor MCP para armazenamento de documentos MarkDown (.md).

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian ou Alpine);
  • Internet no servidor (sua VPS ou host);
  • Docker CE instalado;

1 – Sobre LangWizard MCP

O LZ-MCP é um software de gerenciamento de arquivos MarkDown para acesso via WEB (HTTP/HTTPs) e MCP (Model Context Protocol).

Vou explicar alguns conceitos, problemas, soluções e como ao final o LangWizard MCP oferece alternativas e soluções.

1.1 – Instruções para Agentes de IA

Quando trabalhamos com agentes de IA temos alguns problemas chatos:

  • Onde ficam os prompts?
  • Onde ficam as especificações (Spec-Driven Development — SDD) do sistema?
  • Onde ficam as SKILLs com habilidades e tutoriais específicos para os agentes?

A resposta mais ingênua é: Na pasta do projeto no seu notebook, e mais tarde no GIT.

1.2 – O problema do MONOREPO

Para cada novo projeto nós criamos as specs, baixamos as skills, criamos os prompts e agentes e depois de algumas horas temos um sistema estável para a IA pilotar (Claude Code, Antigravity, OpenCode, Codex, etc).

Esse tipo de prática é a melhor que existe para sistemas MONOREPO – uma (mono) pasta de projeto (repositório) que contem o software inteiro: Froentend, backend, bibliotecas, testes, assets (imagens, ícones, css), specs, documentações, etc.

O MONOREPO tem um ponto fraco: Consumo de TOKENS progressivo e instabilidade, ambos aumentam com o crescimento do código e da lógica. Nem vou citar os problemas de branchs no GIT que podem virar uma bagunça.

Chega em um ponto que somente modelos caros (Claude OPUS, GPT Pro) conseguem tocar sem estragar uma coisa para cada oura coisa arrumada. Fazer uma pergunta pode drenar seus créditos diários pois a janela de contexto é saturada de inclusões de arquivos.

1.3 – Arquitetura de micro-serviço

Quando um software cresce muito, o melhor desenho para continuar é dividi-lo em pedaços que se encaixam na hora do build (compilação) e deploy.

Divisões:

  • Por biblioteca: As funções e procedimentos mais simples são transformados em bibliotecas, cada biblioteca vira um projeto separado
    • Exemplos: “lib-crypto-enterprise”, “lib-license-sdk”, “lib-schemas”;
    • Projeto principal: Apenas inclui as bibliotecas como dependências;
  • Por funcionalidade: As partes que sobram são divididos em serviços que se comunicam internamente para prover autenticação, CRUD, eventos, etc:
    • Por canais: APIs internas, HTTP, JRCP, gRCP;
    • Por mensageria: NATS, RabbitMQ, Kafka;
    • Por claim check: Criar objeto em banco (SQL, NoSQL) e comunicar identificador por evento PUB/SUB (Redis/Valkey, NATS, Postgres, MongoDB);

Em todos os casos, o problema surge agora:

Qual a fonte de verdade das especificações se todos os projetos de bibliotecas e serviços precisaram compartilhar especificações?

Especificações, skills e prompts vão se repetir em vários projetos, o projeto A que precisa ser comunicar com os projetos B e C precisam ter 3 especificações A,B,C para não errar.

Não vale responder “A IA lê o código fonte e aprende” pois isso é exatamente o que queremos evitar para não explodir a janela de contexto do modelo.

1.4 – Contexto na nuvem

Para resolver o problema de duplicação e descasamento de contextos (specs, skills, prompts) existem sistemas que centralizam na nuvem esses arquivos, principais sistemas:

  • Context7: https://context7.com/, um dos melhores repositórios de Skills do mundo;
  • King Context;
  • GitMCP: Converte repositórios GibHub em documentação por acesso MCP;
  • MCPDoc: Dos mesmos criadores do LangChain, focado extração de arquivos llms.txt;
  • Docmancer: Opção self-hosted para ingestão de documentações;
  • ContextQMD: Obter documentação remota e importar para RAG local;
  • Outros sistemas: Procure em https://mcp.directory/servers?q=skills;

O objetivo de todos eles é o mesmo: Armazenar de maneira centralizada as informações de um projeto para guiar agentes de IA.

1.5 – LangWizard MCP como servidor de contexto

O LangWizard MCP é uma das alternativas simplistas e direta com implementação imediata e sem dependências chatas.

Seu diferença é ser um único software capaz de prover muitos servidores MCP de contexto na mesma URL de base.

Com esse design, você pode espalhar cada arquivo (documentação, skill e prompt) em servidores MCP específicos para a finalidade.

Após criar o primeiro servidor MCP você já pode entregá-lo ao seu agente.

Pequenos agentes de IA usando modelos baratos podem fazer um ótimo trabalho pontual.

2 – Instalação

A instalação será feita em Docker. Tenha previamente o Docker e o Traefik instalados.

Configure um nome de DNS, por exemplo:

  • langwizard-adm.seudominio.com.br para administrar os servidores MCP;
  • langwizard-mcp.seudominio.com.br para o servidor MCP;

Os dois containers precisam usar o mesmo volume, preparando diretório:

Bash
# Diretorio de dados persistentes:
    DATADIR=/storage/langwizard-mcp;
    mkdir -p $DATADIR;

# Imagem do container:
    IMAGE="tmsoftbrasil/langwizard-mcp:latest";
    docker pull $IMAGE;

Rede Docker para os containers de MCP (network_tools):

Bash
# Rede Docker: network_tools
docker network create \
    -d bridge \
    \
    -o "com.docker.network.bridge.name"="br-net-tools" \
    -o "com.docker.network.bridge.enable_icc"="true" \
    -o "com.docker.network.driver.mtu"="1500" \
    \
    --subnet 10.242.0.0/16 --gateway 10.242.255.254 \
    --ipv6 \
    --subnet=2001:db8:10:242::/64 \
    --gateway=2001:db8:10:242::ffff \
    \
    network_tools;

2.1 – Container de administração

O container abaixo serve para administrar o LangWizard, recursos:

  • Criar servidores MCP;
  • Criar e editar arquivos por tipo:
    • file: Arquivo acessível via tools do protocolo MCP;
    • skill: Arquivo acessível via context do protocolo MCP;
    • prompt: Arquivo acessível via prompts do protocolo MCP.

Edite as variáveis antes de aplicar, script:

Bash
# Endereco de DNS do servidor para HTTPs
    FQDN_ADMIN="langwizard-adm.seudominio.com.br";

# Variaveis
    NAME="langwizard-adm";
    LOCAL=$NAME.intranet.br;

    # Renovar/rodar
    docker rm -f $NAME 2>/dev/null
    docker run \
        -d --restart=always \
        --name $NAME -h $LOCAL \
        --read-only \
        \
        --cpus=2 \
        --memory 256m --memory-swap 256m --memory-reservation 128m \
        \
        --network network_tools \
        --ip=10.242.132.201 \
        --ip6=2001:db8:10:242::132:201 \
        --mac-address "02:1e:01:32:02:01" \
        \
        -v $DATADIR:/data \
        \
        -e ADMIN_PASSWORD=tulipa@123 \
        -e DATA_DIR=/data \
        -e LOG_LEVEL=INFO \
        -e FRONTEND_DIR=/app/mcp-admin/frontend/dist \
        \
        -w /app/mcp-admin \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN_ADMIN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=8000" \
        \
        $IMAGE \
            uvicorn app.main:app --host "0.0.0.0" --port "8000";

2.2 – Container de servidores MCP

O container abaixo é um servidor MCP multi-tenant, capaz de servir aos usuários (clientes MCP) todos os servidores MCP cadastrados na administração.

Esse container replicável, ou seja, crie quantos precisar para aguentar a demanda dos clientes.

Recursos:

  • Listar servidores MCPs;
  • Acessar servidor MCP específico e listar recursos:
    • Tools: Procedimentos acionados pelo cliente, como listar arquivos, obter conteúdo de arquivos hospedados pelo LangWizard;
    • Skills (Resources): Arquivos MarkDown com descrição de habilidades;
    • Prompts: Arquivos de qualquer tipo fornecido em forma de prompt “user”;

Lembre de edite as variáveis antes de aplicar:

Bash
# Endereco de DNS do servidor para HTTPs
    FQDN_ADMIN="langwizard-mcp.seudominio.com.br";

# Variaveis
    NAME="langwizard-mcp";
    LOCAL=$NAME.intranet.br;
    FQDN_MCP="$NAME.$(hostname -f)";

    # Renovar/rodar
    docker rm -f $NAME 2>/dev/null
    docker run \
        -d --restart=always \
        --name $NAME -h $LOCAL \
        --read-only \
        \
        --cpuset-cpus 4,5,6,7 --cpus=4 \
        --memory 2g --memory-swap 2g --memory-reservation 1g \
        \
        --network network_tools \
        --ip=10.242.132.202 \
        --ip6=2001:db8:10:242::132:202 \
        --mac-address "02:1e:01:32:02:02" \
        \
        -v $DATADIR:/data \
        \
        -e DATA_DIR=/data \
        -e LOG_LEVEL=INFO \
        \
        -w /app/mcp-server \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN_MCP\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=8001" \
        \
        $IMAGE \
            uvicorn app.main:app --host "0.0.0.0" --port "8001";

.

Tentei fugir de mim,
mas onde eu ia eu estava.
Tiririca

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com