Pular para o conteúdo
Guide

Proteja seu servidor MCP: uma lista de verificação de desenvolvedor de 8 pontos

| 8 min read

43 estruturas de agentes enviadas com vulnerabilidades incorporadas em 2026. Oito verificações para bloquear seu servidor MCP antes que um agente de IA encontre as lacunas.

Server room with colorful network cables representing MCP server infrastructure
Photo by Taylor Vick on Unsplash

Em novembro de 2026, Barracuda relatou que 43 componentes da estrutura do agente foram enviados com vulnerabilidades incorporadas através do comprometimento da cadeia de suprimentos. Os invasores não invadiram os servidores. Eles envenenaram as ferramentas que os agentes de IA ligue. O OWASP Agentic Apps Top 10 agora lista vulnerabilidades da cadeia de suprimentos e uso indevido de ferramentas como dedicado categorias.

Os servidores MCP (Model Context Protocol) expõem suas APIs como ferramentas que podem ser chamadas para assistentes de IA: Claude Desktop, Cursor, Copiloto VS Code, Windsurf. Cada ferramenta que você registra se torna uma superfície de ataque. E a maioria dos servidores MCP enviado sem autenticação, sem validação de entrada e sem registro.

Esta postagem é uma lista de verificação de 8 pontos para proteger seu servidor MCP. Cada item inclui código de trabalho que você pode adaptar. Os exemplos usam o API Botoi para validação de esquema, hashing, e decodificação JWT, mas os padrões se aplicam a qualquer servidor MCP.

O problema de segurança do MCP em uma tabela

Risco O que acontece Item da lista de verificação
Sem autenticação no endpoint MCP Qualquer cliente na rede chama qualquer ferramenta #1 Adicionar autenticação
Todas as ferramentas expostas a todas as chaves Um agente de monitoramento somente leitura aciona operações destrutivas #2 Ferramentas de escopo por chave
Sem validação de entrada Agentes enviam JSON malformado; ferramentas travam ou executam operações não intencionais Nº 3 Validar com Zod
Anotações de ferramenta ausentes Os agentes não conseguem distinguir ferramentas somente leitura das destrutivas #4 Definir anotações
Sem limites de taxa Um agente de loop esgota sua cota de API em minutos #5 Limite de taxa por agente
Sem trilha de auditoria Não é possível rastrear qual agente causou um problema de produção #6 Registrar invocações
Adulteração de manifesto de ferramenta Atacante modifica definições de ferramentas para redirecionar chamadas #7 Manifestos de pin e hash
Nenhuma confirmação para gravações O agente cria, exclui ou modifica dados sem revisão humana #8 Operações destrutivas em sandbox

1. Adicione autenticação ao seu endpoint MCP

"Está no host local" não é um modelo de segurança. Extensões de navegador, processos locais e qualquer código em execução a mesma máquina pode alcançar localhost:3000. O MCP remoto está crescendo rapidamente; Claude Desktop, Cursor, e Windsurf suportam conexão com servidores MCP remotos por HTTPS.

Exija um token de portador em cada solicitação. Servidor MCP do Botoi em api.botoi.com/mcp aceita API chaves através do Authorization cabeçalho. Sem uma chave válida, você recebe 5 solicitações por minuto e 100 por dia; com um, os limites se adaptam ao seu plano.

Se seus agentes passarem JWTs em vez de chaves estáticas, decodifique-os para extrair escopos e identidade. Veja como para inspecionar um JWT de um cabeçalho de solicitação MCP:

curl -s -X POST https://api.botoi.com/v1/jwt/decode \\
  -H "Content-Type: application/json" \\
  -d '{
    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZ2VudC1jdXJzb3ItNDIiLCJzY29wZSI6InJlYWQ6ZG5zIHJlYWQ6c3NsIiwiaWF0IjoxNzE3MDAwMDAwfQ.signature"
  }'
{
  "success": true,
  "data": {
    "header": { "alg": "RS256", "typ": "JWT" },
    "payload": {
      "sub": "agent-cursor-42",
      "scope": "read:dns read:ssl",
      "iat": 1717000000
    },
    "signature": "signature"
  }
}

O sub reivindicação identifica o agente. O scope reivindicação lista quais ferramentas ela pode acesso. Verifique a assinatura do lado do servidor antes de confiar nesses valores.

2. Ferramentas de escopo por chave de API

Nem todo agente precisa de todas as ferramentas. Um agente de monitoramento que verifica registros DNS nunca deve acessar um ponto de extremidade de criação de pasta. Crie listas de permissões que mapeiem cada chave de API para um conjunto específico de ferramentas.

