Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
mcpsnoop — Wireshark para MCP. Um proxy transparente que mostra cada chamada de ferramenta real entre o seu cliente de IA e os seus servidores MCP, em tempo real no seu terminal. | Kitploit
Ferramentas/GitHubGitHub/kerlenton/mcpsnoop
Utilitários de Propósito GeralAnálise Dinâmica (Sandboxing)Mapeamento de RedeProxies Web e InterceptaçãoScripting e AutomaçãoTestes de Segurança de APIsDepuradoresAnálise de Logs
GitHubkerlenton/mcpsnoop

mcpsnoop

Wireshark para MCP. Um proxy transparente que mostra cada chamada de ferramenta real entre o seu cliente de IA e os seus servidores MCP, em tempo real no seu terminal.

3343220há 13 diasRevisado pelo Kitploit
Ver Repositório

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

mcpsnoop

Wireshark para MCP. Um proxy transparente que mostra cada chamada real de ferramenta entre o seu cliente de IA e os seus servidores MCP, ao vivo no seu terminal.

CI Go Reference MIT Marketplace

mcpsnoop demo

O problema

O MCP Inspector oficial conecta-se como um cliente próprio, por isso nunca vê o que o seu cliente (Cursor, Claude Code, Codex) realmente envia ao seu servidor. E qualquer coisa que espere por uma solicitação chegar não consegue mostrar a chamada que o modelo nunca fez, ou que fez com os argumentos errados. Quando uma ferramenta silenciosamente não é chamada, as capacidades não se alinham, ou uma chamada simplesmente trava, você fica vasculhando logs e adivinhando.

O mcpsnoop fica no caminho real dos dados. Envolva o comando do seu servidor com ele e observe cada frame JSON-RPC ao vivo, enquanto o seu cliente e servidor reais conversam.

Em CI

Esta página também é a listagem da GitHub Action mcpsnoop, então aqui está tudo sobre ela. Ela verifica uma sessão capturada, registra cada descoberta como um alerta de code scanning e falha o job com base no que você definiu como bloqueio.```yaml permissions: security-events: write contents: read

steps:

  • uses: kerlenton/[email protected] with: session: artifacts/session.jsonl
root@kitploit:~
Escolha a versão que quiser. A mais recente está na
[página de releases](https://github.com/kerlenton/mcpsnoop/releases). Cada entrada,
o que significam os códigos de saída e como integrá-lo sem a action estão em
[A GitHub Action](#the-github-action) mais abaixo.

## Início rápido

Veja-o imediatamente, sem nada para configurar.```bash
mcpsnoop demo

Para usá-lo de verdade, envolva o seu servidor na configuração MCP do seu cliente.```json { "mcpServers": { "my-server": { "command": "mcpsnoop", "args": ["--", "node", "build/index.js"] } } }

root@kitploit:~
Tudo o que vem depois de `--` é o comando que normalmente inicia o seu servidor. Substitua por
o que você já usa, como `python server.py`, `npx -y @scope/server`, ou um
binário compilado.

No Claude Desktop você não precisa fazer essa edição manualmente.```bash
mcpsnoop wrap my-server     # route my-server through mcpsnoop
mcpsnoop unwrap my-server   # put it back

wrap localiza o claude_desktop_config.json, copia-o para claude_desktop_config.json.mcpsnoop.bak na primeira vez e reescreve apenas a entrada daquele servidor, deixando a sua formatação e todos os outros servidores intactos. Dentro da entrada reescrita, as chaves voltam a ficar em ordem alfabética. unwrap restaura o arquivo e remove o backup assim que nenhum servidor estiver mais com wrap. Reinicie o Claude Desktop após qualquer uma das operações, pois os servidores MCP são iniciados uma única vez na inicialização.

Depois, use o seu cliente normalmente e abra a interface.```bash mcpsnoop

root@kitploit:~
Sem sinalizadores, sem caminhos de socket, sem ordem de inicialização para lembrar. O shim e a interface encontram
um ao outro por conta própria, e a interface preenche sessões passadas a partir do disco.

Para um servidor HTTP transmissível, execute o mcpsnoop como um proxy reverso.```bash
mcpsnoop http --target http://localhost:3000/mcp --listen :7000

O status HTTP de cada resposta aparece no fluxo, portanto uma resposta que não carrega nenhuma mensagem JSON-RPC própria ainda é um quadro visível em vez de nada: o desafio 401, o 403 em uma Origin rejeitada, o 202 que reconhece uma notificação e o 502 quando o destino não pode ser alcançado de forma alguma. O cabeçalho WWW-Authenticate de um 401 é mantido literalmente e exibido no inspetor, já que ele nomeia o esquema de autenticação e os metadados do recurso para onde ir em seguida. Filtre por status com status:401 na TUI, ou por qualquer falha com status:err. Um 4xx ou 5xx conta como erro, portanto uma execução padrão de mcpsnoop check falha nele.

Não tem servidor próprio? Experimente de verdade contra um servidor de teste publicado, dirigido pelo seu próprio cliente. Para inspecionar uma sessão depois que ela aconteceu, veja revisar sessões passadas a partir de logs.

Arquivo de configuração

Se você reutilizar os mesmos sinalizadores de shim em um projeto, coloque-os em um arquivo .mcpsnoop.toml no diretório de trabalho atual.```toml label = "filesystem" trace-file = "trace.jsonl" redact-secrets = true redact-key = "token,authorization" redact-value = "sk-[A-Za-z0-9]+" redact-path = "$.params.arguments.password" no-trace = false

root@kitploit:~
Repita `redact-key`, `redact-value` e `redact-path` em linhas próprias para adicionar
mais de um de cada.

Essas são todas as chaves que ele suporta.

O arquivo só é procurado no diretório de trabalho atual, não em diretórios
pais.

Flags explícitas de linha de comando sobrescrevem valores do arquivo de configuração.

## Comandos

| Comando | O que faz |
|---|---|
| `mcpsnoop -- <server>` | envolve um servidor stdio como um shim transparente |
| `mcpsnoop` | abre a TUI ao vivo |
| `mcpsnoop http --target <url>` | faz proxy de um servidor HTTP streamable |
| `mcpsnoop export` | renderiza uma sessão para json, html, text, har ou otlp |
| `mcpsnoop check` | falha o CI em erros, frames inválidos, avisos, incompatibilidades de roteamento, chamadas penduradas, resultados atrasados ou um orçamento de latência |
| `mcpsnoop baseline` | inspeciona, aceita ou redefine definições de ferramentas confiáveis |
| `mcpsnoop diff` | compara ferramentas e chamadas entre duas sessões capturadas |
| `mcpsnoop open` | abre uma sessão salva na TUI |
| `mcpsnoop inventory` | lista todos os servidores que já passaram pelo mcpsnoop nesta máquina |
| `mcpsnoop stats` | consolida cada captura armazenada em uma linha por servidor e ferramenta |
| `mcpsnoop prune` | exclui logs de sessões salvas mais antigos que um limite |
| `mcpsnoop wrap <server>` | roteia um dos servidores do Claude Desktop pelo mcpsnoop |
| `mcpsnoop unwrap <server>` | restaura a entrada daquele servidor ao estado original |
| `mcpsnoop remote <user@host>` | imprime o comando de túnel SSH |
| `mcpsnoop demo` | reproduz uma sessão roteirizada |

Execute `mcpsnoop help` para a lista completa, ou `mcpsnoop help <command>` para as flags de um comando.

## Como ele se compara

| | MCP Inspector | mcpsnoop |
|---|:---:|:---:|
| Vê o tráfego real do seu cliente e servidor | não | sim |
| Sinaliza chamadas penduradas e erros de stream | não | sim |
| Sinaliza saída dispersa que corrompe o stream | não | sim |
| Sinaliza frames JSON-RPC malformados | não | sim |
| Detecta desvio de definição de ferramenta após aprovação | não | sim |
| Interface de terminal interativa | não | sim |
| Zero configuração, sem flags ou ordenação | não | sim |
| Inspetor de capacidades | parcial | sim |
| Reproduz uma chamada capturada | não | sim, via stdio e via HTTP |
| Exportação de sessão (json / html / text / otlp) | não | sim |
| Binário único, sem dependências de runtime | não | sim |

## Instalação

### npm

Sem necessidade de toolchain Go. A maioria dos servidores MCP é escrita em Node ou Python, então esta
é a forma mais rápida de começar.```bash
npx mcpsnoop -- node build/index.js

O pacote npm não inclui código próprio. Cada um dos seis pacotes de plataforma carrega uma build, e o npm instala apenas aquele que corresponde à sua máquina, portanto não há nada para baixar no momento da instalação nem nada para desbloquear em um proxy. Para mantê-lo por perto em vez de buscá-lo a cada execução, use npm i -g mcpsnoop.

Go```bash

go install github.com/kerlenton/mcpsnoop/cmd/mcpsnoop@latest

root@kitploit:~
### Homebrew```bash
brew install mcpsnoop

Binários pré-compilados para todas as plataformas estão na página de Releases.

Completions de shell

O mcpsnoop inclui completions para bash, zsh, fish e PowerShell. Execute mcpsnoop completion <shell> --help para ver os passos de configuração, que cobrem a ativação do completion e o caminho de instalação para o seu SO.

Como funciona

O mcpsnoop fica no meio do caminho entre o seu cliente de IA e os seus servidores MCP, copiando cada frame JSON-RPC para uma interface de terminal ao vivo

O mcpsnoop desempenha dois papéis em um único binário. mcpsnoop -- <server> é o shim transparente que o seu cliente inicia, encaminhando bytes exatamente como estão enquanto envia uma cópia de cada frame para o hub. mcpsnoop sem argumentos é esse hub e a sua TUI ao vivo. Eles se conectam por meio de um socket bem conhecido e de logs em disco, então nenhum deles precisa iniciar primeiro.

