tds-mcp
Connects an MCP AI client to TOTVS Protheus to manage AdvPL/TLPP compilation, RPO inspection, and patch workflows.
List configured Protheus servers and connect/authenticate to a server and environment.
Compile AdvPL/TLPP sources or folders into the RPO, with optional forced recompilation and clear success/failure fields.
Run syntax-only checks without writing to the RPO.
Generate preprocessed PPO output to debug includes, defines, and translations.
Inspect RPO objects, functions, version/generation date, and applied patch history.
Generate traceable PTM patches with manifests and history.
Validate patches without applying and inspect patch contents.
Apply patches to the RPO as a destructive deploy operation.
Read language-server logs for connection/compilation diagnostics.
Integrates with TOTVS Protheus servers to compile AdvPL/TLPP sources, generate and apply patches, and inspect the RPO (Remote Program Object) repository.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tds-mcp compile the AdvPL source clientes.prw"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tds-mcp
Servidor MCP que dá a um assistente de IA (Claude Code, Claude Desktop, ou qualquer cliente MCP) a capacidade de compilar fontes AdvPL/TLPP, gerar e aplicar patches e inspecionar o RPO de servidores TOTVS Protheus.
Por baixo usa o advpls — o mesmo TDS Language Server que a extensão
tds-vscode utiliza — falando JSON-RPC via stdio.
Reaproveita a configuração que você já tem no TDS: servidores, ambientes, includes e tokens.
Não distribui binários da TOTVS. O
advplsé localizado na extensão tds-vscode já instalada na sua máquina. Você precisa ter o TDS instalado e um servidor configurado.
Requisitos
Windows (veja Limitações)
Node.js 18+
Extensão totvs.tds-vscode instalada, com pelo menos um servidor configurado e já conectado uma vez pelo VS Code
AppServer Protheus acessível (build 7.00.x)
Related MCP server: vibing-steampunk
Instalação
git clone https://github.com/Guipegoraro/tds-mcp.git
cd tds-mcp
npm install # o script "prepare" já compila o TypeScriptRegistre no Claude Code:
claude mcp add --scope user tds node "<caminho-do-clone>/dist/index.js"Ou, em qualquer cliente MCP, via configuração JSON:
{
"mcpServers": {
"tds": {
"command": "node",
"args": ["C:\\caminho\\para\\tds-mcp\\dist\\index.js"]
}
}
}Como a conexão funciona (zero-config)
O MCP lê ~/.totvsls/servers.json — o arquivo global onde o TDS guarda seus servidores.
Você não precisa cadastrar nada duas vezes:
Cliente MCP (Claude)
└── tds-mcp (Node, stdio)
├── lê ~/.totvsls/servers.json (servidores, ambientes, includes, tokens)
├── spawn advpls.exe language-server
└── JSON-RPC: $totvsserver/connect, compilation, patchGenerate, patchApply, ...O arquivo é procurado na mesma ordem que o TDS usa: TDS_MCP_SERVERS_JSON (override) →
.vscode/servers.json do workspace (opção Workspace server config) → ~/.totvsls/servers.json.
tds_list_servers mostra em arquivoConfig qual está em uso.
Autenticação, em ordem:
Token de reconexão salvo pelo TDS — funciona sem senha nenhuma. Se expirar, basta conectar no servidor pelo VS Code uma vez para renovar.
Credenciais em
~/.tds-mcp/config.json— fallback opcional (veja Configuração). O arquivo é relido a cadatds_use_server: credencial gravada com o MCP aberto vale sem reconectar.
A conexão do MCP é independente da do VS Code: ambos podem estar conectados ao mesmo tempo.
Tools
Tool | Descrição | Efeito |
| Servidores do servers.json, ambientes, sessão ativa e binário advpls em uso | read-only |
| Conecta/autentica em servidor + ambiente (token do TDS, ou | sessão |
| Compila fontes/pastas no RPO; | grava no RPO |
| Verifica sintaxe com o linter do TDS (erros e avisos com linha) e a colisão de nomes nos 10 primeiros caracteres; não usa o AppServer | nenhum |
| Fonte pré-processado (debug de | nenhum |
| Lista objetos do RPO (filtro + datas) | read-only |
| Lista os fontes compilados com | read-only |
| Remove do RPO os temporários registrados; outro fonte só com | remove do RPO |
| Lista funções do RPO (fonte + linha) | read-only |
| Versão do RPO + histórico de patches aplicados | read-only |
| Gera PTM com manifesto e rastreabilidade | read-only no RPO |
| Valida patch contra o RPO sem aplicar | read-only |
| Lista o conteúdo de um | read-only |
| Aplica patch no RPO (deploy) | destrutivo |
| Últimas mensagens do advpls + caminho e versões do tds-ls/extensão | read-only |
| Pastas e arquivos de uma pasta do AppServer | read-only |
| Operações que o usuário pode executar no AppServer | read-only |
| Sessões (threads) conectadas: usuário, ambiente, programa, memória. Desligada por padrão (ver abaixo) | read-only |
| Envia mensagem ao usuário de uma sessão. Desligada por padrão | afeta usuário |
| Pede à aplicação da sessão que se encerre. Desligada por padrão | destrutivo |
| Derruba a sessão imediatamente. Desligada por padrão | destrutivo |
| Executa uma função num SmartClient HTML invisível: concluído (com | executa código |
| Inicia depuração (modos headless, navegador para operar telas pelo chrome-devtools, job para StartJob/REST); | executa código |
| Espera parada / continua, próxima, entrar, sair; devolve local, pilha, Local/Private/Static, watches e o que mudou | depuração |
| Troca os breakpoints de um fonte (também com o programa rodando); condição, contagem, logpoint e rastro; avisa quando o programa já está parado | depuração |
| Variáveis por escopo (Local, Private, Public, Static, Table) e frame; expande array/JSON/tabela; bytes de string em sessão aberta com | read-only |
| Avalia expressão no ponto de parada; | executa código |
| Expressões observadas a cada parada / encerra a sessão (a thread parada num breakpoint é encerrada ali) e o WebAgent dela; no modo navegador devolve | depuração |
Segurança operacional (leia antes de usar em cliente)
tds_compile, tds_patch_generate, tds_patch_apply e tds_rpo_delete alteram o RPO de um servidor real, e as
tools de ação do monitor (tds_monitor_*) afetam usuários conectados, e
tds_run, tds_debug_start e tds_debug_evaluate executam código no servidor.
Recomendação forte: configure seu cliente MCP para sempre pedir confirmação nelas.
No Claude Code, em ~/.claude/settings.json:
{
"permissions": {
"ask": [
"mcp__tds__tds_compile",
"mcp__tds__tds_patch_generate",
"mcp__tds__tds_patch_apply",
"mcp__tds__tds_rpo_delete",
"mcp__tds__tds_monitor_send_message",
"mcp__tds__tds_monitor_kill_user",
"mcp__tds__tds_monitor_app_kill_user",
"mcp__tds__tds_run",
"mcp__tds__tds_debug_start",
"mcp__tds__tds_debug_evaluate"
]
}
}Enquanto há sessão de depuração deste tds-mcp aberta (tds_debug_start) ou tds_run em
andamento, compilação, geração, validação e aplicação de patch e remoção do RPO são
recusadas: encerre com tds_debug_stop ou espere o tds_run terminar. Sessão de outro
tds-mcp ou do TDS no mesmo AppServer não é vista.
As tools tds_monitor_* vêm desligadas: num servidor atrás de balanceador (a porta da nuvem
TOTVS, por exemplo), a conexão de monitor cai num AppServer só, e a lista sai sem as sessões dos
outros, sem erro. Elas aparecem
com "enableMonitor": true no ~/.tds-mcp/config.json (ou TDS_MCP_MONITOR=1), lido na subida do
MCP; use num AppServer sem balanceador, como o local. As ações do monitor identificam a sessão
pela thread e conferem na lista atual do monitor antes de agir.
Uma thread parada num breakpoint fica presa no AppServer até o depurador sair: tds_debug_stop
libera, e a sessão também encerra sozinha por inatividade (debugIdleMinutes) e quando o tds-mcp fecha.
As demais tools são read-only e podem ser liberadas sem risco.
Execução e depuração
Usa o debugAdapter da TOTVS (@totvs/tds-da, o mesmo do VS Code, localizado ao lado do advpls) e
o SmartClient HTML (webapp) do AppServer, num Chromium/Chrome/Edge headless controlado pelo
tds-mcp. O processo para o agente (pedir licença, alinhar fonte e RPO, escolher o modo,
inspecionar, encerrar) está na skill skills/debugar-advpl deste repositório.
Para o Claude Code enxergá-la, ligue a pasta nas skills do usuário (Windows, sem admin):
mklink /J "%USERPROFILE%\.claude\skills\debugar-advpl" "<repo>\skills\debugar-advpl"No modo navegador o tds-mcp devolve abrirCom (url, isolatedContext e, com o WebAgent,
initScript) e proximoPasso com as chamadas do chrome-devtools: new_page em about:blank no
contexto isolado e navigate_page com a url e o initScript. O contexto isolado é necessário:
o perfil normal do navegador guarda o último programa, e o webapp então descarta os parâmetros da
URL e roda o programa fora do depurador. O contexto isolado abre outra janela; o proximoPasso
manda fechar as abas em about:blank que sobram (a inicial do chrome-devtools e as tds-* de
sessões encerradas), e fica uma janela só. O initScript grava a porta do agente no localStorage
antes de o webapp carregar: o webapp informa essa porta ao AppServer ao abrir a conexão, antes de o
agente conectar, e sem ela o AppServer trata a sessão como sem agente (ExecInClient, como a porta
serial, volta vazio). O Chromium headless do tds-mcp faz o mesmo sozinho. tds_debug_wait informa
conectado enquanto nenhum webapp abriu a sessão e o estado do agente. Ao terminar,
tds_debug_stop devolve fecharAba com a aba a fechar (close_page): aberta, ela mantém no
AppServer o programa que não estava parado num breakpoint. O agente da sessão encerra quando a
página sai do programa ou a aba fecha.
Três argumentos no MCP chrome-devtools ajudam o modo navegador:
"args": ["<...>/chrome-devtools-mcp.js", "--isolated",
"--chromeArg=--disable-features=LocalNetworkAccessChecks",
"--chromeArg=--start-maximized"]--isolated: cada sessão do Claude sobe o próprio Chromium com perfil temporário. Sem ele, todas usam o mesmo perfil, e a segunda sessão recebe "The browser is already running" até a primeira fechar o navegador.--disable-features=LocalNetworkAccessChecks: o webapp de um AppServer remoto chama o WebAgent em 127.0.0.1, e o Chromium pede ao usuário a permissão "Acessar outros apps e serviços neste dispositivo" a cada servidor. O Chromium headless do tds-mcp já sobe com essa flag.--start-maximized: sem ele a janela abre menor que a tela e, com a faixa de navegador controlado por automação e a escala do Windows em 125%, a área da página fica abaixo de 768 px de altura; o webapp avisa "A resolução mínima indicada para o funcionamento do sistema é 1024 x 768". Se o aviso continuar numa tela menor,--chromeArg=--force-device-scale-factor=1desenha a página em escala 100% (texto menor na tela).
Com modulo (código ou nome, ex.: 04 ou SIGAEST) a rotina roda pelo SIGABPM dentro do módulo,
com o ambiente que o usuário tem no menu (empresa, filial, data base, variáveis do módulo). A tela
pede login e confirma os diálogos de entrada do módulo; a rotina roda sem argumentos. Sem modulo,
a função é o programa inicial e roda sem empresa aberta.
Nos modos headless e job, o arquivo que o programa manda ao navegador (PDF do FWMSPrinter sem
WebAgent, CpyS2TW) é gravado em pastaDownloads (padrão %TEMP%\tds-mcp\downloads\<data_hora>,
guardada por 24 h) e listado em arquivosBaixados; nome repetido ganha sufixo (2) em vez de
sobrescrever. O fim do programa espera até 2 s pelo início de um download.
TOTVS WebAgent
O WebAgent é o agente local da TOTVS que dá ao webapp o comportamento do SmartClient desktop:
GetRemoteType() 1, arquivo local, Excel, impressão, porta serial (MsOpenPort) e PDF abrindo no
visualizador da máquina. Ele roda na máquina do tds-mcp: arquivos, impressoras e portas COM são os
dela. O tds-mcp sobe uma instância própria do agente em cada execução, numa porta livre, sem mexer
no agente que o usuário tiver aberto, e a encerra no fim (no modo navegador, quando a página sai do
programa ou a aba fecha, no máximo 2 h depois do stop: agente encerrado com a página ligada faria o
webapp abrir outro pelo protocolo web-agent: do Windows).
Ligado por padrão no modo navegador (alguém acompanha a tela); desligado em
tds_run, headless e job, que seguem recebendo o arquivo gerado como download.webAgent: true/falsemuda numa execução.O agente vem de
webAgentPathno config (executável ou pasta), deTDS_MCP_WEBAGENTou do WebAgent instalado (%LOCALAPPDATA%\Programs\web-agent).A versão do agente precisa ser a que o webapp do servidor aceita: a TOTVS amarra as versões de WebApp e WebAgent (TDN "2. WebApp - WebAgent"), e o Protheus traz os instaladores em
bin\web-agent. O tds-mcp não escolhe pela versão: confere no log da instância se o handshake fechou. Se o webapp recusar o agente ou não conectar, o headless recomeça sem agente; o modo navegador avisa notds_debug_waitpara iniciar de novo comwebAgent: false. O retorno trazwebAgentcomativoou o motivo de seguir sem ele.Agente que fala TLS com certificado não confiável no Windows não é usado, e o motivo traz o comando
Import-Certificatepara confiar no certificado da TOTVS (o tds-mcp não instala certificado).Com o agente, o PDF do FWMSPrinter é aberto no visualizador padrão da máquina e não vem em
arquivosBaixados.
Limitações do depurador TOTVS que as tools contornam: evaluate só no frame do topo (outros
frames via tds_debug_variables), sem setVariable (use x := v), pause não interrompe thread
em Sleep (inclua breakpoint), logpoint só interpola nome de variável numérica (use rastro),
erro de execução não para o depurador (a tela de erro é capturada e devolvida).
Como ler o resultado de uma compilação
Uma compilação pode falhar em dois níveis independentes — e olhar só um deles faz erro parecer sucesso:
Nível | Onde aparece | Exemplo |
Build |
|
|
Fonte |
| erro de sintaxe ( |
Uma falha de build acontece antes/fora da compilação individual: resultados pode vir
vazio ou só com SUCCESS, e ainda assim nada foi gravado no RPO (o build é revertido).
Sempre use o booleano
sucesso(ousintaxeOk) — ele já combina os dois níveis. Nunca conclua sucesso apenas porque não há itensERRORemresultados.
Quando falha, a resposta também vem marcada como erro no protocolo MCP (isError) e inclui
logDoServidor com as mensagens do AppServer — é lá que aparece, por exemplo, a dica
BuildKillUsers = 1 do COMPILEERROR-300.
Resposta enxuta: resultados lista os fontes com erro, aviso ou algum detalhe; SUCCESS sem
detalhe entra só em compiladosSemAviso. No detalhe, mensagens iguais saem uma vez com a contagem e as linhas
(warning W0008 Too few parameters calling valtype (37x, linhas 12, 40, ...)). Erros saem todos;
avisos, até 10 mensagens distintas por fonte, e o resto vira uma contagem.
Conexão que cai: com returnCode 40820, ou com a request recusada por "autoReconnect", o tds-mcp refaz a conexão do último
tds_use_server e compila de novo uma vez (no 40820 o build não tinha começado; na request recusada, reconexao avisa que SKIPPED pode ser o que a primeira tentativa gravou). As consultas (tds_rpo_*,
tds_patch_generate/validate/info, tds_server_*, tds_monitor_users) também reconectam e
repetem; o que grava ou afeta usuário (tds_patch_apply, tds_rpo_delete, envio de mensagem e
derrubada pelo monitor) só reconecta e devolve o erro, sem repetir.
Sucesso sem gravação: fontes já atualizados no RPO voltam com status SKIPPED (quando
recompile=false). Isso conta como sucesso, mas nada foi escrito — se todos forem
ignorados, a resposta traz o campo aviso dizendo isso. Confira ignorados antes de
afirmar que algo foi compilado.
Valores de returnCode medidos em AppServer 7.00.240223P: 0 sucesso, -1 erro de fonte
(sintaxe / arquivo inexistente), -300 sem acesso exclusivo ao RPO, 40840 token expirado. O
40910 veio em AppServers de clientes na cloud e no local junto com "SYMTAB in use for StartBuild", "Error when
loading Rpo DEFAULT", "Already building" ou o COMPILEERROR-300: outra compilação ou o RPO preso
impediu o início do build (código sem documentação da TOTVS).
Encoding: fontes precisam estar em CP1252
O compilador Protheus só aceita Windows-1252. Um fonte em UTF-8 com acentos vai para o
RPO com caracteres corrompidos — às vezes sem erro de compilação, o que é pior que falhar.
Como agentes de IA gravam em UTF-8 por padrão, tds_compile e tds_syntax_check
verificam antes de enviar e recusam o que não estiver em CP1252:
arquivo 100% ASCII → passa (é idêntico nos dois encodings)
bytes altos que não formam UTF-8 válido → assume CP1252 → passa
UTF-8 válido com acentos, ou BOM UTF-8 → bloqueia, dizendo qual arquivo e como converter
CP1252 com trechos em UTF-8 (agente editou parte de um fonte CP1252) → bloqueia e aponta as linhas; converter o arquivo inteiro corromperia os acentos que já estavam certos. Linha que também tem acento CP1252 (ex.:
StrTran(cTxt, "ç", "ç")) não conta. Quando a sequência é intencional (tabela de conversão de UTF-8), o usuário confirma as linhas e o agente repete comaceitarMisto: true;tds_compileetds_syntax_checklistam o que foi liberado emencodingMistoAceitoUTF-16 (BOM
FF FE/FE FFou bytes nulos, saída padrão doOut-Filedo PowerShell 5) → bloqueia
O arquivo nunca é alterado pelo MCP — a conversão é decisão sua (convert_encoding do
MCP file-tools, ou Save with Encoding → Windows 1252 no VS Code). Recursos binários
(.png, .bmp, .res) não passam pela checagem.
Semântica das datas (importante — evita conclusão errada)
O campo de data que o RPO expõe por objeto (dataFonte em tds_rpo_objects, date em
tds_patch_info, rpoDate no manifesto, dataPatch/dataRPO em tds_patch_validate)
é o mtime do arquivo-fonte registrado no momento da compilação — não o instante
em que a compilação ocorreu.
dataFonte== mtime do arquivo em disco (±2s) → o RPO contém o conteúdo atual.mtime do disco >
dataFonte→ fonte alterado depois da última compilação → recompilar.Nunca compare com data de commit git: commit posterior ao mtime é normal (editou num dia, commitou no outro) e não significa RPO desatualizado.
Exceção: tds_rpo_info.dataGeracao e as datas do histórico de patches (geradoEm,
aplicadoEm) são datas de evento reais.
Rastreabilidade de patches
Cada tds_patch_generate produz em <patchesRoot>/<cliente>/<ticket>/:
DDMMAA_HHMM_<ticket>_<customizacao>.ptm— data/hora (padrão brasileiro) lideram o nome, seguidas do ticket e do identificador da customização, ex.011026_1706_00018662_balanca_refugo_req_op.ptm. Colisão no mesmo minuto ganha segundos (DDMMAA_HHMMSS).customizacaoé obrigatório: snake_case minúsculo, sem acento, até 40 caracteres.DDMMAA_HHMM_<ticket>_<customizacao>.manifest.json— título do tcloud, título e descrição recomendados, sha256, fontes com data do RPO, servidor/ambiente/build de origem, autor, commit git (opcional)historico.jsonl— append-only por ticket (gerações, validações, aplicações)<patchesRoot>/historico-global.jsonl— histórico consolidado
Título recomendado (data e hora primeiro): 19/07/2026 20:37 — Cliente ticket — FONTE.PRW
Título do tcloud (tituloTcloud, obrigatório, até 60 caracteres, validado na entrada e devolvido
no retorno e no manifesto): ticket + o que muda, ex. 18662 Balança refugo: regras, data e requisição na OP.
Configuração
Opcional. Copie config.example.json para ~/.tds-mcp/config.json:
{
"patchesRoot": "C:\\TOTVS\\patches",
"advplsPath": "",
"credentials": {
"NomeDoServidorNoTDS": { "user": "usuario", "password": "senha" }
},
"webappUrls": { "NomeDoServidorNoTDS": "http://servidor:8080/webapp/" },
"debugIdleMinutes": 10
}patchesRoot— raiz da árvore de patches (padrãoC:\TOTVS\patches)advplsPath— só se o advpls não estiver na extensão instalada (sem ele, usa a extensão tds-vscode de maior versão;tds_server_logmostra qual binário está em uso). Também aceita a variável de ambienteTDS_MCP_ADVPLS. O advpls da extensão 2.1.6 (tds-ls 2.2.7) espera 30 s a cada subida (issue #1536), e cadatds_syntax_checkleva esses 30 s a mais (o resultado trazavisoSubida): aponte para o advpls de outra versão (o pacote.vsixda release, extraído numa pasta própria).credentials— senhas em texto plano. Prefira deixar vazio e usar o token do TDS. O arquivo fica fora do repositório; nunca o versione.webappUrls— URL do webapp por servidor, quando não forhttp(s)://<endereço>:<porta>/webapp/(porta multiprotocolo;httpsquando a validação do servidor detecta TLS, mesmo que o servers.json diga o contrário)debugIdleMinutes— minutos sem uso até a sessão de depuração encerrar (padrão 10; no modo navegador vale o triplo, porque o uso das telas pelo chrome-devtools não passa pelo tds-mcp)debugAdapterPath,chromiumPath— só se o debugAdapter ou o navegador não forem encontrados (tambémTDS_MCP_DEBUG_ADAPTEReTDS_MCP_CHROMIUM). Para o navegador headless, ochrome-headless-shelldo Chrome for Testing gasta uns 100 MB a menos por execução que o Chromium e abre com metade da CPU, e passou nos testes de webapp, WebAgent, downloads e PDF do FWMSPrinter. Em observação: na bateria completa, doistds_runsimultâneos deram tela vazia 2 vezes em 21 rodadas com ele, e nenhuma com o Chromium. Ele não tem janela: serve para ochromiumPath, não para o chrome-devtools do modo navegador. O binário vem sem assinatura digital e não se atualiza sozinho.webAgentPath— WebAgent compatível com o webapp dos servidores, quando não for o instalado (tambémTDS_MCP_WEBAGENT)enableMonitor—trueliga as toolstds_monitor_*(padrão desligado; tambémTDS_MCP_MONITOR=1). Só muda ao reconectar o MCP
Um caminho informado (advplsPath, debugAdapterPath, chromiumPath, webAgentPath ou as variáveis de
ambiente) que não existe é erro: o tds-mcp não troca por outro binário sem avisar. Campo com
tipo errado ou JSON inválido no config é ignorado com aviso em avisosConfig do tds_server_log (e no
erro do tds_use_server que depender dele). O config é relido a cada tds_use_server;
debugIdleMinutes e advplsPath só mudam ao reconectar o MCP.
Desenvolvimento e testes
npm run build # compila TypeScript
npm test # testes de lógica e do linter local (não precisa de AppServer;
# o do linter usa o advpls da extensão TDS e é pulado sem ela)
node test/smoke.mjs <servidor> [ambiente] # read-only: conecta e inspeciona o RPO
node test/debug-protocol.mjs [host] [porta] # JSON-RPC cru (diagnóstico de protocolo)
node test/debug-returncode.mjs <srv> [amb] # read-only: returnCode em cada cenário
node test/e2e-readonly.mjs <servidor> [amb] # read-only: E2E pelo servidor MCP
node test/e2e-admin-readonly.mjs <srv> [amb] # read-only: binário, privilégios, pastas e monitor
node test/e2e-debug.mjs <servidor> [amb] # COMPILA test/zTstDbg1.prw e executa/depura as funções dele
node test/e2e-debug-classe.mjs <srv> [amb] # COMPILA e REMOVE test/zTstCls1.prw e zTstCls2.tlpp; ::prop e self:prop no evaluate
node test/e2e-debug-bordas.mjs <srv> [amb] # inatividade no navegador, download no modo job, parâmetros inválidos (depois do e2e-debug)
node test/e2e-webagent.mjs <srv> [amb] # WebAgent no navegador e no headless (GetTempPath(.T.) da máquina), recusa e ausência do agente (depois do e2e-debug)
node test/e2e-monitor-acoes.mjs <srv> [amb] # COMPILA test/zTstDbg1.prw; mensagem, app kill e kill na thread do teste
node test/e2e-rpo-delete.mjs <srv> [amb] # COMPILA e REMOVE do RPO dois fontes de teste; registro de temporários
node test/e2e-recusa-depuracao.mjs <srv> [amb] # COMPILA test/zTstDbg1.prw; compilação, patch e remoção recusados com a depuração ativa e liberados depois, PPO livre (depois do e2e-debug)
node test/e2e-mcp.mjs <servidor> [ambiente] # E2E: COMPILA um fonte de teste no RPO
node test/cleanup.mjs <servidor> [ambiente] # remove o fonte de teste do RPOOs E2E aceitam TDS_MCP_TEST_USER e TDS_MCP_TEST_PASSWORD para autenticar com usuário e senha
quando o token salvo pelo TDS expirou.
O E2E compila test/zTstMcp1.prw (User Function inofensiva) e gera um patch. Use apenas
em ambiente de desenvolvimento descartável e rode o cleanup depois.
test/zTstBrw1.prw é fonte manual, sem e2e: uma FWBrowse com duplo clique, Enter e botão
da mesma ação para operar grade no modo navegador. Compile como temporário e rode com
modulo (fora de um módulo a FWBrowse não abre).
Limitações
Verificação de sintaxe: no tds-ls 2.2.x o modo
syntaxOnlyda compilação não passa pelo AppServer (é o linter local, que só reporta para arquivo aberto num workspace LSP). Por issotds_syntax_checksobe um language server próprio, abre os fontes e colhe os diagnósticos do linter, com as pastas de include do servidor (sem elas o linter não acha nem oPRTOPDEF.CHimplícito; pasta que não existe na máquina sai emincludesAusentes). O linter é mais rigoroso que o compilador em alguns casos (ex.:Forcom variável não Local vira aviso W0004 na compilação; o tds-mcp rebaixa esse caso); na dúvida, compile num ambiente de desenvolvimento.Windows apenas por enquanto: a resolução do binário procura
bin/windows/advpls.exena extensão tds-vscode. Oadvplsexiste para Linux e macOS (@totvs/tds-ls), então o suporte é uma mudança pequena emresolveAdvplsPath()— PRs bem-vindos.Prazos do advpls: compilação e patch (gerar, aplicar, validar, ler) têm 30 min para responder; remoção de fonte do RPO, 5 min; conexão, autenticação e consultas, 90 s cada (abaixo dos 120 s em que o Claude Code passa a chamada para segundo plano). No prazo vencido o advpls é avisado do cancelamento, mas o AppServer pode continuar: depois de um timeout de compilação o build pode terminar e gravar no RPO, então confira com
tds_rpo_objectsantes de repetir. A verificação de sintaxe espera até 60 s a subida do advpls e avisa (avisoSubida) quando ela passa de 20 s.O protocolo
$totvsserver/*não é um contrato público da TOTVS. Ao atualizar a extensão TDS, o binário muda junto; se algo quebrar,tds_server_logajuda a diagnosticar. A especificação viva ésrc/protocolMessages.ts.O advpls não aceita o handshake LSP
initializecom params mínimos (derruba o processo com0xC0000409). Os requests$totvsserver/*são enviados diretamente — é o que o@totvs/tds-languageclientoficial também faz.Fora do escopo (mas mapeados no protocolo):
defragRPO,rpoCheckIntegrity,deletePrograms,wsdlGenerate.
Alternativas headless
Se você precisa de CI/CD em vez de um assistente:
advpls cli <script.ini>— modo CLI oficial do TDS Language Server (script INI em CP1252)appserver.exe -compile— compilação/patch direto pelo AppServer, usado nos pipelines oficiais da TOTVS (totvs/protheus-ci-universo)
Créditos
Este projeto não é afiliado à TOTVS. O protocolo foi derivado do código-fonte público do
tds-vscode (Apache-2.0) e da documentação do
tds-ls. As regras de encoding CP1252, a lista de
extensões compiláveis e parte do troubleshooting seguem a skill oficial
advpl-tlpp-compile (Engenharia Protheus, MIT). Protheus, AdvPL, TLPP e TOTVS são marcas de
seus respectivos proprietários.
Licença
MIT — veja LICENSE.
Available Tools
10 toolstds_generate_ppoGerar PPO (fonte pré-processado)ARead-only
Retorna o fonte após o pré-processador (resolução de #include/#define). Útil para depurar problemas de defines e includes.
Inputs: arquivo (required).
tds_patch_applyAplicar patch no RPOADestructive
APLICA um patch no RPO do ambiente conectado (operação de deploy — altera o ambiente). Por padrão aplica somente fontes mais novos; use aplicarAntigos=true para forçar. Recomenda-se tds_patch_validate antes.
Inputs: arquivoPatch (required), aplicarAntigos.
tds_patch_generateGerar patch (PTM) com rastreabilidadeA
Gera um patch PTM a partir de fontes já compilados no RPO, com organização padrão (///DDMMAA_HHMM_.ptm, datas no padrão brasileiro), manifesto JSON (sha256, fontes, datas do RPO, servidor, autor, git) e histórico. Retorna também título e descrição recomendados — o título começa com data e hora. No manifesto/retorno, rpoDate de cada fonte é o mtime do arquivo-fonte na compilação (semântica de tds_rpo_objects), não o instante da compilação.
Inputs: fontes (required), ticket (required), cliente (required), descricao, +1 more.
tds_patch_infoInspecionar conteúdo de patchARead-only
Lista o conteúdo (fontes, datas, tamanhos) de um arquivo de patch sem aplicá-lo. Auditoria de patch recebido de terceiros. O campo date de cada objeto é o mtime do arquivo-fonte registrado na compilação (mesma semântica de tds_rpo_objects).
Inputs: arquivoPatch (required).
tds_patch_validateValidar patch (sem aplicar)ARead-only
Valida um arquivo de patch contra o RPO do ambiente conectado, sem aplicar. Aponta fontes do patch mais antigos que o RPO. Gate recomendado antes de tds_patch_apply. As datas comparadas (dataPatch/dataRPO) seguem a semântica de mtime do arquivo-fonte na compilação, não do instante de compilação.
Inputs: arquivoPatch (required).
tds_rpo_functionsListar funções do RPOARead-only
Lista funções do RPO com fonte e linha onde estão definidas. Use filtro para procurar uma função específica (ex.: 'U_TEC10R06').
Inputs: filtro, limite, apenasPublicas.
tds_rpo_infoInformações do RPOARead-only
Versão do RPO, data de geração e histórico de patches aplicados no ambiente conectado. Auditoria pré/pós-deploy.
Inputs: ultimosPatches.
tds_rpo_objectsListar objetos do RPOARead-only
Lista fontes/recursos do RPO do ambiente conectado. Use filtro para limitar (ex.: 'TEC10'). ATENÇÃO à semântica de dataFonte: é o mtime (data de modificação) do ARQUIVO-FONTE registrado no momento da compilação — NÃO é o instante em que a compilação ocorreu. Uso correto: comparar com o mtime do arquivo em disco — igual (±2s) significa que o RPO contém o conteúdo atual do arquivo; disco mais novo significa fonte alterado depois da última compilação. NÃO compare com data de commit git (commit posterior ao mtime é normal). Sem filtro retorna contagem + primeiros 100.
Inputs: filtro, limite, incluirRecursos.
tds_server_logLog do language serverARead-only
Últimas mensagens emitidas pelo advpls nesta sessão (diagnóstico de conexão/compilação).
Inputs: no named parameters.
tds_syntax_checkVerificar sintaxe (sem gravar no RPO)ARead-only
Compila com syntaxOnly: valida os fontes no servidor SEM commitar no RPO. Sem efeito colateral — pode ser usada livremente antes de tds_compile. Confie no campo sintaxeOk: ele considera tanto returnCode (falha de build) quanto os status por fonte. Lista resultados vazia NÃO significa sucesso.
Inputs: arquivos (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
Each tool serves a distinct purpose (syntax check, listing RPO objects/functions, preprocessor, server log, RPO info, patch operations). No two tools overlap in functionality; descriptions clearly differentiate them.
All tools follow a consistent 'tds_verb_noun' pattern with snake_case (e.g., tds_syntax_check, tds_rpo_objects). Naming is predictable and uniform across the set.
10 tools cover the full workflow of TDS/ADVPL development: syntax checking, RPO exploration, preprocessor, logging, and patch lifecycle. The count is appropriate for the domain without redundancy.
The tools cover core operations: syntax validation, object/function listing, preprocessor output, server diagnostics, and patch management. Minor gap: no direct tool to fetch raw source file content (though generate_ppo provides preprocessed source).
Maintenance
Related MCP Connectors
Plan Salesforce deploys, open pull requests and trigger pipelines from your AI client.
The OpenRouter MCP server plugs OpenRouter into the AI tools you already use. Once connected, your assistant can pull live OpenRouter data (models, prices, your credits, rankings, and docs) and send quick test messages, all without leaving your editor.
Run accessibility, contrast, and design token audits and file QA issues from your AI coding tool.
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to perform Business Central AL development tasks including language server operations, container management, Git version control, and file system operations for professional BC development workflows.-
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to access SAP ADT APIs for reading, writing, debugging, deploying, and testing ABAP code through natural language or DSL automation.530MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to interact with VS Code for language intelligence, debugging, and code execution.17MIT
- AlicenseBqualityDmaintenanceProvides AI assistants with VS Code integration for file operations, command execution, project analysis, and development workflow automation.29MIT