// Scope tools per API key using an allowlist
interface AgentPermissions {
  allowedTools: Set<string>;
  maxBurst: number;
  dailyLimit: number;
}

const AGENT_PERMISSIONS: Record<string, AgentPermissions> = {
  "key_readonly_monitor": {
    allowedTools: new Set(["lookup_dns", "lookup_ssl", "lookup_ip"]),
    maxBurst: 10,
    dailyLimit: 500,
  },
  "key_full_access": {
    allowedTools: new Set(["*"]),  // wildcard for all tools
    maxBurst: 30,
    dailyLimit: 5000,
  },
};

function canUseTool(apiKey: string, toolName: string): boolean {
  const perms = AGENT_PERMISSIONS[apiKey];
  if (!perms) return false;
  if (perms.allowedTools.has("*")) return true;
  return perms.allowedTools.has(toolName);
}

O servidor MCP da Botoi expõe 49 ferramentas selecionadas de mais de 150 endpoints de API. A curadoria em si é uma forma de escopo: apenas as ferramentas que fazem sentido para os assistentes de IA são registradas. Seu servidor deve fazer o mesmo.

3. Valide as entradas da ferramenta com esquemas Zod

As ferramentas MCP aceitam JSON arbitrário dos agentes. Um agente pode enviar onde você espere uma string ou inclua campos que sua ferramenta não reconhece. Valide cada entrada antes de executar.

O servidor MCP do Botoi converte definições de caminho OpenAPI em esquemas Zod na inicialização usando schema-builder.ts. O buildZodSchema função lê sua especificação OpenAPI, mapeia cada tipo de propriedade para um tipo Zod e marca os campos obrigatórios:

import { z } from "zod";
import { buildZodSchema } from "./schema-builder";

// Build a Zod schema from your OpenAPI spec for each tool
const dnsSchema = z.object(buildZodSchema("/v1/dns/lookup", "post"));

