Sigil
Camada de confiança para servidores MCP: varredura de segurança estática e comportamental, fuzzing e selos com versão fixada assinados por Ed25519 publicados em um índice público baseado em git.
Documentação
Sigil
Verificação de confiança para servidores MCP: heurísticas estáticas mais avaliações comportamentais, com selos de confiança assinados e fixados por versão. O lugar onde você verifica antes de instalar um servidor MCP.
Os scanners existentes auditam código estaticamente. O Sigil adiciona o que eles não fazem: ele executa o servidor (esquema, conformidade e oráculos de fuzzing semeados portados do harness mcp-eval da EVE) e publica o resultado como um selo assinado e fixado por versão que qualquer pessoa pode verificar sem gerenciamento de chaves.
Instalação
Requer Node.js 20 ou posterior.
npm install -g sigil-mcp
# or run without installing
npx -p sigil-mcp sigil scan ./my-server
A partir do código-fonte:
git clone https://github.com/fernandogarzaaa/sigil.git
cd sigil
npm install
npm run build
node dist/cli.js scan ./my-server
Início rápido
Verifique um servidor antes de instalá-lo, usando o índice público de confiança:
# See the verified install for a server (newest active version)
sigil pin @modelcontextprotocol/server-filesystem
# Pin an exact version
sigil pin @modelcontextprotocol/server-filesystem@2025.1.0
# Install the verified version (shows the badge first)
sigil install @modelcontextprotocol/server-filesystem --dry-run
Escaneie um servidor você mesmo e publique o selo:
sigil scan ./my-server --sign --badge-out my-server.trust.json
sigil verify my-server.trust.json
sigil publish --badge my-server.trust.json
Uso
# Scan a local directory (also accepts an npm spec or git URL)
sigil scan ./my-mcp-server
sigil scan express-mcp-server@1.2.3
sigil scan https://github.com/org/server.git
# CI gating: exit 2 when risk reaches the threshold (default: high)
sigil scan ./my-mcp-server --fail-on high
# Full JSON report
sigil scan ./my-mcp-server --json
# Sign a badge with your key (see keygen below)
sigil keygen
sigil scan ./my-mcp-server --sign --badge-out server.trust.json
sigil verify server.trust.json
# Publish a badge to the public trust index (opens a pull request)
sigil publish --badge server.trust.json
# or scan, sign, and publish in one step
sigil scan ./my-mcp-server --sign --publish
# Resolve the verified install from the public index
sigil pin my-server@1.2.3
sigil pin my-server # newest active (non-revoked) version
# Install the verified version (npm); shows the badge summary first
sigil install my-server@1.2.3
sigil install my-server --dry-run # preview only
# Revoke a badge version (project maintainer key)
sigil revoke --server my-server --version 1.2.3 \
--reason "Signer key compromised" \
--key ~/.config/sigil/project/key.priv.json \
--out revocation.json
# then open a PR adding revocations/my-server/1.2.3.json
Opções para scan: --json, --sign, --key <path>, --badge-out <path>, --publish, --fail-on <low|medium|high|critical>, --no-fuzz, --skip-audit, --timeout <ms>.
verify também verifica o selo contra o índice público de confiança (use --offline para pular): selos revogados saem com código 2 e o motivo, os substituídos emitem um aviso.
Códigos de saída: 0 passou na verificação (ou o comando foi bem-sucedido), 2 risco igual ou acima de --fail-on ou selo revogado na verificação, 1 erro operacional.
Índice de Confiança
Os selos são mais úteis em público. O sigil-index é um registro público baseado em git de selos assinados em badges/<server>/<version>.json, navegável em https://fernandogarzaaa.github.io/sigil-index/.
sigil publish --badge <file> verifica o selo localmente primeiro e depois abre uma solicitação de pull contra o índice (requer a CLI do GitHub, gh, instalada e autenticada). A CI verifica cada selo enviado: esquema JSON, assinatura Ed25519 contra a chave pública incorporada, posicionamento correto de badges/<server>/<version>.json e sem versões duplicadas. O índice é somente de acréscimo por versão: uma nova varredura de uma nova versão adiciona um novo arquivo.
Cada selo carrega um status derivado: active (versão indexada mais recente), superseded (uma versão mais antiga) ou revoked (o mantenedor do projeto publicou uma revogação assinada em revocations/<server>/<version>.json). sigil pin recusa versões revogadas, e sigil verify informa o status do índice.
Um selo atesta a versão exata escaneada, nada mais. A confiança no signatário (o ID da chave) é fora de banda, como um ID de chave PGP: o índice prova que um selo está íntegro e bem formado, não que seu signatário é honesto.
O que ele verifica
Passo estático (sem execução):
- Classificação de capacidades das ferramentas, incluindo o formato da tríade letal: uma superfície de ferramenta que combina acesso a dados privados, egresso de rede e execução de código.
- Padrões de envenenamento de descrição de ferramentas: sobreposição de instruções ("ignore instruções anteriores"), solicitações de divulgação do prompt do sistema, diretivas de exfiltração, frases de jailbreak, links markdown incorporados.
- Heurísticas de fonte: segredos commitados (chaves AWS, material de chave privada),
eval/new Function, comandos shell construídos com interpolação, URLs remotas codificadas, valores de ambiente fluindo para chamadas de rede. - Acúmulo de severidade
npm auditsobre a árvore de dependências. - Extração de ferramentas com melhor esforço a partir do código-fonte quando o servidor não pode ser iniciado.
Passo comportamental (inicia o servidor via stdio, ou conecta via HTTP):
- Oráculo de esquema: esquemas de entrada malformados, descrições ausentes/rasas, desonestidade de anotações (
delete_*comdestructiveHint: false). - Oráculo de conformidade: handshake de inicialização, declaração de capacidades, ping, comportamento de erro para ferramenta desconhecida.
- Oráculo de fuzzing: entradas adversariais semeadas por ferramenta (violações de tipo, campos obrigatórios ausentes, valores de limite, payloads superdimensionados), classificadas como erro de protocolo, resultado de erro, aceito, travamento ou falha.
Pontuação: cada achado deduz de 100 em um único cronograma (crítico 25, grave 12, menor 4, informativo 1). Qualquer achado crítico força um nível de risco critical; caso contrário, abaixo de 70 é high, abaixo de 90 é medium, o restante low.
Selos: JSON assinado com Ed25519 vinculando servidor, fixação de versão, pontuações, contagens de achados e um hash SHA-256 do conteúdo pontuado. O selo incorpora a chave pública do signatário, então a verificação é autocontida. A confiança no signatário (ID da chave) é fora de banda, como um ID de chave PGP.
Exemplo de saída
sigil: fixture-server@0.1.0 [local]
risk score: 0/100 (critical)
findings: 16 total (1 critical, 6 major, 6 minor, 3 info)
static: 10 findings over 4 tool(s) [runtime]
behavioral: schemaQuality 79/100, robustness 92/100, conformance 100/100
fuzz: 8 calls over 4 tool(s): 0 protocol errors, 0 error results, 4 accepted-invalid, 0 hangs, 0 crashes
[critical] (server.js) Possible AWS access key committed in source (static)
- server.js:23: const AWS_KEY = "AKIA...";
[major] [fetch_and_run] "fetch_and_run" combines data access, network egress, and code execution (static)
- capabilities detected: data access, network egress, code execution
[major] [fetch_and_run] Instruction-override phrasing in tool description (static)
- description of "fetch_and_run" matched: "Ignore previous instructions"
[major] [get_status] "get_status" has no description (behavioral)
- tools/list entry for "get_status" carries no description
...
Limitações (leia antes de confiar em uma varredura)
- As verificações estáticas são heurísticas com falsos positivos. Uma ferramenta que lê arquivos, chama a rede e executa comandos pode ser uma ferramenta de implantação perfeitamente legítima. Os achados são prompts de revisão com evidências citadas, nunca veredictos.
- Uma varredura aprovada não é uma garantia. O passo comportamental apenas exercita o que consegue alcançar pelo protocolo; ele não revisa a lógica de negócios, e o oráculo de fuzzing usa um pequeno orçamento de casos semeados.
- O scanner executa o alvo. O passo comportamental inicia o servidor como um subprocesso. Apenas escaneie código que você decidiu executar.
- A auditoria de dependências precisa da rede e degrada para "desconhecido" quando
npm auditnão pode ser executado. - As pontuações de avaliação atestam apenas a versão escaneada. Um selo é fixado a uma versão exata; um novo lançamento precisa de uma nova varredura.
Desenvolvimento
npm run build # typecheck + emit to dist/
npm test # vitest (build first: the e2e tests run dist/cli.js)
npm run lint # biome check
Licença
MIT. Veja LICENSE.