O hub carrega as 100 sessões salvas mais recentes por padrão, mantendo o trabalho de inicialização limitado sem excluir rastreamentos mais antigos. Use mcpsnoop --history-limit N para escolher outro limite, ou mcpsnoop --history-limit 0 para carregar todo o histórico. Sessões mais antigas permanecem disponíveis por meio de mcpsnoop open <session-id> e mcpsnoop export <session-id>.

O limite de histórico restringe quantas sessões são carregadas. Dentro de uma sessão, a TUI ao vivo é limitada duas vezes, porque um hub deixado observando um servidor muito falante cresceria até ser encerrado. Ele mantém no máximo 64 MiB de corpos de frames, liberando os mais antigos primeiro, e no máximo 200.000 frames, descartando os mais antigos por completo além disso. O primeiro limite é o que uma captura de grandes payloads encontra e o segundo é o que um longo fluxo de pequenas notificações faz.

Nenhum dos limites altera uma resposta. Um frame cujo corpo foi liberado mantém a sua linha, o seu veredito e o seu lugar na linha do tempo, e o seu inspetor diz que o corpo se foi em vez de mostrar um frame vazio. Um frame que foi descartado por completo leva primeiro as estatísticas da sua chamada de ferramenta para os totais acumulados, então o resumo de ferramentas e o que o servidor custa a você em contexto descrevem todas as chamadas que a sessão fez, não apenas as recentes. O rodapé do stream diz quantos frames mais antigos estão apenas em disco, e r recusa um frame cujos params ele não possui mais em vez de reproduzir outra coisa.

mcpsnoop open <session-id> lê o log e mantém tudo dele, e exportar a partir da TUI também lê o log, então nenhum dos dois é limitado. check, export e diff criam um armazenamento ilimitado de propósito, já que uma verificação que subestima em uma captura grande é pior do que uma que usa a memória.

O limite de histórico restringe o que é carregado. mcpsnoop prune restringe o que é mantido. Ele exclui logs de sessões salvas mais antigos que um limite, e nunca é executado por conta própria.```bash mcpsnoop prune --older-than 30d --dry-run # list what would go, remove nothing mcpsnoop prune --older-than 30d # delete after confirming mcpsnoop prune --older-than 72h --yes # skip the prompt in a script

root@kitploit:~
`--older-than` é obrigatório (não há padrão que apagaria qualquer coisa) e
aceita uma contagem de dias como `30d` ou uma duração Go como `72h`. As linhas de base das ferramentas são
deixadas intactas, pois uma linha de base é identificada pelo rótulo do servidor, e não pela sessão.

Por estar no próprio pipe, e não à margem como o Inspector, ele
vê exatamente o que seu cliente e servidor reais dizem um ao outro, seja qual for a linguagem
em que o servidor foi escrito.

## Atalhos de teclado

| Tecla | Ação | | Tecla | Ação |
|---|---|---|---|---|
| `enter` | inspecionar / aprofundar | | `/` | filtrar |
| `esc` | voltar | | `:` | comando |
| `j` / `k` | mover | | `r` / `R` | reproduzir / editar e reproduzir |
| `g` / `G` | topo / fim | | `c` | capacidades |
| `ctrl-f` / `ctrl-b` | página | | `s` | resumo da ferramenta |
| `p` | pausar | | `y` | copiar |
| `shift`+`<tecla>` | ordenar por coluna | | `e` | exportar |
| `ctrl-d` | excluir sessão | | `f` | seguir |
| `?` | ajuda | | | |

Pressione `?` no aplicativo para ver a lista completa.

## Filtrando o fluxo

Pressione `/` em uma sessão e combine tokens separados por espaços, com AND. Texto simples
corresponde ao método, ferramenta, id e payload.

| Token | Filtra por | Exemplo |
|---|---|---|
| `tool:` | nome da ferramenta | `tool:search` |
| `method:` | método JSON-RPC | `method:tools/call` |
| `id:` | id da solicitação e qualquer nova tentativa que a continue | `id:7` |
| `task:` | id da tarefa | `task:01J...` |
| `dir:` | direção (`c2s`, `s2c`) | `dir:s2c` |
| `kind:` | tipo de quadro (`req`, `resp`, `notify`, `stderr`, `invalid`) | `kind:invalid` |
| `status:` | resultado da chamada (`ok`, `error`, `cancel`, `late`, `cancelled`, `pending`, `bad`, `warn`, `mismatch` ou um status HTTP como `401`) | `status:error` |

Empilhe tokens para obter algo específico.```text
tool:search status:pending        # in-flight calls to one search tool
status:cancel                     # calls the client gave up on (status:cancelled is a cancelled task)
status:late                       # results that arrived after the cancellation
method:tools/call status:error    # tool calls that failed
dir:s2c kind:req                  # server-initiated requests (servers before 2026-07-28)

O último só encontra algo num servidor que fala 2025-11-25 ou anterior. A revisão de 2026-07-28 removeu pedidos iniciados pelo servidor, e um servidor que precisa de algo do cliente agora responde ao próprio pedido do cliente pedindo isso, e então o cliente tenta novamente. O mcpsnoop liga essas novas tentativas ao pedido que elas continuam, para que a troca seja lida como uma única chamada em vez de várias.

Exportar sessões

Transforme qualquer sessão capturada num ficheiro portátil.```bash mcpsnoop export -T json|html|text|har|otlp [-o file|-] [session-id|log.jsonl|-]

root@kitploit:~
| Formato | O que você obtém |
|---|---|
| `json` | chamadas correlacionadas, contagens por ferramenta e latência p50/p95/p99, chamadas mais lentas, capacidades e quadros brutos |
| `html` | um arquivo de navegador autônomo com pesquisa e JSON recolhível |
| `text` | um despejo de texto simples e legível |
| `har` | uma entrada por chamada correlacionada, aberta no devtools do navegador e em qualquer outra coisa que leia HAR |
| `otlp` | JSON OTLP com um span por chamada correlacionada, com contexto de rastreamento W3C unindo os rastreamentos do chamador onde estiver presente e um rastreamento por sessão caso contrário |

MCP não é HTTP, então a URL, o código de status e os tempos de uma entrada HAR são um
mapeamento deliberado de cada chamada, e não uma transcrição de rede.

Para OTLP, o `_meta.traceparent` de uma solicitação fornece o rastreamento e os IDs de span pai
dessa chamada, e `_meta.tracestate` acompanha o span. Quando o traceparent está
ausente ou inválido, o mcpsnoop mantém o rastreamento derivado da sessão e não carrega estado.
O mcpsnoop observa em vez de participar, então não adiciona entrada de fornecedor própria
e repassa o estado do chamador inalterado.```bash
mcpsnoop export -T html -o out.html                    # an HTML file to open in a browser
mcpsnoop export -T text server.py-48213-7f3a1c9e2b04   # a specific session, as text
mcpsnoop export -T json | jq                           # the newest session, piped to jq
mcpsnoop export -T har -o session.har                  # a HAR file to open in browser devtools
mcpsnoop export -T otlp -o trace.json                  # import into an OTLP-compatible tracing backend

Omita -o para escrever na saída padrão (stdout) e omita a sessão para usar a mais recente, ou passe - para ler JSONL da entrada padrão (stdin). Na TUI, pressione e para exportar a sessão selecionada como HTML, ou execute :export json|html|text|har|otlp [caminho] a partir do modo de comando.

Redação

Para limpar uma captura existente antes de inspecioná-la ou compartilhá-la, passe os mesmos sinalizadores de redação usados durante a captura para export ou open:```bash mcpsnoop export session.jsonl --redact-secrets --redact-key project_token -o shared.json mcpsnoop open session.jsonl --redact-path '$.params.arguments.password'

root@kitploit:~
Estas flags reescrevem o arquivo exportado ou a visão TUI em memória, nunca o
JSONL de origem. `export` recusa uma saída que nomeie o mesmo arquivo que sua
entrada e grava por meio de um arquivo temporário que é renomeado no lugar, de
modo que uma execução que falhe deixa o arquivo anterior intacto.

O `inputSchema` e o `outputSchema` de uma ferramenta, conforme anunciados em um
resultado de `tools/list`, são deixados intactos por `--redact-key` e
`--redact-secrets`, por três motivos.

- Um nome dentro de um schema é uma declaração de tipo, não um valor.
- O nome em si permanece no log de qualquer forma.
- Limpar o subschema sob uma propriedade chamada `token` levaria junto as
  próprias verificações da ferramenta.

A isenção vale apenas para essa posição, de modo que um argumento que por acaso
se chame `inputSchema` é limpo como qualquer outro, e ela para em `default`,
`const`, `examples` e `enum`, que contêm dados em vez de estrutura. Use
`--redact-path` para nomear algo dentro de um schema, ou `--redact-value`, que
corresponde a texto onde quer que esteja, exceto nas duas palavras-chave que o
mcpsnoop analisa, `type` e `x-mcp-header`.

O alcance de cada flag difere, então verifique o resultado em vez de presumir.
Todas as quatro limpam payloads JSON-RPC, e `--redact-key`, `--redact-path` e
`--redact-secrets` alcançam apenas esses. Somente `--redact-value` também limpa
stderr, outro texto não JSON e o interior de uma string. Um cabeçalho
`Mcp-Param-*` é limpo junto com o valor do corpo que ele espelha. Os demais
metadados do envelope, rótulos do servidor, `Mcp-Name`, `Mcp-Method` e o status
HTTP, são deixados como capturados. A redação é de melhor esforço, então use um
caminho de saída separado e leia o resultado antes de compartilhá-lo.

### Transmitir chamadas concluídas para um coletor OTLP

Envie spans enquanto o proxy está em execução apontando-o para um endpoint de
traces OTLP/HTTP JSON. Repita `--otlp-header` para autenticação do coletor ou
cabeçalhos de tenant.```bash
mcpsnoop \
  --otlp-endpoint http://localhost:4318/v1/traces \
  --otlp-header "Authorization=Bearer $OTLP_TOKEN" \
  -- node build/index.js

