Servidor MCP (Model Context Protocol) em Python que expõe o cliente
proxmark3.exe (fork Iceman / RfidResearchGroup, compilado via ProxSpace)
como ferramentas chamáveis por qualquer cliente MCP — Claude Desktop, Cursor,
etc. Tudo o que acontece é gravado em um banco SQLite e pode ser navegado
em uma GUI web local (Flask): tags lidas, dumps, chaves recuperadas e o log
completo de comandos.
Pensado especificamente para o Proxmark3 Easy (a versão econômica), mas funciona com qualquer Proxmark rodando firmware Iceman compatível.
📷 Dica: rode
python start.py --gui, tire um print do painel, salve emdocs/screenshot.pnge descomente a linha da imagem acima.
Esta ferramenta é para uso ético e legal. Use-a somente em:
- hardware (cartões/tags) de sua propriedade, ou
- sistemas para os quais você tem autorização escrita para testar.
Ler, clonar ou simular credenciais de terceiros sem permissão é crime na maioria dos países. Você é o único responsável pelo uso que fizer. Os autores não se responsabilizam por uso indevido.
- Proxmark3 Easy físico, com firmware Iceman compatível com o cliente.
- ProxSpace instalado e o cliente compilado.
Veja: https://github.com/Gator96100/ProxSpace e
https://github.com/RfidResearchGroup/proxmark3.
Ao final você terá um
proxmark3.exe(algo comoC:\ProxSpace\pm3\proxmark3.exe). - Python 3.10+ no Windows 10/11 64-bit.
O
libpm3(binding Python via SWIG) vem junto do ProxSpace. Se ele estiver disponível, o servidor o usa; se não, cai automaticamente para chamar oproxmark3.exepor subprocess. Você não precisa instalarlibpm3manualmente.
git clone <url-do-repositorio> proxmark-mcp
cd proxmark-mcp
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtCopie o arquivo de exemplo e edite:
copy .env.example .env
notepad .envA única variável obrigatória é o caminho do cliente:
PM3_CLIENT_PATH=C:\ProxSpace\pm3\proxmark3.exeVariáveis opcionais:
| Variável | Default | Descrição |
|---|---|---|
PM3_CLIENT_PATH |
(obrigatória) | Caminho absoluto do proxmark3.exe. |
PM3_PORT |
(auto-detect) | Porta COM de fallback (ex.: COM3) se a auto-detecção falhar. |
DB_PATH |
./data/proxmark.db |
Caminho do banco SQLite. |
DUMPS_DIR |
./data/dumps |
Onde os dumps são salvos. |
GUI_PORT |
5000 |
Porta da GUI web. |
DEFAULT_TIMEOUT |
30 |
Timeout padrão (segundos) por comando. |
A porta COM do Proxmark é detectada automaticamente por VID:PID. PM3_PORT
só é usada se a auto-detecção não encontrar nada.
# Só o servidor MCP (stdio) — é o que os clientes MCP usam:
python start.py --server
# Só a GUI web (abra http://localhost:5000):
python start.py --gui
# Os dois ao mesmo tempo (recomendado para uso diário):
python start.py --both--bothsobe a GUI em uma thread e o servidor MCP na thread principal.- Encerre com
Ctrl+C; a sessão é fechada corretamente no banco. - Todos os logs vão para o stderr (o stdout é reservado ao protocolo MCP).
No Windows, edite (crie se não existir):
%APPDATA%\Claude\claude_desktop_config.json
Conteúdo (ajuste os dois caminhos):
{
"mcpServers": {
"proxmark3": {
"command": "python",
"args": [
"C:\\caminho\\absoluto\\para\\proxmark-mcp\\start.py",
"--both"
],
"env": {
"PM3_CLIENT_PATH": "C:\\ProxSpace\\pm3\\proxmark3.exe"
}
}
}
}Reinicie o Claude Desktop. As ferramentas proxmark3 aparecerão disponíveis.
Para ter a GUI junto, rode python start.py --gui em um terminal à parte (ele
lê o mesmo banco).
Um exemplo pronto está em examples/claude_desktop_config.json.
Toda ferramenta retorna o mesmo envelope:
{ "raw": "saída crua do pm3", "parsed": { ... } | null, "error": "msg" | null }| Ferramenta | Parâmetros | Descrição |
|---|---|---|
pm3_exec |
command, timeout=30 |
Roda qualquer comando pm3 (escape hatch). |
pm3_version |
— | Versão do cliente/firmware (hw version). |
pm3_status |
— | Status do dispositivo (hw status). |
pm3_hw_tune |
— | Sintonia de antena (hw tune). |
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
hf_search |
— | Procura qualquer tag HF (hf search). |
hf_14a_info |
— | Info da tag 14a (hf 14a info). |
hf_14a_raw |
data, timeout=1000, options="" |
Envia frame cru (hf 14a raw). |
| Ferramenta | Parâmetros | Timeout | Descrição |
|---|---|---|---|
hf_mf_info |
— | 30s | Info da MIFARE Classic. |
hf_mf_rdbl |
block, key, key_type='A' |
30s | Lê um bloco. |
hf_mf_rdsc |
sector, key, key_type='A' |
30s | Lê um setor inteiro. |
hf_mf_wrbl |
block, key, key_type, data |
30s | Escreve um bloco (destrutivo). |
hf_mf_dump |
keys_file=None |
120s | Dump usando chaves conhecidas. |
hf_mf_chk |
dict_file=None |
300s | Testa chaves de dicionário. |
hf_mf_nested |
block, key, key_type='A' |
300s | Ataque nested. |
hf_mf_hardnested |
block, key, key_type='A', target_block, target_key_type='B' |
600s | Ataque hardnested. |
hf_mf_autopwn |
— | 600s | Crack + dump automáticos. |
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
hf_mfu_info |
— | Info Ultralight/NTAG. |
hf_mfu_rdbl |
block |
Lê uma página. |
hf_mfu_wrbl |
block, data |
Escreve uma página (destrutivo). |
hf_mfu_dump |
— | Dump completo. |
| Ferramenta | Parâmetros | Timeout | Descrição |
|---|---|---|---|
hf_iclass_info |
— | 30s | Info iClass (CSN). |
hf_iclass_dump |
key=None |
120s | Dump iClass. |
hf_iclass_chk |
dict_file=None |
300s | Testa chaves iClass. |
hf_legic_info |
— | 30s | Info LEGIC. |
hf_legic_rdbl |
offset, length=1 |
30s | Lê bytes do LEGIC. |
hf_legic_dump |
— | 60s | Dump LEGIC. |
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
lf_search |
— | Procura qualquer tag LF. |
lf_read |
samples=40000 |
Captura amostras LF. |
lf_config |
options="" |
Mostra/ajusta config LF. |
lf_t55xx_detect |
— | Detecta chip T55xx. |
lf_t55xx_info |
— | Decodifica o bloco de config. |
lf_t55xx_dump |
— | Dump de todos os blocos. |
lf_t55xx_write |
block, data, password=None |
Escreve bloco (destrutivo). |
lf_t55xx_wipe |
— | Reseta o T55xx (destrutivo). |
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
lf_hid_read |
— | Lê HID Prox. |
lf_hid_clone |
facility, card_number, format='H10301' |
Clona HID para T5577. |
lf_hid_sim |
facility, card_number, format='H10301' |
Simula HID. |
lf_indala_read |
— | Lê Indala. |
lf_indala_clone |
uid |
Clona Indala para T5577. |
lf_awid_read |
— | Lê AWID. |
lf_awid_clone |
facility, card_number, fmt=26 |
Clona AWID para T5577. |
lf_em_410x_read |
— | Lê EM410x. |
lf_em_410x_clone |
uid |
Clona EM410x para T5577. |
lf_em_410x_sim |
uid |
Simula EM410x. |
lf_hitag_info |
— | Info Hitag. |
lf_hitag_read |
password=None |
Lê Hitag. |
lf_hitag_dump |
password=None |
Dump Hitag. |
| Ferramenta | Parâmetros | Descrição |
|---|---|---|
script_run_lua |
script_path, args=[] |
Roda script Lua (script run). |
script_run_py |
script_path, args=[] |
Roda script Python (script run). |
db_list_tags |
tag_type=None, limit=50 |
Lista tags do histórico. |
db_get_tag |
tag_id |
Tag + dumps + chaves relacionados. |
db_list_dumps |
tag_id=None, limit=50 |
Lista dumps. |
db_get_dump |
dump_id |
Metadados de um dump. |
db_list_recent_commands |
limit=20 |
Últimos comandos executados. |
db_search |
query |
Busca em tags, dumps e comandos. |
db_export_dump |
dump_id, format='bin' |
Exporta conteúdo do dump (hex/json/eml). |
Timeouts: comandos de cracking (
hf_mf_chkcom dicionário grande,hf_mf_nested,hf_mf_hardnested,hf_mf_autopwn,hf_iclass_chk) já usam timeouts maiores (300–600 s). Para comandos longos viapm3_exec, passe umtimeoutadequado.
- "Veja se tem alguma tag no leitor e me diga o tipo."
- "Faça dump da MIFARE Classic que tá no leitor usando dicionário padrão."
- "Clone esse cartão HID Prox pra um T5577."
- "Mostre as últimas 20 tags que eu li."
Mais exemplos em examples/prompts.md.
O Proxmark3 Easy é a versão econômica. Em relação ao RDV4, ele não tem:
- Memória flash on-device → este servidor não expõe
mem load/save/wipe/dump. Dumps e dicionários ficam no PC, não na placa. - Leitor de smartcard → comandos
smart ...não são expostos. - Bluetooth → conexão é sempre por USB (cabo).
- FPC / antenas destacáveis → antenas únicas integradas; botão único.
Nenhuma feature exclusiva de RDV4 é assumida.
Porta COM não detectada
Verifique os drivers USB. No Windows pode ser preciso instalar o driver
usbser/CDC (ou usar o Zadig). Como alternativa, defina PM3_PORT=COMx no
.env. Confira a porta no Gerenciador de Dispositivos.
libpm3 não importa
Isso é normal fora do ambiente ProxSpace. O servidor cai automaticamente
para o modo subprocess (você verá no log: "libpm3 indisponivel ... Usando
subprocess"). Funciona igual, só reconecta a cada comando.
error while loading shared libraries: libreadline8.dll (ou outra DLL)
O proxmark3.exe compilado no ProxSpace depende de DLLs do runtime msys2/mingw
que ficam numa pasta libs/ ao lado do exe. O servidor detecta e adiciona
essa pasta ao PATH do subprocess automaticamente. Se o seu layout for atípico,
aponte a pasta das DLLs com PM3_DLL_DIR=... no .env.
Could not find the Qt platform plugin "windows" in "" / diálogo de erro do Qt
O cliente Iceman inicializa o Qt (janela de plot do sinal) ao conectar e aborta
com um diálogo se não achar o plugin de plataforma. O servidor resolve isso
sozinho: localiza a pasta plugins/platforms do Qt e força
QT_QPA_PLATFORM=offscreen (headless, sem janela). Para ver o plot de verdade,
sobreponha QT_QPA_PLATFORM=windows no .env/no env do Claude Desktop.
Saída do pm3 com "lixo" / parser retornando null
Versões diferentes do cliente Iceman mudam levemente a formatação. Quando o
parser não reconhece a saída, ele retorna parsed: null e o texto cru fica em
raw (nada se perde). Ajuste o regex do parser correspondente em
src/parsers/ se quiser estruturar aquela saída.
Sintaxe de comando rejeitada (especialmente LF/Hitag)
A sintaxe exata de alguns subcomandos (Hitag, lf read, lf config) varia
entre versões do Iceman. Se uma ferramenta dedicada falhar, use pm3_exec com
o comando exato da sua versão (consulte <comando> -h no cliente).
Antenna detuned (tensões baixas no hw tune)
Rode pm3_hw_tune. Tensões muito baixas indicam antena fora de sintonia ou
problema de hardware/cabo.
ModuleNotFoundError
Rode pip install -r requirements.txt dentro do venv ativado.
proxmark-mcp/
├── requirements.txt
├── README.md # este arquivo (PT-BR)
├── .env.example # modelo de configuração
├── start.py # launcher: --server | --gui | --both
├── conftest.py # torna o projeto importável nos testes
├── src/
│ ├── config.py # carrega .env, valida caminhos
│ ├── port_detect.py # auto-detect da porta COM via VID:PID
│ ├── pm3_client.py # cliente híbrido libpm3 / subprocess (+lock +log)
│ ├── server/
│ │ ├── mcp_server.py # FastMCP, registra todas as tools, stdio
│ │ └── tools/ # uma ferramenta por subcomando do pm3
│ ├── parsers/ # parsers de saída (HF + LF), tolerantes a ANSI
│ ├── db/ # schema.sql, conexão (WAL), models, repository
│ └── gui/ # app Flask, rotas, templates Jinja2, estáticos
├── examples/
│ ├── claude_desktop_config.json
│ └── prompts.md
└── tests/
└── test_parsers.py # um teste por parser com saída real mockada
MIT. Veja o cabeçalho ou adicione um arquivo LICENSE conforme preferir.