function validateToolInput(toolName: string, input: unknown) {
  const schemas: Record<string, z.ZodTypeAny> = {
    lookup_dns: dnsSchema,
    // ... one schema per tool
  };

  const schema = schemas[toolName];
  if (!schema) {
    throw new Error(\`Unknown tool: \${toolName}\`);
  }

  const result = schema.safeParse(input);
  if (!result.success) {
    return {
      error: "Invalid input",
      issues: result.error.issues.map((i) => ({
        path: i.path.join("."),
        message: i.message,
      })),
    };
  }

  return { data: result.data };
}

Gere esquemas Zod a partir de entradas de amostra

Se você não tiver uma especificação OpenAPI, gere esquemas Zod a partir de entradas de ferramentas de exemplo:

curl -s -X POST https://api.botoi.com/v1/schema/json-to-zod \\
  -H "Content-Type: application/json" \\
  -d '{
    "json": {
      "domain": "github.com",
      "check_mx": true,
      "timeout_ms": 5000
    }
  }'
{
  "success": true,
  "data": {
    "schema": "z.object({ domain: z.string(), check_mx: z.boolean(), timeout_ms: z.number() })"
  }
}

Valide entradas no esquema JSON em tempo de execução

Para validação em tempo de execução sem Zod, use o esquema JSON. Envie o esquema e a entrada do agente para /v1/schema/validate:

curl -s -X POST https://api.botoi.com/v1/schema/validate \\
  -H "Content-Type: application/json" \\
  -d '{
    "schema": {
      "type": "object",
      "required": ["domain"],
      "properties": {
        "domain": { "type": "string", "minLength": 1 },
        "record_type": { "type": "string", "enum": ["A", "AAAA", "MX", "TXT", "CNAME", "NS"] }
      },
      "additionalProperties": false
    },
    "data": { "domain": "stripe.com", "record_type": "MX" }
  }'

Retornos de entrada válidos:

{
  "success": true,
  "data": {
    "valid": true,
    "errors": []
  }
}

Se um agente passar "record_type": "INVALID", você receberá erros acionáveis ​​antes da ferramenta ser executada:

{
  "success": true,
  "data": {
    "valid": false,
    "errors": [
      {
        "path": "/record_type",
        "message": "must be equal to one of the allowed values"
      }
    ]
  }
}

4. Defina anotações de ferramentas

O protocolo MCP define quatro dicas de anotação: readOnlyHint, destructiveHint, idempotentHint, e openWorldHint. Eles informam aos agentes se uma ferramenta lê dados, modifica o estado, é seguro tentar novamente ou entra em contato com serviços externos. A maioria dos servidores MCP os ignora.

O servidor MCP do Botoi anota todas as 49 ferramentas. Aqui está o que isso parece na prática:

// curated-tools.ts (from Botoi's MCP server)
export const CURATED_TOOLS: Record<string, CuratedTool> = {
  lookup_dns: {
    path: "/v1/dns/lookup",
    method: "post",
    title: "DNS Lookup",
    description: "Query DNS records for a domain.",
    annotations: {
      readOnlyHint: true,   // reads data, changes nothing
      openWorldHint: true,  // contacts external DNS servers
    },
  },
  storage_paste_create: {
    path: "/v1/paste/create",
    method: "post",
    title: "Create Paste",
    description: "Store text content and return a short URL.",
    annotations: {
      destructiveHint: true,  // creates new data
      idempotentHint: false,  // each call creates a new paste
    },
  },
};

Agentes que respeitam anotações evitarão chamar ferramentas destrutivas sem confirmação e preferirão ferramentas idempotentes ao tentar novamente solicitações com falha. Defina-os em todas as ferramentas.

Anotação Significada Exemplo
readOnlyHint: true A ferramenta lê dados, não altera nada Pesquisa de DNS, verificação de SSL, geolocalização de IP
destructiveHint: true A ferramenta cria, atualiza ou exclui dados Criar, colar, gerar URL curto, enviar webhook
idempotentHint: true É seguro ligar várias vezes com a mesma entrada Geração de hash, formatação JSON, conversão de unidades
openWorldHint: true Ferramenta contata serviços externos DNS sobre HTTPS, WHOIS, extração de metadados de URL

5. Limite de taxa por identidade do agente

Um agente invasor preso em um loop de novas tentativas não deve esgotar toda a sua cota de API. Limitação de taxa padrão por endereço IP não é suficiente; vários agentes podem compartilhar o mesmo IP e um único agente pode alternar IPs.

Extraia a identidade do agente da chave de API ou JWT e aplique limites por identidade usando uma janela deslizante ou token bucket armazenado em KV:

// Hono middleware for per-agent rate limiting
import type { Context, Next } from "hono";

const BURST_LIMIT = 5;   // requests per minute
const DAILY_LIMIT = 100;  // requests per day

async function rateLimitAgent(c: Context, next: Next) {
  // Extract agent identity from API key or JWT
  const apiKey = c.req.header("Authorization")?.replace("Bearer ", "");
  const agentId = apiKey || c.req.header("X-Forwarded-For") || "anonymous";

  // Check burst limit (sliding window in KV)
  const burstKey = \`rate:\${agentId}:burst\

O middleware de autenticação do Botoi impõe duas camadas: um limite de burst (5 solicitações por minuto) e um limite diário (100 solicitações por dia) para acesso anônimo. As chaves autenticadas obtêm limites mais altos com base em suas Nível de assinatura Stripe. Aplique o mesmo padrão de duas camadas ao seu servidor MCP.

6. Registre cada invocação de ferramenta com atribuição de agente

Quando algo dá errado na produção, você precisa responder a três perguntas: qual agente ligou para qual ferramenta, quando e com que entrada. Sem logs de invocação, você está depurando às cegas.

Faça hash da entrada em vez de armazenar argumentos brutos. Isso lhe dá o suficiente para correlacionar e desduplicar sem registrar dados confidenciais:

// Log every tool invocation with agent identity
interface ToolInvocationLog {
  timestamp: string;
  agent_id: string;
  tool_name: string;
  input_hash: string;   // SHA-256 of the input (not the raw input)
  duration_ms: number;
  status: "success" | "error";
}

async function logToolInvocation(
  agentId: string,
  toolName: string,
  input: unknown,
  startTime: number,
  status: "success" | "error"
) {
  const inputStr = JSON.stringify(input);
  const inputHash = await crypto.subtle.digest(
    "SHA-256",
    new TextEncoder().encode(inputStr)
  );
  const hashHex = Array.from(new Uint8Array(inputHash))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");

  const log: ToolInvocationLog = {
    timestamp: new Date().toISOString(),
    agent_id: agentId,
    tool_name: toolName,
    input_hash: hashHex,
    duration_ms: Date.now() - startTime,
    status,
  };

  // Send to your logging pipeline (Datadog, Loki, Cloudflare Logpush)
  console.log(JSON.stringify(log));
}

Envie esses logs estruturados para seu pipeline existente (Datadog, Grafana Loki, Cloudflare Logpush). Crie alertas para padrões incomuns: um único agente realizando 10 vezes o volume normal de chamadas ou um alerta somente leitura agente tentando chamar ferramentas destrutivas.

7. Fixe as definições da ferramenta e verifique a integridade

O relatório Barracuda descobriu que invasores injetaram definições de ferramentas maliciosas em estruturas de agentes por meio de dependências comprometidas. Se alguém modificar o manifesto da sua ferramenta MCP (nomes, descrições ou parâmetros esquemas), os agentes chamarão ferramentas com comportamento diferente do pretendido.

Faça hash do manifesto da sua ferramenta no momento da construção. Na inicialização, recalcule o hash e compare:

import crypto from "node:crypto";
import Botoi from "@botoi/sdk";

const botoi = new Botoi();

// Your tool manifest (the source of truth)
const tools = [
  { name: "dns_lookup", path: "/v1/dns/lookup" },
  { name: "ip_lookup", path: "/v1/ip/lookup" },
  { name: "email_validate", path: "/v1/email/validate" },
  // ... all your tools
];

const manifest = JSON.stringify(tools);

// Hash it at build time and store the expected hash
const EXPECTED_HASH = "a3f2b8c1d4e5f6..."; // from your CI build

// At startup, verify integrity
function verifyManifestIntegrity() {
  const currentHash = crypto
    .createHash("sha256")
    .update(manifest)
    .digest("hex");

  if (currentHash !== EXPECTED_HASH) {
    throw new Error(
      \`Tool manifest tampered. Expected \${EXPECTED_HASH}, got \${currentHash}\`
    );
  }

  console.log("Tool manifest integrity verified.");
}

// Or use the Botoi API for environments without Node crypto
async function verifyWithApi() {
  const result = await botoi.hash.sha256({ input: manifest });
  if (result.data.hash !== EXPECTED_HASH) {
    throw new Error("Tool manifest tampered.");
  }
}

Gere o hash com a API do Botoi

Para ambientes de CI ou tempos de execução de borda sem node:crypto:

curl -s -X POST https://api.botoi.com/v1/hash \\
  -H "Content-Type: application/json" \\
  -d '{
    "text": "[{\\"name\\":\\"dns_lookup\\",\\"path\\":\\"/v1/dns/lookup\\"},{\\"name\\":\\"ip_lookup\\",\\"path\\":\\"/v1/ip/lookup\\"}]",
    "algorithm": "sha256"
  }'
{
  "success": true,
  "data": {
    "hash": "a3f2b8c1d4e5f67890abcdef1234567890abcdef1234567890abcdef12345678",
    "algorithm": "sha256"
  }
}

Armazene o hash esperado como uma variável de ambiente. Compare-o no momento da implantação. Se os hashes divergirem, bloquear a implantação.

8. Operações destrutivas em sandbox

Ferramentas que gravam dados, acionam efeitos colaterais ou entram em contato com serviços externos precisam de um fluxo de confirmação. Não deixe um agente criar 1.000 pastas ou disparar webhooks sem revisão humana.

// Confirmation flow for destructive MCP tools
interface ToolResult {
  content: Array<{ type: string; text: string }>;
  isError?: boolean;
}

function handleDestructiveTool(
  toolName: string,
  input: Record<string, unknown>,
  confirmed: boolean
): ToolResult {
  const destructiveTools = new Set([
    "paste_create",
    "short_url_create",
    "webhook_inbox_create",
  ]);

  if (!destructiveTools.has(toolName)) {
    // Non-destructive: execute immediately
    return executeTool(toolName, input);
  }

  if (!confirmed) {
    // Return a preview instead of executing
    return {
      content: [{
        type: "text",
        text: JSON.stringify({
          action: "confirmation_required",
          tool: toolName,
          input,
          message: \`This tool will create new data. Pass "confirmed": true to proceed.\`,
        }),
      }],
    };
  }

  // Confirmed: execute the destructive operation
  return executeTool(toolName, input);
}

O padrão é simples: ferramentas destrutivas retornam uma prévia na primeira chamada. O agente mostra a visualização para o usuário. Somente após a confirmação do usuário o agente envia uma segunda chamada com "confirmed": true.

Para ferramentas que entram em contato com serviços externos (openWorldHint: true), considere adicionar um tempo limite e um disjuntor. Se uma API externa estiver lenta ou inativa, seu servidor MCP não deverá espere para sempre por uma resposta.

Como o servidor MCP do Botoi aplica essas verificações

Servidor MCP do Botoi em api.botoi.com/mcp serve como referência de trabalho para este lista de verificação. Veja como cada item é mapeado:

Item da lista de verificação Como Botoi faz isso
Autenticação Chaves de API por meio de Authorization cabeçalho; acesso anônimo com limites de taxa rígidos
Escopo da ferramenta 49 ferramentas selecionadas de mais de 150 endpoints; apenas ferramentas apropriadas ao agente são registradas
Validação de entrada schema-builder.ts converte esquemas OpenAPI em Zod; valida antes da execução
Anotações de ferramentas Cada ferramenta em curated-tools.ts tem readOnlyHint, destructiveHint, etc.
Limitação de taxa Burst de 5 req/min + limite anônimo de 100 req/dia via KV; limites mais altos por nível de chave de API
Registro Registros de observabilidade do Cloudflare Workers para cada solicitação com atribuição de agente
Integridade manifesta As definições de ferramentas estão em TypeScript com controle de versão; implantado via CI sem mutação de tempo de execução
Sandbox destrutivo As ferramentas de armazenamento (colar, URL curto, webhook) são separadas das ferramentas de pesquisa somente leitura; anotações sinalizam risco

Você pode se conectar ao servidor MCP do Botoi a partir do Claude Desktop, Claude Code, Cursor, VS Code ou Windsurf. O Página de configuração do MCP tem a configuração para cada cliente.

Sua lista de verificação de segurança do servidor MCP

Aqui está a lista de verificação completa, condensada. Imprima, fixe ou cole no runbook da sua equipe:

  • Exigir autenticação em cada endpoint MCP (token de portador, chave de API ou JWT)
  • Mapeie cada chave de API para uma lista de permissões de ferramentas permitidas
  • Valide cada entrada de ferramenta com esquemas Zod ou esquema JSON antes da execução
  • Anote cada ferramenta com readOnlyHint, destructiveHint, idempotentHint, e openWorldHint
  • Limite de taxa por identidade de agente, não por IP; use limites diários e contínuos
  • Registrar cada chamada de ferramenta com ID do agente, nome da ferramenta, hash de entrada, duração e status
  • Faça hash do manifesto da sua ferramenta no momento da construção; verifique na inicialização e bloqueie implantações adulteradas
  • Retornar visualizações de ferramentas destrutivas; requer confirmação explícita antes de executar

43 estruturas de agentes enviadas com vulnerabilidades incorporadas em 2026. Os servidores MCP são o próximo alvo. As oito verificações acima não tornarão seu servidor invulnerável, mas preencherão as lacunas que os invasores explore primeiro: endpoints abertos, entradas não validadas e invocações invisíveis.

FAQ

Os servidores MCP precisam de autenticação?
Sim. A maioria dos servidores MCP é fornecida sem autenticação, o que significa que qualquer cliente que alcance o endpoint pode invocar qualquer ferramenta. À medida que a adoção remota do MCP cresce, você precisa de uma chave de API ou de autenticação baseada em JWT em cada endpoint. Somente localhost não é uma garantia de segurança; processos locais e extensões de navegador também podem alcançar o localhost.
O que são anotações da ferramenta MCP e por que são importantes?
As anotações de ferramentas são dicas de metadados definidas no protocolo MCP: readOnlyHint, destructiveHint, idempotentHint e openWorldHint. Eles informam aos agentes de IA se uma ferramenta lê dados, modifica o estado, é seguro tentar novamente ou entra em contato com serviços externos. Os agentes usam essas dicas para tomar decisões mais seguras sobre quais ferramentas chamar e em que ordem.
Como faço para limitar a taxa de agentes de IA que chamam meu servidor MCP?
Atribua uma identidade a cada agente (ou chave de API) e aplique limites de taxa por identidade. Use um token bucket ou algoritmo de janela deslizante. Rastreie solicitações em uma loja KV ou Redis. O próprio servidor MCP da Botoi impõe 5 solicitações por minuto e 100 solicitações por dia para acesso anônimo, com limites mais altos para chaves autenticadas.
Posso validar as entradas da ferramenta MCP com Zod?
Sim. As ferramentas MCP recebem JSON arbitrário dos agentes. Defina um esquema Zod para o formato de entrada esperado de cada ferramenta e valide antes de executar. Você pode gerar esquemas Zod a partir de JSON de amostra usando o endpoint Botoi /v1/schema/json-to-zod ou converter definições de caminho OpenAPI em objetos Zod como faz o schema-builder.ts do Botoi.
Como posso detectar adulteração do manifesto da minha ferramenta MCP?
Faça hash do manifesto da sua ferramenta com SHA-256 e armazene o hash. Antes de iniciar ou implantar cada servidor, recalcule o hash e compare. Se os hashes forem diferentes, alguém (ou algo) modificou as definições da sua ferramenta. Você pode calcular hashes SHA-256 por meio do endpoint Botoi /v1/hash ou com bibliotecas de criptografia nativas.

Comece a construir com botoi

150+ endpoints de API para consultas, processamento de texto, geração de imagens e utilitários para desenvolvedores. Plano gratuito, sem cartão de crédito.