mcpsnoop http \
  --target http://localhost:3000/mcp \
  --otlp-endpoint http://localhost:4318/v1/traces

A entrega é de melhor esforço e nunca bloqueia o tráfego MCP com proxy. Se o coletor estiver indisponível, o mcpsnoop tenta novamente em segundo plano e descarta novos quadros de rastreamento quando sua fila limitada estiver cheia. O registro normal de sessão em JSONL permanece como o registro durável.

Comparando sessões

Compare duas sessões salvas por id ou caminho JSONL.```bash mcpsnoop diff before-session after-session mcpsnoop diff old.jsonl new.jsonl

root@kitploit:~
O relatório mostra ferramentas que foram adicionadas ou removidas, alterações na descrição e no `inputSchema`,
chamadas de ferramentas correspondentes cujo status mudou e mudanças notáveis de duração. As chamadas
são correspondidas pelo nome da ferramenta e pelos argumentos, portanto chamadas reordenadas ainda são comparadas corretamente.
Por padrão, as mudanças de duração devem diferir em pelo menos 100 ms e 2x. Use
`--duration-threshold` e `--duration-ratio` para ajustar esses limites.

Passe `--exit-code` para controlar a CI quanto a regressões. Ele sai com código não zero quando a sessão
"after":

- remove uma ferramenta
- altera a descrição, o título, o schema de entrada, o schema de saída ou as anotações de uma ferramenta
- tem uma chamada cujo status piorou
- fica mais lenta

Uma mudança de ícone não conta, pois altera a aparência de uma ferramenta sem mudar o que ela
faz. Melhorias, ou seja, ferramentas adicionadas, chamadas corrigidas e acelerações, ainda saem
com código zero.

## Verificando sessões na CI

Controle uma execução de agente gravada quanto a erros, corrupção de stream, avisos de protocolo,
incompatibilidades de cabeçalho de roteamento, chamadas que nunca receberam resposta, quadros descartados que
deixam a captura incompleta, desvio de definição de ferramenta ou uso de recursos de protocolo
obsoletos.```bash
mcpsnoop check [--format text|junit|sarif] [--fail-on error,invalid,warn,mismatch,pending,late-result,drift,deprecated,incomplete,schema] [session-id|log.jsonl|-]

error, invalid e warn falham na verificação por conta própria. As demais são opcionais. Passe um subconjunto separado por vírgulas para limitar apenas ao que um trabalho se importa, omita a sessão para verificar a captura mais recente, ou use - para ler JSONL da entrada padrão.

SinalFalha em
erroruma chamada respondida com um erro JSON-RPC, um resultado marcado como isError, ou uma tarefa que terminou em falha
invalidum frame no canal de protocolo que não é JSON-RPC válido, geralmente um servidor registrando logs no stdout
warnum frame que quebra uma expectativa definida pela especificação MCP ou JSON-RPC
mismatchum cabeçalho de roteamento em desacordo com o corpo, montado em um lote, ou ausente onde a revisão o exige
pendinguma solicitação ainda aberta quando a captura terminou, deixando o chamador esperando
late-resultuma resposta que chegou depois que sua solicitação foi cancelada
driftuma definição de ferramenta anunciada que muda após a linha de base ser aprovada
deprecatedum recurso que a especificação descontinuou
incompleteframes descartados a montante, o que torna cada outra contagem um piso em vez de um total
schemaum schema anunciado usando uma construção ou um dialeto que se propaga mal entre clientes

Cada sinal é contado independentemente de estar ou não limitando a falha, então uma execução informa o que encontrou antes que você decida o que deve falhar nela.``` session build-agent: errors=1 invalid=0 warnings=0 mismatches=0 pending=0 late_results=0 deprecated=0 missing_frames=0 schema_findings=1 schema findings: oneOf: search check failed: error

root@kitploit:~
O contagem de quadros perdidos também viaja com os artefatos, então uma captura que
subestima a si mesma informa isso onde quer que seja aberta:

- `missing_frames` na exportação JSON
- `log.comment` no HAR
- o atributo de recurso `mcpsnoop.session.missing_frames` no OTLP```bash
mcpsnoop check build-agent
mcpsnoop check --fail-on error,invalid artifacts/session.jsonl
mcpsnoop check --fail-on mismatch gateway-run.jsonl

O código de saída indica qual das duas situações ocorreu, e um wrapper de CI precisa dessa diferença. 1 significa que a verificação foi executada e algo falhou no portão, portanto as descobertas são reais e valem a pena ser publicadas. 2 significa que a verificação nunca aconteceu: um caminho que não existe, um arquivo que não é um log de sessão, um diretório de estado sem conteúdo, uma flag que não faz parsing. Nada é escrito no stdout em um 2, portanto um pipeline nunca envia um relatório vazio como se fosse um veredito.

Afirme o que deve e o que não deve acontecer

Além das contagens de sinais, afirme a forma da execução. Elas se combinam entre si e com --fail-on, e qualquer falha sai com 1, o código que significa que a verificação foi executada e encontrou algo.

FlagFalha quando
--max-duration <dur>uma ou mais chamadas de ferramenta concluídas excederam o orçamento, reportando sua contagem e a pior chamada
--expect-tool <name>a ferramenta nomeada nunca foi chamada (repetível)
--forbid-tool <name>a ferramenta nomeada foi chamada (repetível)

a contract for the run: search must run, delete must not, nothing over 2s

mcpsnoop check --expect-tool search --forbid-tool delete --max-duration 2s run.jsonl

root@kitploit:~
### Reporte onde a CI já procura

`--format junit` escreve um `<testcase>` por sinal e sessão, e suas falhas
seguem a mesma seleção de `--fail-on` que a saída de texto.```yaml
- name: Check captured MCP session
  run: |
    mkdir -p test-results
    mcpsnoop check --format junit artifacts/session.jsonl > test-results/mcpsnoop.xml
- name: Upload mcpsnoop JUnit report
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: mcpsnoop-junit
    path: test-results/mcpsnoop.xml

--format sarif grava um log SARIF 2.1.0 em vez disso. Enquanto o junit reporta um agregado por sinal, o SARIF reporta um resultado por descoberta, carregando a sessão, o Seq do frame e o próprio texto de aviso ou deriva do frame, e apontando para a linha do log da qual o frame foi decodificado. Um sinal nomeado em --fail-on é reportado no nível error e um fora dele no nível note, para que o relatório e a porta nunca discordem.

Um resultado aponta para o log de onde a descoberta veio, e como depende de onde o log foi lido.

  • Um caminho dentro do diretório de trabalho torna-se relativo, o que o code scanning resolve em relação à raiz do repositório.
  • Um caminho em outro lugar no disco, ou um id de sessão resolvido a partir do diretório de estado, torna-se um URI absoluto file://.
  • Ler de stdin dá a um resultado nenhuma localização, já que não há arquivo para apontar.

O alerta é renderizado com suas linhas circundantes apenas quando esse caminho é um arquivo no commit analisado, então uma captura que o workflow gerou em artifacts/ abre um alerta carregando a mensagem, a regra e o número da linha, mas sem visualização da fonte. Confirmar uma captura que você quer renderizada por completo é a única maneira de obter uma.

O code scanning rejeita um arquivo cuja execução contenha mais de 25.000 resultados e exibe apenas os 5.000 principais do que aceita, então o relatório é limitado a 5.000: as descobertas nas quais a porta falhou primeiro, depois um resultado mcpsnoop/report-truncated dizendo quantas foram deixadas de fora. Os formatos de texto e junit permanecem completos.

A GitHub Action

Tudo abaixo é o que a ação faz por você. Ela instala o mcpsnoop, verifica a captura, arquiva as descobertas na aba Security e falha o job no que você definiu na porta.```yaml permissions: security-events: write contents: read

steps:

  • uses: kerlenton/[email protected] with: session: artifacts/session.jsonl
