Skip to main content
Glama
engoetz

sap-adt-mcp

by engoetz
README.md
# sap-adt-mcp

[![tests](https://github.com/engoetz/sap-adt-mcp/actions/workflows/tests.yml/badge.svg)](https://github.com/engoetz/sap-adt-mcp/actions/workflows/tests.yml)
[![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](pyproject.toml)

Servidor MCP e cliente Python para a API REST do **SAP ADT** (ABAP Development Tools). Dá ao seu
assistente de IA as mesmas operações que o Eclipse ADT usa — pesquisar o repositório, ler e gravar
código-fonte, ativar, verificar sintaxe e trabalhar com transport requests — falando com os mesmos
endpoints `/sap/bc/adt/*`.

> Documentação técnica completa também em inglês: [docs/PROJECT_DOCUMENTATION.md](docs/PROJECT_DOCUMENTATION.md).

---

## O que dá para fazer

- **Pesquisar e navegar** — objetos por curinga (`Z*`, `ZCL_*`), conteúdo de pacotes (inclusive com namespace `/ACME/PKG`) e metadados
- **Ler e gravar fonte** — com bloqueio, atribuição de transport e ativação em uma única chamada; opcionalmente salvando/lendo arquivos locais
- **Ativar e verificar sintaxe** — com mensagens de erro por linha e coluna
- **Transports** — listar, criar, liberar e checar se um objeto precisa de um
- **Criar objetos** — programas, classes, interfaces e pacotes (locais ou transportáveis)
- **Exportar DDIC em Markdown** — tabelas, elementos de dados, domínios e views viram contexto legível para a IA
- **Funcionar em releases antigas** — os media types são negociados por endpoint e o `sap_system_info` diz o que aquele sistema suporta

As credenciais ficam no **gerenciador de credenciais do sistema operacional**; nenhuma senha é
gravada em arquivo do projeto.

---

## Requisitos

| Requisito | Mínimo | Verificação |
| --------- | ------ | ----------- |
| Python | 3.10+ | `python --version` |
| Sistema SAP | NetWeaver 7.31 SP04+ com o nó ICF `/sap/bc/adt` ativo | `sap-adt test <ID>` |
| Cliente MCP | Cursor, Claude Code, Claude Desktop, VS Code ou outro com suporte a MCP | — |
| Rede | acesso ao host e porta do SAP | — |

Pré-requisitos do lado SAP (serviços ICF, roles e objetos de autorização) estão detalhados na
[seção 6 da referência de comandos](docs/MCP_COMMAND_REFERENCE.md#6-pré-requisitos-sap-para-adt).

---

## Instalação

### Direto do GitHub (recomendada)

```bash
pip install git+https://github.com/engoetz/sap-adt-mcp
```

Isso registra dois comandos no PATH:

| Comando | Para quê |
| ------- | -------- |
| `sap-adt` | gerenciar conexões pelo terminal (senha em prompt oculto) |
| `sap-adt-mcp` | executar o servidor MCP (stdio) |

Sem instalar nada permanentemente, com [uv](https://docs.astral.sh/uv/):

```bash
uvx --from git+https://github.com/engoetz/sap-adt-mcp sap-adt-mcp
```

### A partir do código-fonte (para desenvolver)

```bash
git clone https://github.com/engoetz/sap-adt-mcp
cd sap-adt-mcp
python -m venv .venv && .venv/Scripts/activate   # Linux/macOS: source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest tests -q
```

---

## Configurar no cliente MCP

Depois da instalação, o comando `sap-adt-mcp` já está no PATH — não é preciso caminho absoluto:

```json
{
  "mcpServers": {
    "sap-adt": {
      "command": "sap-adt-mcp",
      "args": []
    }
  }
}
```

Onde colocar esse bloco:

| Cliente | Arquivo |
| ------- | ------- |
| Cursor (global) | `~/.cursor/mcp.json` — Windows: `C:\Users\<usuário>\.cursor\mcp.json` |
| Cursor (por projeto) | `.cursor/mcp.json` na raiz do projeto — há um modelo em [`.cursor/mcp.json.example`](.cursor/mcp.json.example) |
| Claude Code | `claude mcp add sap-adt -- sap-adt-mcp` |
| Claude Desktop | `claude_desktop_config.json` |

Se preferir rodar direto do código-fonte, sem instalar o pacote, troque por
`"command": "python", "args": ["/caminho/para/sap-adt-mcp/scripts/run_mcp.py"]`.

### Verificar

No Cursor, o servidor aparece como **user-sap-adt** em *Settings > MCP*. Para testar em qualquer
cliente, peça `sap_list_environments()` — deve devolver a lista de conexões salvas.

| Problema | Solução |
| -------- | ------- |
| Servidor não aparece | Confira o caminho do arquivo de configuração e reabra o cliente |
| Servidor em vermelho | Rode `sap-adt-mcp` no terminal e veja o erro; normalmente é o Python errado no PATH |
| `ModuleNotFoundError: sap_adt` | O pacote foi instalado em outro ambiente virtual |
| `No password available` | Rode `sap-adt password <ID>` |
| `Missing connection parameter(s)` | Rode `sap-adt add <ID>` para criar a conexão |

---

## Credenciais

### Pelo terminal (recomendado)

```bash
sap-adt add DEV
```

O comando pergunta host, porta, mandante, usuário, idioma e HTTPS (Enter aceita o valor sugerido) e,
por último, a senha — **digitada duas vezes, sem eco na tela**. Assim ela não entra no histórico do
shell nem no histórico da conversa com a IA.

```bash
sap-adt list                      # conexões salvas e se têm senha
sap-adt edit DEV --port 8020      # alterar campos sem tocar na senha
sap-adt password DEV              # trocar apenas a senha
sap-adt test DEV                  # conectar e sondar os endpoints ADT
sap-adt delete DEV                # remover conexão e senha
```

> Não existe parâmetro `--password`: por definição, a senha só entra por prompt. Para automação,
> a variável `SAP_PASSWORD` é aceita.

A senha vai para o keyring do SO (Windows Credential Manager, macOS Keychain, Linux Secret Service).
Os demais parâmetros ficam em `~/.sap-adt/environments.json`, **fora do projeto**.

### Pelo chat

`sap_save_password(system_id="DEV", host="...", port=8000, client="100", user="username", password="...")`
faz o mesmo — mas a senha fica registrada na conversa. Prefira o terminal.

---

## Primeiro uso

```
sap_connect(system_id="DEV")
sap_system_info()                       # o que este sistema suporta (rode em release antiga)

sap_search(query="Z*", object_type="CLAS")
sap_read_source(object_name="ZCL_MINHA_CLASSE", object_type="CLAS")

sap_write_source(
    object_name="ZCL_MINHA_CLASSE",
    object_type="CLAS",
    source_code="...",
    transport_request="DEVK900123"
)
```

Fora do cliente MCP, `sap-adt test DEV` faz o mesmo diagnóstico pelo terminal.

---

## Compatibilidade entre releases

Sistemas mais antigos (ECC, NetWeaver 7.3x) expõem um subconjunto do ADT e nem sempre entendem as
mesmas versões de media type. O cliente lida com isso sozinho:

- **Media types negociados** por endpoint, do mais novo ao mais antigo, memorizando o que funcionou
- **Discovery com alternativas** quando `/sap/bc/adt/discovery` não está ativo no SICF
- **Transport enviado nas duas formas** (`corrNr` na query e header `sap-transportrequest`)
- **`sap_system_info`** sonda os endpoints e diz quais ferramentas não vão funcionar ali

Detalhes na [seção 6.7 da referência](docs/MCP_COMMAND_REFERENCE.md).

---

## Ferramentas MCP (25)

### Conexão e credenciais

| Ferramenta | Descrição |
| ---------- | --------- |
| `sap_connect` | Autenticar no sistema SAP (suporta ambientes salvos) |
| `sap_disconnect` | Encerrar a conexão atual (permite trocar de sistema) |
| `sap_system_info` | Diagnóstico: quais endpoints ADT o sistema suporta |
| `sap_discovery` | Listar serviços ADT disponíveis |
| `sap_save_password` | Armazenar credenciais no gerenciador de credenciais do SO |
| `sap_delete_password` | Remover credenciais salvas |
| `sap_list_environments` | Listar ambientes SAP salvos |

### Repositório

| Ferramenta | Descrição |
| ---------- | --------- |
| `sap_search` | Pesquisar objetos ABAP (CLAS, PROG, INTF, FUGR, TABL) |
| `sap_browse_package` | Listar conteúdo de pacotes (suporta namespaces) |
| `sap_object_metadata` | Obter detalhes de um objeto (nome, tipo, pacote, responsável) |
| `sap_export_ddic_markdown` | Exportar metadados DDIC como Markdown |

### Código-fonte

| Ferramenta | Descrição |
| ---------- | --------- |
| `sap_read_source` | Ler código-fonte ABAP (opcional: salvar em arquivo local) |
| `sap_write_source` | Gravar fonte com bloqueio automático, transport e ativação |
| `sap_activate` | Compilar/ativar objetos |
| `sap_syntax_check` | Verificação de sintaxe sem ativar |

### Transports

| Ferramenta | Descrição |
| ---------- | --------- |
| `sap_check_lock` | Verificar status de bloqueio do objeto |
| `sap_list_transports` | Listar transport requests abertos |
| `sap_create_transport` | Criar novo transport request |
| `sap_release_transport` | Liberar um transport request |
| `sap_transport_check` | Verificar se objeto necessita de transport |

### Criação e exclusão

| Ferramenta | Descrição |
| ---------- | --------- |
| `sap_create_program` | Criar novo programa ABAP |
| `sap_create_class` | Criar nova classe ABAP |
| `sap_create_interface` | Criar nova interface ABAP |
| `sap_create_package` | Criar novo pacote ABAP (DEVC), local ou transportável |
| `sap_delete_object` | Excluir objeto ABAP (requer `confirm='DELETE'`) |

> Parâmetros, exemplos e retornos de cada uma: [docs/MCP_COMMAND_REFERENCE.md](docs/MCP_COMMAND_REFERENCE.md)

---

## Arquitetura

```
Cliente MCP  →  servidor MCP (stdio/JSON-RPC)  →  cliente REST ADT  →  SAP /sap/bc/adt/*
```

```
src/sap_adt/
├── client.py            # HTTP: autenticação, CSRF, sessões stateful, negociação de media type
├── credential_store.py  # ~/.sap-adt/environments.json + keyring do SO
├── repository.py        # pesquisa, navegação de pacotes, metadados
├── source.py            # leitura/escrita de fonte com bloqueio
├── activation.py        # ativação e verificação de sintaxe
├── transport.py         # transport requests (CTS)
├── ddic_export.py       # DDIC → Markdown
├── cli.py               # comando `sap-adt`
├── models.py            # dataclasses
├── exceptions.py        # hierarquia de exceções
└── mcp_server.py        # servidor MCP com as 25 ferramentas
```

| Dependência | Finalidade |
| ----------- | ---------- |
| `requests` | cliente HTTP da API REST ADT |
| `mcp` | SDK do Model Context Protocol (FastMCP) |
| `lxml` | parsing de XML |
| `keyring` | credenciais no gerenciador do SO |

---

## Desenvolvimento

```bash
pip install -e ".[dev]"
python -m pytest tests -q
```

Os testes são **offline**: nenhum sistema SAP e nenhuma rede são necessários. Eles cobrem resolução
de URI, os parsers de XML alimentados com respostas estáticas (incluindo o formato de releases
antigas) e o CLI. O CI roda a suíte em Linux e Windows, Python 3.10 e 3.13, e verifica que o pacote
constrói.

Contribuições e relatos de problema são bem-vindos pelas
[issues](https://github.com/engoetz/sap-adt-mcp/issues). Ao abrir uma issue, **não cole hostname,
usuário, mandante ou trechos de código proprietário** — descreva o comportamento e, se possível,
inclua a saída de `sap_system_info`.

---

## Documentação

| Documento | Conteúdo |
| --------- | -------- |
| [docs/MCP_COMMAND_REFERENCE.md](docs/MCP_COMMAND_REFERENCE.md) | Referência de comandos: parâmetros, exemplos, pré-requisitos SAP e o manual do CLI |
| [docs/PROJECT_DOCUMENTATION.md](docs/PROJECT_DOCUMENTATION.md) | Documentação técnica completa (inglês) |
| [docs/PROJECT_DOCUMENTATION_PT-BR.md](docs/PROJECT_DOCUMENTATION_PT-BR.md) | Documentação técnica completa (português) |
| [AGENTS.md](AGENTS.md) | Regras de trabalho para o assistente que usa as ferramentas |

---

## Licença

[Apache-2.0](LICENSE).

Projeto independente, **sem afiliação, patrocínio ou endosso da SAP SE**. SAP, ABAP e SAP NetWeaver
são marcas da SAP SE. A ferramenta apenas consome a API ADT publicamente documentada, com as
credenciais do próprio usuário.