root@kitploit:~
Fixar uma release, a que você quiser. A mais recente está na
[página de releases](https://github.com/kerlenton/mcpsnoop/releases). Não existe
um `v1` flutuante, de propósito. A release fixada também é o binário que a action
instala, então os dois nunca podem divergir e não há um padrão de versão que fique
obsoleto.

| Input | |
|---|---|
| `session` | a captura `.jsonl` a verificar, relativa à raiz do repositório. Obrigatório |
| `fail-on` | como `--fail-on`, com padrão igual ao padrão da CLI |
| `args` | quaisquer outras flags de `check`, entre aspas como numa linha de comando. `--format` é recusado, pois a action lê o relatório |
| `upload-sarif` | envia o relatório para code scanning. `true` |
| `category` | o namespace do code scanning. `mcpsnoop`. Varie-o por perna de uma matrix, ou as pernas se sobrescrevem |
| `fail-on-findings` | falha o job numa finding. `true`. Defina `false` para arquivar os alertas e deixar a verificação obrigatória do code scanning decidir |
| `version` | qual mcpsnoop instalar. Padrão: a release que você fixou |
| `install` | `false` quando o mcpsnoop já está no PATH, que é o caminho numa plataforma para a qual nenhuma release foi compilada |

As saídas são `outcome`, `sarif` e `exit-code`. `outcome` é `passed`,
`findings` ou `error`, e a terceira vale a pena tratar separadamente. Significa
que nada foi verificado, o que não é o mesmo que nada ter sido encontrado. **Uma
execução que não conseguiu verificar falha o job, independentemente do que
`fail-on-findings` disser**, porque um pipeline que fica verde tendo verificado
nada é pior do que um que falha.

O job precisa de `security-events: write`, ou o upload responde 403. Defina
`upload-sarif: false` num repositório sem code scanning.

### Ou conecte você mesmo

A action são quatro passos e nenhuma mágica. Fazer manualmente exige o mesmo
cuidado que ela exige. O upload tem de rodar nas execuções que têm um relatório,
que são as que saíram com 0 ou 1 e não as que saíram com 2, e o passo que falha o
job tem de vir depois dele, ou as findings nunca chegam à aba para a qual existem.```yaml
permissions:
  # required for all workflows
  security-events: write
  # only required for workflows in private repositories
  actions: read
  contents: read

steps:
- name: Check captured MCP session
  id: check
  run: |
    code=0
    mcpsnoop check --format sarif artifacts/session.jsonl > mcpsnoop.sarif || code=$?
    echo "exit-code=$code" >> "$GITHUB_OUTPUT"
    # 2 means the check never happened, so there is no report to publish and
    # nothing was verified. Stop here rather than uploading an empty file.
    [ "$code" -le 1 ] || exit 1
- name: Upload mcpsnoop SARIF report
  if: ${{ !cancelled() }}
  uses: github/codeql-action/upload-sarif@v4
  with:
    sarif_file: mcpsnoop.sarif
    category: mcpsnoop
- name: Fail on findings
  # Separate, and after the upload, so the findings reach the Security tab on
  # exactly the runs that have some.
  if: ${{ !cancelled() && steps.check.outputs.exit-code == '1' }}
  run: exit 1

Capturar um cabeçalho de roteamento que discorda do corpo

No transporte HTTP streamable, um gateway roteia com base em Mcp-Method e Mcp-Name enquanto o servidor lê o corpo, portanto um cabeçalho que discorda do corpo significa que os dois estão olhando para duas requisições diferentes. O sinal mismatch cobre isso, um cabeçalho que viaja em um lote que não consegue endereçar, e um cabeçalho obrigatório ausente por completo.

Em 2026-07-28, um cabeçalho de roteamento ausente é uma falha de validação, e um servidor em conformidade rejeita a requisição com 400 e -32020. O mcpsnoop o levanta apenas quando se sabe que a sessão fala essa revisão ou posterior, já que revisões anteriores não definem esses cabeçalhos e omiti-los ali é correto. A rejeição -32020 do próprio servidor conta como o mesmo sinal.

Um nome ou URI de recurso que não cabe em um valor de campo HTTP viaja em Base64 em um sentinela =?base64?…?=, que é decodificado antes da comparação, portanto um cliente que codifica corretamente nunca é sinalizado.

Em requisições HTTP tools/call, o mcpsnoop também mostra cada cabeçalho Mcp-Param-{Name} e, quando a definição de ferramenta anunciada correspondente é conhecida, compara-o com o caminho de argumento anotado. Propriedades aninhadas, o sentinela Base64, booleanos e inteiros seguros numericamente equivalentes são tratados sem falsos positivos de comparação de strings. Cabeçalhos de parâmetro desconhecidos e sessões sem uma definição de ferramenta correspondente permanecem observacionais. A redação baseada em chave e valor se aplica aos valores de cabeçalho de parâmetro capturados antes de chegarem a um destino, e um valor que o próprio mcpsnoop removeu nunca é relatado como uma discordância.

Verificar os cabeçalhos de transporte que a especificação torna obrigatórios

Os cabeçalhos de roteamento acima eram os únicos que um quadro carregava, portanto o restante dos cabeçalhos obrigatórios do transporte HTTP Streamable não alcançava nada que pudesse verificá-los. Content-Type era o caso mais crítico. O lado da resposta já o lia para distinguir um stream SSE de um corpo JSON e depois o descartava.

Um quadro HTTP agora carrega os cabeçalhos sobre os quais o transporte estabelece regras, e duas dessas regras são verificáveis.

RegraRelatado como
o cliente DEVE enviar um Accept listando tanto application/json quanto text/event-streamwarn na requisição
um servidor que responde a uma requisição JSON-RPC DEVE retornar Content-Type: application/json ou text/event-streamwarn na resposta

Ambas as frases dizem o mesmo em 2025-11-25 e 2026-07-28, portanto, ao contrário das verificações de deriva e extensão, estas não precisam de portão de revisão. Origin também é registrado, já que servidores DEVEM validá-lo e DEVEM responder com 403 quando for inválido, mas o mcpsnoop não pode saber suas origens permitidas, então mostra o valor em vez de julgá-lo.

Curingas contam. Um cliente que envia */* ofereceu ambos os tipos e nunca é relatado, e um parâmetro charset em um Content-Type é ignorado. Um log capturado antes de o mcpsnoop registrar esses cabeçalhos permanece silencioso em vez de relatar cada quadro nele por um cabeçalho que ninguém anotou, e stdio nunca os tem.

Authorization é deliberadamente não capturado. Transformar um desafio em fatos de token é um problema próprio, e colocar um token bearer em disco não é a resposta para ele. Mcp-Session-Id e Last-Event-ID também não são capturados. A revisão 2026-07-28 removeu ambos e diz ao servidor para ignorá-los, portanto não resta nenhuma regra para verificar.

Detectar deriva na definição de ferramentas

O primeiro tools/list completo observado para um rótulo de servidor torna-se sua linha de base confiável. Sessões posteriores comparam essa linha de base campo por campo:

  • a descrição
  • o título
  • os esquemas de entrada e saída
  • as anotações e os ícones

Ferramentas que foram adicionadas ou removidas também são comparadas, o que é uma comparação de conjunto em vez de uma de campo.

As anotações importam mais, já que uma ferramenta aprovada com readOnlyHint que depois se declara destrutiva é a puxada de tapete para a qual esta verificação existe, e a especificação diz aos clientes para tratar anotações como não confiáveis. O título e os ícones são rastreados porque são o que o usuário vê, e a especificação classifica o title de uma ferramenta acima de annotations.title e de seu nome. A tabela de sessões e o resumo de ferramentas sinalizam deriva sem bloquear ou alterar o tráfego MCP.

As anotações são comparadas por meio de seus padrões de especificação, portanto um servidor que começa a explicitar uma dica na qual já confiava não é relatado. Uma linha de base registrada antes de o mcpsnoop rastrear um campo continua funcionando para os campos que registra e diz quais não consegue responder. Regrave com mcpsnoop baseline --accept quando confiar nas definições atuais.

Alterar o que a redação registra altera o que a deriva compara. Uma linha de base obtida sem --redact-value e depois verificada contra uma captura obtida com ele relata os campos removidos como alterados, o que é correto, já que a definição registrada realmente mudou. Regrave com --accept após alterar as configurações de redação.

Use um --label estável e único para cada servidor cujo nome de comando ou host de destino colidiria de outra forma. As linhas de base são armazenadas no diretório de estado normal do mcpsnoop, portanto MCPSNOOP_HOME e XDG_STATE_HOME se aplicam.```bash mcpsnoop check --fail-on drift session.jsonl mcpsnoop baseline session.jsonl mcpsnoop baseline --accept session.jsonl # trust a legitimate definition change mcpsnoop baseline --reset session.jsonl # trust the next complete tools/list

root@kitploit:~
Em CI efêmero, o diretório de estado começa vazio, então uma execução não tem nada com que
comparar e registra a linha de base em vez de verificá-la. **Uma execução que
pediu para falhar em caso de drift e depois não verificou nada não passa**, e indica qual
diretório persistir. Esse é o único caso em que registrar uma linha de base é uma
falha. Sem `drift` em `--fail-on`, registrar uma é o fluxo normal e
não altera nenhum código de saída.

Portanto, a linha de base precisa sobreviver entre execuções para que uma verificação de drift signifique algo.
Aponte `--baseline` para um diretório versionado ou em cache, ou defina `MCPSNOOP_HOME` para
um caminho persistido.```
recorded first-seen tool baseline (trusted, not verified)
check failed: drift

Aqui está a tradução do conteúdo do chunk 53:

root@kitploit:~
## Instalação

### Requisitos

- Python 3.8 ou superior
- pip (gerenciador de pacotes do Python)
- Acesso à internet para baixar dependências

### Passos de Instalação

1. Clone o repositório:
   ```bash
   git clone https://github.com/exemplo/ferramenta-seguranca.git
   cd ferramenta-seguranca
  1. (Opcional) Crie e ative um ambiente virtual:

    root@kitploit:~
    python3 -m venv venv
    source venv/bin/activate  # No Windows: venv\Scripts\activate
    
  2. Instale as dependências necessárias:

    root@kitploit:~
    pip install -r requirements.txt
    
  3. Verifique se a instalação foi concluída com sucesso:

    root@kitploit:~
    python ferramenta.py --help
    

Uso

Comandos Básicos

Para executar a ferramenta com as opções padrão:

root@kitploit:~
python ferramenta.py -t https://exemplo-alvo.com

Para uma varredura mais detalhada com saída verbosa:

root@kitploit:~
python ferramenta.py -t https://exemplo-alvo.com -v --saida relatorio.json

Opções da Linha de Comando

OpçãoDescrição
-t, --alvoURL ou endereço IP do alvo (obrigatório)
-p, --portasPortas a serem verificadas (padrão: 80, 443, 8080)
-v, --verbosoHabilita a saída detalhada
-o, --saidaArquivo de saída para salvar os resultados
--sem-corDesativa a saída colorida no terminal
-h, --helpMostra a mensagem de ajuda e sai

Exemplos

Exemplo 1: Varredura básica de portas

root@kitploit:~
python ferramenta.py -t 192.168.1.1 -p 22,80,443

Exemplo 2: Varredura com detecção de serviços

root@kitploit:~
python ferramenta.py -t scanme.exemplo.org --detectar-servicos

Exemplo 3: Salvar resultados em um arquivo

root@kitploit:~
python ferramenta.py -t https://exemplo-alvo.com -o resultados.txt

Configuração

A ferramenta pode ser configurada usando um arquivo de configuração YAML localizado em ~/.config/ferramenta/config.yaml. Se o arquivo não existir, os valores padrão serão usados.

root@kitploit:~
# Exemplo de arquivo de configuração
alvo:
  timeout: 30
  user_agent: "FerramentaSeguranca/1.0"

varredura:
  threads: 10
  retries: 3

relatorio:
  formato: "json"
  nivel_detalhe: "alto"

Solução de Problemas

Erro: "Permissão negada" ao executar

Se você encontrar um erro de permissão, tente executar com sudo (no Linux/macOS) ou certifique-se de que seu usuário tenha as permissões necessárias:

root@kitploit:~
sudo python ferramenta.py -t https://exemplo-alvo.com

Erro: "Módulo não encontrado"

Se o Python não conseguir encontrar um módulo, certifique-se de que todas as dependências foram instaladas corretamente:

root@kitploit:~
pip install -r requirements.txt --upgrade

Problemas de conectividade

Se a ferramenta não conseguir se conectar ao alvo, verifique sua conexão de rede e as configurações de firewall. Você também pode aumentar o tempo limite usando a opção --timeout:

root@kitploit:~
python ferramenta.py -t https://exemplo-alvo.com --timeout 60

Perguntas Frequentes (FAQ)

P: A ferramenta é legal de usar?

R: Esta ferramenta é destinada apenas para fins educacionais e testes de penetração autorizados. Sempre obtenha permissão por escrito do proprietário do sistema antes de executar qualquer varredura.

P: Posso usar esta ferramenta em sistemas Windows?

R: Sim, a ferramenta é multiplataforma e funciona em Windows, Linux e macOS, desde que o Python 3.8 ou superior esteja instalado.

P: Como posso contribuir com o projeto?

R: Sinta-se à vontade para abrir issues ou enviar pull requests no repositório do GitHub. Certifique-se de seguir as diretrizes de contribuição descritas no arquivo CONTRIBUTING.md.

Licença

Este projeto está licenciado sob a Licença MIT - consulte o arquivo LICENSE para obter detalhes.

Aviso Legal

Esta ferramenta é fornecida apenas para fins educacionais e de pesquisa. O uso indevido desta ferramenta para atacar sistemas sem autorização prévia é ilegal e antiético. O autor não se responsabiliza por qualquer uso indevido ou dano causado por esta ferramenta. Use por sua conta e risco.

root@kitploit:~
mcpsnoop check --fail-on drift --baseline .mcpsnoop/baselines session.jsonl
```
`drift` é opcional para `check`. O gate padrão `error,invalid,warn` permanece inalterado.

### Capturar um recurso que nenhum dos lados negociou

SEP-2133 moveu recursos opcionais para fora do protocolo principal e para extensões,
anunciadas no mapa `extensions` das capacidades de cada lado. Tasks é um deles,
então em 2026-07-28 um `tasks/get`, um `notifications/tasks` ou um `tools/call`
respondido com um handle de task só significa algo quando o outro lado disse que
fala Tasks.

Quando não falou, a especificação é explícita: a parte que suporta DEVE ou recuar
para o comportamento principal ou rejeitar a solicitação. Fazer mesmo assim é por que
um recurso parece estar conectado e depois silenciosamente não faz nada, e o que um
leitor recebe em vez disso é um `-32601` ou um `-32021` vários frames depois, ou uma task que nunca
progride. mcpsnoop avisa no frame que alcançou a extensão e nomeia
qual lado nunca a anunciou.```
tool "slow" answered with a task handle uses the io.modelcontextprotocol/tasks
extension, which the client never advertised
```
É um `warn`, portanto uma execução padrão de `check` falha nele. Ele permanece silencioso sempre que a captura não consegue mostrar o que foi negociado, o que é uma captura que começa após o handshake ou uma cujas capacidades foram removidas pela sua própria redação, e em revisões anteriores a 2026-07-28, onde `tasks/*` são protocolo central e usá-los é correto.

### Sinalizar recursos de protocolo obsoletos

A revisão de 2026-07-28 desaprova Roots, Sampling e Logging. Eles continuam funcionando por pelo menos um ano, então o mcpsnoop os marca em vez de tratá-los como erros. O fluxo, o inspetor de capacidades e a exportação sinalizam todos eles, e cada marcador nomeia a substituição.

Dois dos três agora são acessíveis apenas por meio de uma solicitação de múltiplas idas e voltas, onde o nome do método fica dentro do mapa `inputRequests` do servidor, em vez de no próprio quadro. Esses também são sinalizados, para que um servidor que migrou para o novo padrão não pare silenciosamente de reportar.```bash
mcpsnoop check --fail-on deprecated session.jsonl
```
Como `drift`, `deprecated` é opt-in. Uma execução padrão reporta a contagem e permanece
verde, então uma sessão que usa um recurso obsoleto ainda legal nunca deixa o CI vermelho por
conta própria.

### Construções de esquema de flag que os clientes lidam mal

Um servidor pode ser perfeitamente válido e ainda assim ser difícil para um agente usar. Os clientes
diferem em quanto do JSON Schema realmente suportam, e uma ferramenta que o modelo fica
chamando incorretamente costuma ser uma ferramenta cujo esquema pediu mais do que o cliente
entrega.

O resumo de ferramentas, aberto com `s`, tem uma coluna SCHEMA nomeando o aspecto mais
notável do esquema de cada ferramenta anunciada, com um `+` ao final quando há mais
de um tipo.

| Mostrado | Significado |
|---|---|
| `no root` | o `inputSchema` está ausente, não é um objeto JSON, ou tem um tipo raiz diferente de `"object"` |
| `dialect` | um `$schema` nomeando um dialeto diferente do 2020-12 que a revisão usa por padrão |
| `ext ref` | um `$ref` apontando para fora do documento, que também é o caso em que a especificação avisa os implementadores a não seguir cegamente |
| `oneOf`, `anyOf`, `allOf`, `not` | uma palavra-chave de composição, tratada de forma inconsistente entre os clientes |
| `ref` | um `$ref` apontando para dentro do mesmo documento |
| `untyped` | uma propriedade que não declara tipo nem outra forma de dizer o que aceita |

Todas, exceto a primeira, são observações em vez de veredictos. Um esquema usando `oneOf`
não está errado, apenas provavelmente será lido de forma diferente por clientes diferentes, e um
esquema pode declarar o dialeto que quiser. `no root` é a exceção: a
definição de `Tool` exige `inputSchema` e fixa seu tipo raiz em `"object"`, então
um cliente que valida uma listagem rejeita essa ferramenta por completo e ela nunca se torna
chamável, sem nada no fio para explicar o porquê. `no root` lidera a coluna por
esse motivo, e um esquema que a própria redação do mcpsnoop removeu nunca é reportado,
já que um esquema ilegível não é um esquema errado.

Essa divisão decide o que `check` faz com eles. `no root` é um aviso no
frame `tools/list`, então falha o gate padrão `error,invalid,warn` sem
nenhuma flag, que é o ponto: um servidor que envia uma ferramenta inutilizável responde
normalmente a cada handshake e simplesmente nunca recebe um `tools/call`. As
observações são contadas como `schema_findings` e reportadas sob `schema
findings:`, e só falham a execução quando você adiciona `schema` a `--fail-on`. Ambas
chegam a `--format junit` e `--format sarif`, e `export` carrega a lista
por ferramenta sob `summary.definitions.per_tool[].findings`.```bash
mcpsnoop check session.jsonl                     # a non-object root already fails this
mcpsnoop check --fail-on schema session.jsonl    # and now so do the observations
```
A coluna carrega a cor de aviso e nunca o vermelho da coluna ERR, e o
mcpsnoop ainda não altera nada sobre o tráfego que encaminha.

Nada é resolvido ou buscado. Um `$ref` externo é reconhecido pela sua forma
sozinha, e o schema para o qual ele aponta nunca é lido.

### Reproduzir uma chamada capturada via HTTP

`r` re-emite uma chamada capturada contra um servidor ativo. Para uma captura
stdio, o comando está no log, então o mcpsnoop lança uma cópia isolada e envia a
solicitação para ela. Uma captura HTTP não tem comando para lançar, e o endpoint
que ela registra é despojado do seu userinfo e de cada valor de query, então ele
nomeia o servidor sem ser um endereço para discar.

Então você diz para onde uma reprodução vai, e o mcpsnoop nunca disca um endpoint
de produção porque alguém pressionou uma tecla.```bash
mcpsnoop open --replay-target https://api.example.com/mcp session.jsonl
mcpsnoop open --replay-target https://api.example.com/mcp \
  --replay-header 'Authorization: Bearer sk-…' session.jsonl
```
Sem `--replay-target`, uma sessão HTTP diz isso em vez de oferecer uma chave que
não pode funcionar. Com uma, `r` ainda pergunta antes do primeiro envio de uma sessão,
da mesma forma que um comando gravado é respondido antes de ser executado.

Uma credencial chega ao servidor através de `--replay-header` e de nenhum outro lugar.
O mcpsnoop não grava nenhum cabeçalho `Authorization` e não reproduz nenhum, portanto
não há nada capturado que uma reprodução possa vazar.

O POST reproduzido carrega o que o transporte torna obrigatório, o que um POST do
corpo capturado puro não faz: `MCP-Protocol-Version`, um `Accept` listando tanto
`application/json` quanto `text/event-stream`, `Mcp-Method`, `Mcp-Name` onde a
especificação o exige, e cada `Mcp-Param-*` capturado. Esses são reenviados verbatim
a partir da captura, sentinela base64 e tudo, portanto não podem discordar do corpo
da forma como uma re-derivação poderia. O único cabeçalho que não é copiado é a versão
do protocolo, porque o corpo reproduzido declara a revisão que o mcpsnoop fala e o
cabeçalho tem que corresponder ao corpo.

`Mcp-Name` é derivado do corpo que está sendo enviado em vez de copiado, porque a
especificação o origina de `params.name` ou `params.uri` e exige que um servidor
rejeite um cabeçalho que discorde do corpo, então uma edição que renomeie a ferramenta
enviaria de outra forma o nome antigo. Os cabeçalhos `Mcp-Param-*` espelham os
argumentos capturados, então uma reprodução editada não envia nenhum deles em vez de
afirmar algo sobre um corpo que alguém reescreveu. Uma captura só pode definir
cabeçalhos nessa única família. Um log é um arquivo que as pessoas compartilham, e
deixá-lo nomear qualquer cabeçalho permitiria que ele sobrescrevesse os obrigatórios
ou adicionasse uma credencial que ninguém passou.

Um `Mcp-Param-*` que uma regra de redação limpou interrompe a reprodução com um motivo.
Enviar o espaço reservado colocaria os próprios bytes do mcpsnoop em um servidor ativo
como se um usuário os tivesse digitado.

Um redirecionamento é recusado em vez de seguido. O endereço é aquele que você nomeou e
pelo qual respondeu, e seguir um 307 entregaria essa escolha à outra ponta, reenviando
o corpo e, em um salto que apenas muda a porta, a credencial também. O mcpsnoop
informa para onde o servidor queria enviá-lo e deixa você decidir se quer nomear
aquele em vez disso.

Uma resposta que chega como um único objeto JSON e uma que chega como um fluxo de
eventos são ambas lidas, e uma falha é nomeada em vez de numerada:

- um 401 informa o esquema que o servidor exigiu
- um `-32020` informa ao que ele se opôs
- um 400 ou 404 não-JSON-RPC diz que o endereço não é um endpoint HTTP Streamable
  desta revisão

### Distinguir a latência do servidor da do usuário

Em requisições de múltiplas idas e voltas, uma chamada de ferramenta são várias
requisições, e os segundos que uma pessoa gastou respondendo a uma elicitação ficam
dentro do intervalo. Isso é deliberado, já que esse intervalo geralmente é o que você
mais quer ver, mas significa que um único número não pode responder a ambas as
perguntas.

Em uma cadeia `book_flight` onde o servidor trabalhou 1,2 segundos enquanto o usuário
levou 37, `check --max-duration 5s` culpa a ferramenta por 38,2 segundos. Ele ainda
culpa, porque mudar o que essa flag significa afrouxaria todos os pipelines que já a
definem. Dois irmãos nomeiam o que medem em vez disso.```bash
mcpsnoop check --max-server-duration 1s session.jsonl   # the server's share alone
mcpsnoop check --max-round-trips 2 session.jsonl        # how chatty a tool is
```
```
# Instalação

## Requisitos

- Python 3.8 ou superior
- pip
- Git

## Instalação via pip

```bash
pip install kitploit
```

## Instalação a partir do código-fonte

```bash
git clone https://github.com/kitploit/kitploit.git
cd kitploit
pip install -r requirements.txt
python setup.py install
```

## Verificação da instalação

Para verificar se a instalação foi concluída com sucesso, execute:

```bash
kitploit --version
```

Se a instalação estiver correta, você verá o número da versão exibido no terminal.

## Solução de problemas

### Erro: `pip: comando não encontrado`

Certifique-se de que o Python e o pip estejam instalados e adicionados ao seu PATH. Você pode verificar com:

```bash
python --version
pip --version
```

### Erro: `PermissionError` durante a instalação

Tente usar `pip install --user` ou execute o comando com `sudo` (não recomendado em ambientes virtuais).

### Erro: dependências ausentes

Execute `pip install -r requirements.txt` novamente para garantir que todas as dependências estejam instaladas.

assertion failed: 1 tool call exceeded the 1s server budget (worst: tool "book_flight" held for 1.2s) assertion failed: 1 tool call exceeded the 2 round trip budget (worst: tool "book_flight" took 3)

root@kitploit:~
Ambos estão desativados por padrão, portanto uma execução padrão de `check` não é afetada, e ambos são
lidos a partir dos timestamps dos frames e de um link que o mcpsnoop já inferiu, então nenhum
adivinha intenções.

Pressione `i` na TUI para ver o detalhamento, ou leia `interactions` nas exportações
json, text e html. Cada entrada é uma operação lógica com sua contagem de idas e voltas,
seu total, a parcela que o servidor a manteve e a parcela em que ela esperou
pelo cliente, além de uma linha por salto nomeando o que cada resposta solicitou. O
resumo por ferramenta ganha uma coluna `TRIPS` para que uma ferramenta prolixa seja visível sem
abrir nada.

`export --format har` coloca a parcela do servidor em `wait` e o restante em
`blocked`, que é para isso que esse campo serve, então um visualizador para de desenhar uma espera de servidor
de 38 segundos que nunca aconteceu.

As contagens e as duas parcelas são acumuladas conforme os frames chegam, em vez de
derivadas quando você pede, porque o armazenamento ativo libera frames antigos para permanecer dentro de seu
orçamento, e uma resposta derivada seria silenciosamente uma janela em vez de uma cadeia.
O detalhamento por salto é lido dos frames ainda retidos e informa quando é
apenas parte de um. `ServerTime + ClientTurnaround` é igual ao total por
construção, e não por uma aritmética em que alguém precise confiar.

`--max-round-trips` julga uma cadeia que ainda está em execução, porque cada requisição
que ela já fez é contável, e um servidor que pergunta repetidamente produz
exatamente a operação que ninguém jamais termina. `--max-server-duration` espera por um
fim, que é a regra que `--max-duration` já aplica, já que uma operação
ainda aberta não tem latência para julgar.

Uma operação que o mcpsnoop não conseguiu vincular permanece como sua própria entrada de salto único. `matchRetry`
recusa um vínculo ambíguo de propósito, e esta visão não preenche essa lacuna.

Uma operação que levou uma requisição não carrega detalhamento de saltos, porque um único
salto reafirma os totais acima palavra por palavra. Uma cadeia relata um salto por
requisição e informa quando o armazenamento não retém mais todos os frames ou quando o trabalho
se resolveu fora do par requisição e resposta do qual um salto é feito, o que um handle de tarefa
faz.

### Veja o que um servidor pediu ao seu usuário

Elicitação é o único caminho no MCP em que uma pessoa digita dados em um servidor, e
sob o MRTR a pergunta e a resposta não são mais duas metades de uma única troca.
A pergunta está enterrada em um `InputRequiredResult`, a resposta volta dentro de
`inputResponses` em uma nova tentativa sob um id diferente, e a única coisa que as
une é o link que o mcpsnoop já infere.

Sem esse pareamento, uma solicitação de senha recusada é lida como um erro comum de ferramenta.```
tools/call login_legacy [form] creds: decline after 3s
  password string

Prima l na TUI, ou lê elicitations nas exportações json, text e html. Cada linha nomeia a operação que a pergunta interrompeu, o modo, a mensagem, o que foi pedido, o que o utilizador fez e quanto tempo demorou. Uma pergunta que nenhuma tentativa alguma vez respondeu aparece como pendente, o que o MRTR torna um resultado normal em vez de um erro, uma vez que a especificação diz aos servidores para não assumirem que um cliente vai tentar novamente de todo.

As linhas de formulário listam os nomes das propriedades requestedSchema e os seus tipos declarados. Uma propriedade cujo subschema uma regra de redação substituiu mostra um tipo desconhecido em vez do espaço reservado, porque um espaço reservado não é algo que o servidor declarou. As linhas de URL transportam o endereço completo, que a especificação manda o cliente mostrar antes do consentimento, e nomeiam o anfitrião por si só, que diz para destacar contra spoofing de subdomínio.

O ledger nunca transporta um valor submetido. O que o utilizador escreveu fica na captura para quem precisar dele, e deixá-lo fora de uma superfície de resumo construída para ser exportada e colada em todo o lado é o que mantém isto fora da história de redação por completo. Importa mais no modo url, onde a especificação coloca credenciais de propósito.

Uma tentativa responde à ronda de onde foi emitida e a nenhuma outra. O MRTR diz a um servidor que, quando um cliente omite parte do que foi pedido, deve perguntar novamente numa nova ronda, portanto uma ronda anterior que contém uma chave sem resposta ao lado de uma respondida é tráfego normal, e a metade sem resposta permanece pendente em vez de tomar emprestada a resposta da ronda posterior.

Uma pergunta registada é limitada. A mensagem, o url e a lista de campos são mantidos durante a vida da sessão, fora do orçamento de frames que liberta corpos, para que um servidor não possa tornar um arbitrariamente caro. Os limites estão muito acima de qualquer pergunta real e uma mensagem truncada diz que foi truncada.

Nada aqui avisa e nada aqui altera um código de saída check. Um ledger regista o que aconteceu. Não o julga.

Encontrar a ferramenta que falha uma em cada quatro execuções

check lê uma sessão e diff lê exatamente duas, portanto uma ferramenta que falha ocasionalmente permanece invisível até alguém abrir as capturas à mão. Ao longo de dezasseis capturas de um servidor cujo run_query responde isError cerca de um quarto das vezes, check reporta a mais recente, honestamente, como limpa.```bash mcpsnoop stats mcpsnoop stats --since 7d --label prod mcpsnoop stats --limit 20 --format json

root@kitploit:~
I'm ready to translate the Kitploit tool content from English to Portuguese. Please provide the chunk 71 of 89 content you'd like me to translate.```
read 16 logs of 16 in ~/.local/state/mcpsnoop/sessions

SERVER       TOOL          CALLS   ERR  PROTO    FAIL%       SESS       p50      p95      p99      DEF
flaky-demo   run_query        13     3      0    23.1%       3/13     434ms    519ms    519ms     195B
docs-mirror  run_query         3     1      0    33.3%        1/3     357ms    434ms    434ms     195B
docs-mirror  search_docs      12     0      0     0.0%        0/3     377ms    386ms    386ms     200B
flaky-demo   search_docs      52     0      0     0.0%       0/13      42ms     58ms      59ms    200B

ERR e PROTO são colunas separadas porque a especificação as trata como coisas separadas. Uma ferramenta que responde isError está a reportar algo sobre o qual um modelo pode agir e repetir. Um erro JSON-RPC é o pedido ou o servidor estar errado. SESS é a contagem de sessões que viram uma falha sobre as sessões que chamaram a ferramenta, que é a questão de "uma execução em dez" que uma taxa sobre chamadas não consegue responder.

As linhas são chaveadas pelo servidor e pelo rótulo em conjunto. O servidor é o comando registado e o diretório de trabalho para stdio e o endpoint para HTTP, a mesma identidade que o inventory usa. Qualquer metade sozinha agrupa algo que não deveria: o rótulo sozinho funde dois servidores que derivam um nome, o que acontece sempre que dois checkouts de um projeto executam o mesmo ponto de entrada, e a identidade sozinha funde um comando deliberadamente executado como prod e novamente como staging. Ambos os erros misturam duas distribuições limpas numa que não descreve nenhuma.

Quando duas linhas partilham um rótulo, a célula SERVER carrega o diretório de trabalho ou endpoint que as distingue, e o JSON carrega command, cwd e endpoint em cada linha. Um nome que nunca foi ambíguo é deixado em paz, por isso a tabela comum fica inalterada.

Cada sessão num registo é dobrada, não apenas a primeira, por isso um ficheiro feito por concatenação de capturas conta todas elas.

Os percentis são agrupados sobre as durações brutas. Uma mediana de medianas é uma mediana de nada. Uma operação com múltiplas idas e voltas é uma chamada com uma duração, independentemente de quantos pedidos levou, e uma chamada ainda aberta conta para CALLS enquanto não contribui com latência.

Uma captura está residente de cada vez. Um registo é carregado, dobrado nos contadores em execução e descartado antes de o próximo abrir, por isso um diretório com centenas custa a maior captura individual em vez da sua soma.

--limit tem como padrão uma centena dos registos mais recentes e o cabeçalho diz quantos de quantos foram lidos, por isso uma resposta limitada nunca passa por uma completa. stats reporta e não bloqueia: não escreve nada, não toca em nenhuma baseline, não abre nenhum socket e sai com 0 sempre que a varredura foi bem-sucedida.

Ver quais servidores realmente foram executados aqui

A descoberta que as pessoas repetem sobre o Shadow MCP é que as organizações descobrem várias vezes mais servidores MCP em execução do que alguém aprovou, porque um servidor é muitas vezes apenas uma dependência que alguém adicionou a um plugin de IDE. A mesma coisa acontece em miniatura num único portátil, e o mcpsnoop tem registado a resposta o tempo todo sem nunca a mostrar.```bash mcpsnoop inventory mcpsnoop inventory --tools # also count what each server last advertised mcpsnoop inventory --format json # for something else to read

root@kitploit:~
Uma linha por servidor, e não por sessão. A chave da linha é o comando registado
e o diretório de trabalho, nunca o rótulo, porque o rótulo vem do
último elemento do caminho do comando e `node ~/one/build/index.js` e
`node ~/two/build/index.js` derivam ambos `index.js`. Uma sessão HTTP baseia-se no
endpoint que fez proxy, uma vez que o mcpsnoop não lançou nada ali.

A leitura é um envelope por log, o quadro de metadados que o proxy escreve primeiro, por isso
isto permanece barato num diretório de capturas grandes. `--tools` é a exceção e
lê um log por servidor, a execução mais recente de cada um, razão pela qual é uma flag
em vez de uma coluna. Mesmo assim, a leitura é limitada, porque um inventário de ferramentas é
estado de sessão que a loja incorpora à medida que avança, pelo que uma captura de cem megabytes é
lida através de uma janela fixa em vez de ser mantida inteira para produzir um único inteiro.

Quando não há contagem, a linha indica qual de três coisas aconteceu, porque um
log que não pôde ser lido não é um servidor que não anunciou nada, e uma
frase para ambos faria o mcpsnoop afirmar algo falso.

Um comando que uma regra `--redact` reescreveu é impresso como registado e marcado, em vez
de ser apresentado como o comando que foi executado. Duas execuções de um servidor, uma limpa
e outra não, são duas linhas. O mcpsnoop não pode saber o que o espaço reservado substituiu,
e fundi-las significaria adivinhar que as metades ocultas coincidiam. Um servidor executado sob
dois valores `--label` é uma linha que carrega ambos os nomes, uma vez que a chave é o
comando em vez do nome.

Nada numa linha é escrito pelo mcpsnoop. Um comando vem de quem instalou
o servidor, um diretório de trabalho vem do sistema de ficheiros, e um rótulo derivado
vem do comando. Um valor que contém um caráter de controlo é citado em vez
de impresso em bruto, para que um diretório cujo nome contém uma nova linha não possa fechar o
campo em que é impresso e fazer com que as linhas seguintes sejam lidas como servidores que nunca
foram executados. Um argumento que contém um espaço também é citado, porque `node "~/My Project/
build/index.js"` é, de outra forma, indistinguível de dois argumentos.

Qualquer coisa que a passagem não pudesse incorporar é nomeada no cabeçalho em vez de ser descartada.
Logs vazios são contados separadamente dos danificados, uma vez que um log de zero bytes é o
resíduo comum de uma execução cujo exec falhou ou de um proxy HTTP que ninguém chamou.

A saída é ordenada por nome em vez de por recência, para que duas execuções sobre um diretório
produzam os mesmos bytes, o que é o que a torna utilizável como linha de base para comparar
posteriormente.

Existem duas lacunas por construção, em vez de por descuido. Uma execução com
`--trace-file` escreveu fora do diretório de sessões e não aparecerá, e
`prune` elimina logs, pelo que a primeira vista só é tão antiga quanto o que ainda está em
disco. O mcpsnoop reporta o que foi executado nesta máquina através dele. Não analisa nenhuma rede,
não lê nenhuma configuração de cliente para a qual não foi apontado, e não julga nada.

### Distinguir um servidor avariado de uma ferramenta que diz não

Uma ferramenta que responde `result.isError` está a funcionar. Ela procurou e não encontrou nada, ou
rejeitou a entrada. Um servidor que responde a um erro JSON-RPC está avariado. Ambos eram um
número no resumo de ferramentas, o que significava que uma ferramenta bem comportada que reporta falhas de domínio
parecia exatamente um servidor avariado, e era ordenada acima de um.

A coluna `ERR` separa-os. O vermelho é o lado do servidor, que é um erro JSON-RPC
ou uma tarefa que terminou falhada sem dizer porquê. A cor de aviso é o próprio `isError` da ferramenta.
Uma ferramenta com ambos mostra as contagens unidas, vermelho primeiro, e uma
linha sob a tabela nomeia os dois totais sempre que há um número de aviso para
explicar. A exportação carrega a mesma divisão como `protocol_errors` e
`tool_errors` ao lado do total `errors` a que sempre somam.

`check --fail-on error` permanece inalterado e ainda dispara em qualquer um dos casos,
uma vez que uma porta que ignorasse um deles seria uma porta que um servidor poderia desativar devolvendo
o outro.```bash
mcpsnoop export -T json | jq '.summary.tools[] | {name, errors, protocol_errors, tool_errors}'

Veja o que o servidor custa a você em contexto

As definições de ferramentas entram no contexto do modelo em toda conversa, e os resultados de ferramentas em toda chamada. O resumo de ferramentas (s) mede ambos a partir da sessão que você realmente capturou.

A linha definitions é o custo fixo: o que o tools/list deste servidor pesa antes de uma única chamada ser feita. A coluna DEF detalha isso por ferramenta e RESULT é o que as respostas de cada ferramenta custaram até agora. A tabela permanece ordenada por erros e latência, então examine DEF para encontrar as definições caras. A exportação as lista das mais pesadas primeiro. Uma linha abaixo da tabela nomeia o único resultado mais pesado, que um total esconde.

Os valores de definição são o JSON com espaços em branco insignificantes removidos, então um servidor que formata seu tools/list de forma bonita não é contado como mais caro do que um que não o faz, e o mesmo servidor mede o mesmo entre capturas. RESULT são os bytes como chegaram: um resultado é uma carga útil única, em vez de um contrato que valha a pena normalizar.```bash mcpsnoop export -T json | jq '.summary.definitions'

root@kitploit:~
A exportação traz os mesmos números, por ferramenta e divididos entre descrição e
bytes de schema, de modo que uma descrição grande e um schema grande permanecem separáveis e qualquer
um pode ser rastreado entre capturas. `mcpsnoop diff` informa se uma descrição ou
schema mudou entre duas sessões. A exportação é onde reside o tamanho dessa mudança.

**Estes são bytes, não tokens.** Uma contagem de tokens depende do modelo, portanto
medi-la significaria incluir um tokenizador e escolher de quem. Bytes são
exatos e você pode aplicar sua própria proporção. Um `tools/list` inacabado relata o que
viu como um piso e assim o diz, em vez de passar uma soma parcial como se fosse o
total.

### Detectar um cliente que corrompe o estado do servidor

No padrão de múltiplas idas e voltas, o servidor entrega ao cliente um
`requestState` opaco e o cliente deve devolvê-lo intacto na nova tentativa. O
servidor é instruído a tratá-lo como entrada controlada pelo atacante, porque um cliente que
o adultera pode tentar alterar o comportamento do servidor ou contornar uma verificação de
autorização.

Posicionado no fluxo, o mcpsnoop vê o valor sair e voltar, então pode dizer
quando o contrato foi quebrado. Há três maneiras de quebrá-lo, cada uma reportada como um
aviso de protocolo na nova tentativa.

| Reportado | Significado |
|---|---|
| `MRTR retry changed requestState` | o cliente devolveu algo diferente do que o servidor emitiu |
| `MRTR retry is missing requestState` | o servidor emitiu um e a nova tentativa o omitiu |
| `MRTR retry invented requestState` | a nova tentativa carregou um que o servidor nunca emitiu |

Estas são violações de protocolo pelo cliente, e não observações nossas, portanto
seguem o sinal de aviso comum e **uma execução padrão de `check` falha em uma delas**.
Isso é deliberado. Um cliente que corrompe o estado do servidor merece interromper uma compilação.

O valor em si nunca é exibido ou registrado, e nada o decodifica ou analisa.
Pode ser um bloco criptografado carregando um principal e um token, e comparar
bytes opacos é toda a verificação.

Um caso está fora de alcance. Quando um servidor responde com um `requestState` e sem
`inputRequests`, uma nova tentativa adulterada não corresponde a nada e não responde a nenhuma chave, portanto
não resta nada para vinculá-la à solicitação original e ela é lida como uma chamada
não relacionada, em vez de uma violação.

Uma troca abandonada não perturba a próxima, e também não é mantida para sempre.
Sessenta e quatro trocas abertas é muito mais do que qualquer cliente tem de uma vez, portanto uma
sessão que mantém mais está mantendo aquelas que ninguém terminará, e as mais antigas são
aposentadas porque a especificação instrui os servidores a dar a esse estado um prazo curto e
rejeitá-lo depois. A aposentadoria é contabilizada em vez de silenciosa. O rodapé do fluxo
mostra `N unlinked` e a exportação carrega `session.retired_exchanges`, porque uma
nova tentativa que chega para uma operação aposentada é lida como sua própria chamada, e um
leitor que compara contagens merece ser informado.

Aposentar uma também permite que o armazenamento ativo a libere. Uma operação estacionada permanece
pendente de propósito, portanto sua duração abrange toda a troca, e o armazenamento
recusa-se a esquecer uma chamada pendente porque uma resposta ainda pode estar chegando. Uma vez
que o limite aposentou uma operação, nada pode respondê-la, portanto mantê-la mantém uma
chamada viva que nenhum leitor pode alcançar. O que a sessão relata não muda. Ela
ainda é contada como pendente e ainda é contada em `N unlinked`, porque quanto
de memória um registro ocupa e o que o registro diz são perguntas diferentes.

Uma troca abandonada não perturba a próxima. O MRTR instrui os servidores a
não assumir que um cliente fará nova tentativa, portanto um usuário que recusa uma elicitação
deixa uma operação que nenhum quadro posterior jamais resolverá. O mcpsnoop procura primeiro
entre as operações cuja presença de `requestState` concorda com a da nova tentativa,
o que a especificação torna uma regra em ambas as direções, portanto uma nova tentativa conforme ainda
encontra a única operação que continua, mesmo quando uma troca abandonada na mesma
ferramenta está ao lado dela. A verificação que relata as três violações acima
é executada apenas quando nada concorda, portanto uma nova tentativa genuinamente não conforme ainda é
nomeada.

## Observando de outra máquina

Mantenha a captura local na máquina onde o tráfego ocorre e use SSH para o salto de
rede, de modo que o mcpsnoop nunca precise de um transporte remoto próprio.

### Visualização ao vivo

Execute a TUI na sua estação de trabalho e encaminhe o socket do mcpsnoop da máquina remota
de volta para ela. O túnel ao vivo usa encaminhamento de socket Unix via SSH, portanto ambas as extremidades devem
executar Linux ou macOS. No Windows, use a cópia do log pós-morte abaixo.```bash
# on your workstation, start the TUI
mcpsnoop

# create the remote socket directory once
ssh remote-user@remote-host 'mkdir -p ~/.local/state/mcpsnoop'

# print the tunnel command, then run the printed ssh -R line
mcpsnoop remote remote-user@remote-host

# on the remote host, wrap your server as usual
mcpsnoop -- node build/index.js

O socket reside no diretório de estado do remoto, resolvido como MCPSNOOP_HOME, senão XDG_STATE_HOME/mcpsnoop, senão ~/.local/state/mcpsnoop. Por padrão, o mcpsnoop assume o home Linux /home/<user> a partir do seu user@host e imprime um lembrete no stderr sempre que recorre a essa suposição. Se o remoto resolver em outro lugar, nomeie a única peça não padrão.```bash

a non-Linux or custom home, macOS is /Users/ and root is /root

mcpsnoop remote --remote-home /Users/remote-user remote-user@remote-host

an explicit MCPSNOOP_HOME on the remote

mcpsnoop remote --remote-mcpsnoop-home /srv/mcpsnoop remote-user@remote-host

an explicit XDG_STATE_HOME on the remote

mcpsnoop remote --remote-xdg-state-home /var/lib/state remote-user@remote-host

root@kitploit:~
### Post-mortem

Transmita uma sessão remota diretamente para a TUI via SSH, sem necessidade de cópia local.```bash
ssh remote-user@remote-host 'cat ~/.local/state/mcpsnoop/sessions/session.jsonl' | mcpsnoop open -

Para manter uma cópia local, use scp para copiar os logs para o seu diretório de sessões e execute a TUI normalmente.```bash

copy the remote logs into your local sessions directory

mkdir -p /.local/state/mcpsnoop/sessions scp remote-user@remote-host:'/.local/state/mcpsnoop/sessions/*.jsonl'
~/.local/state/mcpsnoop/sessions/

open the TUI, it backfills the copied sessions

mcpsnoop

root@kitploit:~
## Segurança

O mcpsnoop executa o comando do servidor que você envolve, portanto envolva apenas servidores em que confia e execute os não confiáveis em um contêiner. Ele nunca executa nada que você não tenha colocado na configuração do seu cliente.

Para fluxos de trabalho remotos, use túnel SSH ou transferência de arquivos via SSH para que autenticação de transporte, criptografia, verificação de host, rotação de chaves e política de auditoria permaneçam na sua configuração SSH existente.

### Redigindo o que você captura

Os quadros capturados podem incluir prompts, argumentos de ferramentas, credenciais e resultados de ferramentas. Se os payloads puderem carregar segredos, opte pela redação para limpar as cópias do trace observado enquanto os bytes intermediados ainda passam inalterados.

A redação baseada em chaves substitui valores inteiros sob chaves JSON correspondentes, e o mesmo conjunto de chaves é aplicado com melhor esforço aos argumentos de linha de comando do servidor envolvido, de modo que `--api-key=sk-x` e `--token sk-x` sejam limpos sob `--redact-secrets`. Um argumento que carrega um segredo sem um nome de flag reconhecível não pode ser detectado.

O endpoint HTTP não faz parte de nada disso, porque não é um payload que você escolheu enviar. `--target` é um flag que você precisa passar para executar o proxy, então sua URL chegaria ao log da sessão independentemente das suas configurações de redação. O mcpsnoop o registra com o userinfo, cada valor de query e o fragmento já removidos, sempre, por construção e não por padrão. As chaves de query sobrevivem, pois são o que distingue dois endpoints de um mesmo host, e o fragmento é descartado porque nunca chegou ao servidor em primeiro lugar. O que é registrado identifica o servidor e não é um endereço para discar.

A redação baseada em caminhos substitui apenas valores selecionados por uma expressão JSONPath, o que é útil quando um nome de chave comum é sensível em um local, mas seguro em outro. Repita `--redact-path` para limpar mais de um local.

A redação baseada em valores aplica expressões regulares a valores de string observados, texto de stderr e quadros de texto não JSON.

Todos os três são de melhor esforço. Expressões regulares podem deixar passar segredos, capturar texto inofensivo em excesso ou não detectar valores transformados ou codificados.

A redação nunca se transforma em uma acusação. Cada verificação que compara uma coisa observada com outra, um cabeçalho de roteamento contra o corpo, um valor de `Mcp-Param` contra o argumento que ele espelha, o schema de uma ferramenta contra o que a revisão exige dela, sabe quando o mcpsnoop foi o lado que reescreveu os bytes e permanece em silêncio em vez de reportar um servidor pela configuração de privacidade do próprio usuário. O desvio de definição de ferramenta é a exceção, e deliberadamente, pois ativar a redação muda o que é registrado e, portanto, o que uma linha de base contém. Consulte [Detectar desvio de definição de ferramenta](#detect-tool-definition-drift).```bash
# built-in preset of common secret keys
mcpsnoop --redact-secrets -- node build/index.js

# or name your own keys
mcpsnoop --redact-key token,api_key,password -- node build/index.js

# scrub one location without redacting every field named password
mcpsnoop --redact-path '$.params.arguments.password' -- node build/index.js

# wildcards scrub every matching array element
mcpsnoop --redact-path '$.params.arguments.accounts[*].password' -- node build/index.js

# scrub obvious token-shaped values outside known keys
mcpsnoop --redact-value 'sk-[A-Za-z0-9]+' -- node build/index.js

# combine the layers in http mode
mcpsnoop http --target http://localhost:3000/mcp --redact-secrets --redact-value 'Bearer\s+\S+'

Contributing

Issues e pull requests são bem-vindos. Consulte CONTRIBUTING.md para os detalhes.

License

MIT

Baixar ferramenta