O Protocolo de Contexto do Modelo (MCP) revoluciona a forma como assistentes de IA interagem com ferramentas externas e fontes de dados. Pense no MCP como uma porta USB-C universal para aplicações de IA — ele fornece uma maneira padronizada de conectar o Claude Code a praticamente qualquer fonte de dados, API ou ferramenta que você possa imaginar. Este guia abrangente irá guiá-lo na construção do seu próprio servidor MCP do zero, permitindo que o Claude Code acesse funcionalidades personalizadas que estendem suas capacidades muito além de seus recursos integrados.
Quer você queira integrar bancos de dados, APIs, sistemas de arquivos ou criar ferramentas totalmente personalizadas, o MCP fornece a base para extensibilidade ilimitada. Ao final deste tutorial, você terá um servidor MCP funcionando e entenderá como expandi-lo para qualquer caso de uso.
Quer uma plataforma integrada e Completa para sua Equipe de Desenvolvedores trabalhar com máxima produtividade?
Apidog entrega todas as suas demandas e substitui o Postman a um preço muito mais acessível!
We’re thrilled to share that MCP support is coming soon to Apidog! 🚀
— Apidog (@ApidogHQ) March 19, 2025
Apidog MCP Server lets you feed API docs directly to Agentic AI, supercharging your vibe coding experience! Whether you're using Cursor, Cline, or Windsurf - it'll make your dev process faster and smoother.… pic.twitter.com/ew8U38mU0K
O Que é um Servidor MCP e Por Que Todos Estão Falando Sobre Ele
O Que Torna o MCP Diferente
MCP (Model Context Protocol) é um protocolo aberto desenvolvido pela Anthropic que permite que modelos de IA se comuniquem com servidores externos através de uma interface padronizada. Diferente das integrações de API tradicionais onde você codifica endpoints específicos, o MCP fornece uma maneira estruturada para assistentes de IA descobrirem, entenderem e utilizarem ferramentas externas dinamicamente.
O gênio do MCP reside na sua capacidade de descoberta. Quando o Claude Code se conecta ao seu servidor MCP, ele aprende automaticamente quais ferramentas estão disponíveis, como usá-las e quais parâmetros elas aceitam. Isso significa que você pode adicionar novas funcionalidades sem precisar atualizar o próprio Claude Code.
Arquitetura do MCP em Detalhes
O protocolo segue uma arquitetura cliente-servidor com papéis claramente definidos:
- Hosts MCP: Aplicações como Claude Code, Claude Desktop, ou outros assistentes de IA que consomem serviços MCP
- Clientes MCP: Clientes de protocolo que mantêm conexões 1:1 com servidores e lidam com a comunicação
- Servidores MCP: Programas leves que expõem capacidades específicas através do protocolo padronizado
- Camada de Transporte: Método de comunicação (stdio para servidores locais, SSE para servidores remotos)
Fluxo de Comunicação Explicado
Quando o Claude Code precisa usar uma ferramenta externa, veja o que acontece:
- Fase de Descoberta: O Claude Code consulta seu servidor por ferramentas disponíveis
- Validação de Esquema: Seu servidor responde com definições de ferramentas e esquemas de entrada
- Seleção de Ferramenta: O Claude Code escolhe ferramentas apropriadas com base nas solicitações do usuário
- Fase de Execução: O Claude Code envia chamadas de ferramenta com parâmetros validados
- Processamento de Resultado: Seu servidor processa a solicitação e retorna resultados estruturados
Este fluxo garante segurança de tipo, tratamento de erros adequado e comportamento consistente em todas as integrações MCP.
Pré-requisitos e Configuração do Ambiente
Análise dos Requisitos do Sistema
Antes de construir seu servidor MCP, você precisa entender seu ambiente de desenvolvimento e escolher as ferramentas certas. Servidores MCP podem ser construídos em várias linguagens, mas Python e TypeScript são as mais comumente suportadas com ferramentas extensivas.
Para Desenvolvimento Python:
- Python 3.8 ou superior - Necessário para suporte moderno a async/await e anotações de tipo
- Gerenciador de pacotes pip - Para gerenciamento de dependências
- Ferramentas de ambiente virtual - Use
venv
ouconda
para isolar dependências
Para Desenvolvimento TypeScript/JavaScript:
- Node.js v20 ou posterior - Necessário para recursos modernos do ECMAScript e estabilidade
- npm ou yarn - Para gerenciamento de pacotes
- Compilador TypeScript - Se estiver usando TypeScript para melhor segurança de tipo
Dependências Essenciais:
- Claude Code CLI: A interface principal para gerenciamento de servidor MCP
- Conhecimento de JSON-RPC 2.0: Entendimento do protocolo de comunicação subjacente
- Conceitos básicos de arquitetura de servidor: Ciclos de solicitação/resposta e tratamento de erros
Preparação do Ambiente Passo a Passo
1. Instalar o Claude Code CLI
O Claude Code CLI é sua ferramenta principal para gerenciar servidores MCP. Instale-o globalmente para garantir acesso de qualquer diretório:
# Install Claude Code globally
npm install -g @anthropic-ai/claude-code
Por que a instalação global é importante: A instalação global garante que o comando claude
esteja disponível em todo o sistema, prevenindo problemas relacionados a caminhos ao registrar servidores MCP de diferentes diretórios.
2. Verificar a Instalação
Verifique se o Claude Code está instalado e acessível corretamente:
# Verify installation and check version
claude --version
# Check available commands
claude --help
3. Configuração Crítica de Permissões na Primeira Vez
Este passo é absolutamente essencial e frequentemente negligenciado:
# Run initial setup with permissions bypass
claude --dangerously-skip-permissions
O que este comando faz:
- Inicializa o diretório de configuração do Claude Code
- Estabelece permissões de segurança para comunicação MCP
- Cria tokens de autenticação necessários
- Configura o banco de dados de registro MCP
Por que é necessário: Sem este passo, servidores MCP não conseguem estabelecer conexões seguras com o Claude Code, levando a falhas de autenticação e timeouts de conexão.
Considerações de segurança: A flag --dangerously-skip-permissions
é segura para ambientes de desenvolvimento, mas ignora os prompts de segurança normais. Em ambientes de produção, revise cada solicitação de permissão cuidadosamente.
Configuração Crítica: Entendendo os Escopos do MCP
Por Que os Escopos de Configuração São Importantes
Um dos erros mais comuns ao construir servidores MCP é o gerenciamento inadequado do escopo de configuração. Entender os escopos é crucial porque eles determinam onde e quando seu servidor MCP está disponível para o Claude Code. Muitos desenvolvedores gastam horas depurando erros de "servidor não encontrado" que resultam de má configuração de escopo.
O Claude Code usa um sistema de configuração hierárquico projetado para fornecer flexibilidade enquanto mantém a segurança. Cada escopo serve a um propósito específico e tem diferentes casos de uso.
Hierarquia de Escopo de Configuração Explicada
1. Escopo de Projeto (.mcp.json
) - Prioridade Mais Alta
Localização: Diretório raiz do projeto em um arquivo .mcp.json
Propósito: Servidores MCP específicos do projeto que só devem estar disponíveis ao trabalhar naquele projeto específico
Caso de uso: Conexões de banco de dados específicas de um projeto, linters específicos de um projeto, ou ferramentas de build personalizadas
Quando o escopo de projeto é apropriado:
- Você tem ferramentas específicas do projeto que não devem ser globais
- Você está trabalhando em equipe e quer compartilhar configurações MCP via controle de versão
- Você precisa de versões diferentes da mesma ferramenta para projetos diferentes
2. Escopo de Usuário (-scope user
) - Configuração Global
Localização: Configuração do diretório home do usuário
Propósito: Servidores MCP disponíveis globalmente em todos os projetos e diretórios
Caso de uso: Ferramentas de propósito geral como APIs de clima, ferramentas de calculadora, ou utilitários de sistema
Por que o escopo de usuário é geralmente preferido:
- Funciona de qualquer diretório no seu sistema
- Sobrevive a mudanças de diretório de projeto
- Ideal para servidores utilitários que você quer usar em qualquer lugar
3. Escopo Local (padrão) - Específico do Diretório
Localização: Contexto do diretório de trabalho atual
Propósito: Configurações rápidas e temporárias de servidor MCP
Limitação: Só funciona quando você executa o Claude Code daquele diretório específico
Erros Comuns de Configuração
❌ Abordagem errada (Escopo local - funcionalidade limitada):
claude mcp add my-server python3 /path/to/server.py
Problema: Este servidor só funciona quando você está no diretório exato onde o registrou.
✅ Abordagem correta (Escopo de usuário - acesso global):
claude mcp add --scope user my-server python3 /path/to/server.py
Benefício: Este servidor funciona de qualquer diretório no seu sistema.
Planejamento Estratégico de Diretórios
Estrutura de Diretório Recomendada
Crie uma estrutura de diretório bem organizada para manutenibilidade a longo prazo:
# Create permanent storage location
mkdir -p ~/.claude-mcp-servers/
# Organize by functionality
mkdir -p ~/.claude-mcp-servers/apis/
mkdir -p ~/.claude-mcp-servers/utilities/
mkdir -p ~/.claude-mcp-servers/development/
Benefícios da Estrutura Organizada
Manutenibilidade: Fácil de encontrar e atualizar servidores posteriormente
Segurança: Separação clara entre diferentes tipos de ferramentas
Backup: Simples fazer backup de todos os servidores MCP fazendo backup de um único diretório
Compartilhamento: Fácil compartilhar configurações de servidor com membros da equipe
Guia de Solução de Problemas de Escopo
Diagnosticando Problemas de Escopo
Se seu servidor MCP não estiver aparecendo, siga esta sequência de diagnóstico:
- Verificar a configuração do escopo atual:
claude mcp list
- Verificar se você não está em um diretório com escopo de projeto conflitante:
ls .mcp.json
- Testar a partir de diferentes diretórios:
cd ~ && claude mcp list
cd /tmp && claude mcp list
Corrigindo Problemas de Escopo
Problema: Servidor só funciona em um diretório
Solução: Remover a configuração local e adicionar novamente com escopo de usuário
# Remove problematic local configuration
claude mcp remove my-server
# Re-add with global user scope
claude mcp add --scope user my-server python3 /path/to/server.py
Construindo Seu Primeiro Servidor MCP
Entendendo o Processo de Desenvolvimento
Construir um servidor MCP envolve entender tanto o protocolo MCP quanto os requisitos específicos do seu caso de uso. Começaremos com um servidor "Hello World" básico para entender os fundamentos, e então construiremos sobre essa base.
O processo de desenvolvimento segue estas fases:
- Configuração da Estrutura do Servidor: Criando a estrutura básica de arquivos e ponto de entrada
- Implementação do Protocolo: Implementando os métodos MCP necessários
- Definição de Ferramentas: Definindo quais ferramentas seu servidor fornece
- Registro e Teste: Adicionando o servidor ao Claude Code e verificando a funcionalidade
- Aprimoramento e Produção: Adicionando funcionalidade real e tratamento de erros
Passo 1: Fundação e Estrutura do Projeto
Criando o Ambiente de Desenvolvimento
Primeiro, estabeleça um ambiente de desenvolvimento adequado para seu servidor MCP:
# Navigate to your MCP servers directory
cd ~/.claude-mcp-servers/
# Create a new server project
mkdir my-first-server
cd my-first-server
# Initialize the project structure
touch server.py
touch requirements.txt
touch .env
Por Que Esta Estrutura Importa
Desenvolvimento Organizado: Manter cada servidor em seu próprio diretório previne conflitos e facilita a manutenção.
Isolamento de Dependências: Cada servidor pode ter seus próprios requisitos sem afetar outros.
Gerenciamento de Configuração: Arquivos de ambiente permitem configuração segura sem codificar valores diretamente.
Entendendo os Requisitos do Servidor MCP
Todo servidor MCP deve implementar três métodos JSON-RPC essenciais:
initialize
: Estabelece a conexão e declara as capacidades do servidortools/list
: Retorna as ferramentas disponíveis e seus esquemastools/call
: Executa ferramentas específicas com parâmetros fornecidos
Passo 2: Implementando a Estrutura Central do Servidor
Crie um arquivo chamado server.py
com o template fundamental do servidor MCP:
#!/usr/bin/env python3
"""
Custom MCP Server for Claude Code Integration
"""
import json
import sys
import os
from typing import Dict, Any, Optional
# Ensure unbuffered output for proper MCP communication
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1)
def send_response(response: Dict[str, Any]):
"""Send a JSON-RPC response to Claude Code"""
print(json.dumps(response), flush=True)
def handle_initialize(request_id: Any) -> Dict[str, Any]:
"""Handle MCP initialization handshake"""
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "my-custom-server",
"version": "1.0.0"
}
}
}
def handle_tools_list(request_id: Any) -> Dict[str, Any]:
"""List available tools for Claude Code"""
tools = [
{
"name": "hello_world",
"description": "A simple demonstration tool",
"inputSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name to greet"
}
},
"required": ["name"]
}
}
]
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"tools": tools
}
}
def handle_tool_call(request_id: Any, params: Dict[str, Any]) -> Dict[str, Any]:
"""Execute tool calls from Claude Code"""
tool_name = params.get("name")
arguments = params.get("arguments", {})
try:
if tool_name == "hello_world":
name = arguments.get("name", "World")
result = f"Hello, {name}! Your MCP server is working perfectly."
else:
raise ValueError(f"Unknown tool: {tool_name}")
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"content": [
{
"type": "text",
"text": result
}
]
}
}
except Exception as e:
return {
"jsonrpc": "2.0",
"id": request_id,
"error": {
"code": -32603,
"message": str(e)
}
}
def main():
"""Main server loop handling JSON-RPC communication"""
while True:
try:
line = sys.stdin.readline()
if not line:
break
request = json.loads(line.strip())
method = request.get("method")
request_id = request.get("id")
params = request.get("params", {})
if method == "initialize":
response = handle_initialize(request_id)
elif method == "tools/list":
response = handle_tools_list(request_id)
elif method == "tools/call":
response = handle_tool_call(request_id, params)
else:
response = {
"jsonrpc": "2.0",
"id": request_id,
"error": {
"code": -32601,
"message": f"Method not found: {method}"
}
}
send_response(response)
except json.JSONDecodeError:
continue
except EOFError:
break
except Exception as e:
if 'request_id' in locals():
send_response({
"jsonrpc": "2.0",
"id": request_id,
"error": {
"code": -32603,
"message": f"Internal error: {str(e)}"
}
})
if __name__ == "__main__":
main()
Explicação da Arquitetura do Código
Configuração de Entrada/Saída: As primeiras linhas configuram I/O sem buffer, o que é crítico para a comunicação MCP. A saída com buffer pode causar atrasos na entrega de mensagens que quebram o protocolo.
Manipulação de JSON-RPC: O loop principal lê solicitações JSON-RPC do stdin e escreve respostas no stdout. Isso segue a especificação MCP para comunicação de servidor local.
Estratégia de Tratamento de Erros: O código implementa múltiplas camadas de tratamento de erros:
- Erros de parsing JSON (solicitações malformadas)
- Erros de método não encontrado (operações não suportadas)
- Erros de execução de ferramenta (falhas em tempo de execução)
Conformidade com o Protocolo: Cada resposta inclui o campo jsonrpc: "2.0"
necessário e o ID da solicitação para correlação adequada.
Passo 3: Preparação e Teste do Servidor
Tornando o Servidor Executável
# Make the server executable
chmod +x server.py
Por que permissões de execução importam: Servidores MCP são lançados como subprocessos pelo Claude Code. Sem permissões de execução, o lançamento falhará com erros de permissão crípticos.
Teste Manual do Protocolo
Antes de registrar com o Claude Code, teste a implementação do protocolo do servidor:
# Test the initialize handshake
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | python3 server.py
O que esperar: Você deve ver uma resposta JSON contendo a versão do protocolo e as capacidades. Se você vir mensagens de erro ou nenhuma saída, verifique sua instalação Python e a sintaxe do script.
Passos de Validação
Realize estas verificações de validação antes de prosseguir:
- Verificação de Sintaxe:
python3 -m py_compile server.py
- Teste de Importação:
python3 -c "import json, sys, os"
- Teste de Execução: Verifique se o teste manual do protocolo funciona
Passo 4: Registro com o Claude Code
Adicionando Seu Servidor
Registre seu servidor usando o escopo adequado e caminhos absolutos:
# Register with global user scope for universal access
claude mcp add --scope user my-first-server python3 ~/.claude-mcp-servers/my-first-server/server.py
Detalhes críticos:
- Use caminhos absolutos para evitar erros de "arquivo não encontrado"
- Escolha nomes de servidor descritivos para fácil identificação
- Sempre use
-scope user
para servidores de desenvolvimento
Verificação e Solução de Problemas
# Verify registration
claude mcp list
# Check for any connection issues
claude mcp get my-first-server
Problemas comuns de registro:
- Servidor não listado: Verifique o caminho do arquivo e as permissões
- Conexão falhou: Verifique a instalação Python e a sintaxe do script
- Problemas de escopo: Certifique-se de que você não está em um diretório com
.mcp.json
conflitante
Exemplo Avançado: Integração com API de Clima
Indo Além do Hello World
Agora que você entende a estrutura básica do servidor MCP, vamos construir um servidor mais prático que demonstra padrões de integração do mundo real. Este servidor de API de clima ensinará você:
- Integração com API externa com tratamento de erros adequado
- Gerenciamento de variáveis de ambiente para configuração segura
- Validação de entrada e processamento de parâmetros
- Formatação de resposta para integração ótima com o Claude Code
- Padrões de tratamento de erros prontos para produção
Planejando Sua Integração de API
Antes de escrever código, considere estes aspectos de integração:
Seleção de API: Usaremos a API OpenWeatherMap por sua simplicidade e nível gratuito
Fluxo de Dados: Solicitação do usuário → Validação de parâmetro → Chamada de API → Formatação de resposta → Resposta do Claude
Cenários de Erro: Falhas de rede, chaves de API inválidas, respostas malformadas, limitação de taxa (rate limiting)
Segurança: Chaves de API armazenadas em variáveis de ambiente, sanitização de entrada
Estratégia de Implementação
Vamos construir este servidor incrementalmente, implementando cada parte com tratamento de erros completo:
#!/usr/bin/env python3
import json
import sys
import os
import requests
from typing import Dict, Any
# Configuration - use environment variables for security
WEATHER_API_KEY = os.environ.get("OPENWEATHER_API_KEY", "your-api-key-here")
def get_weather(city: str) -> str:
"""Fetch current weather data for a specified city"""
try:
url = "<http://api.openweathermap.org/data/2.5/weather>"
params = {
"q": city,
"appid": WEATHER_API_KEY,
"units": "metric"
}
response = requests.get(url, params=params, timeout=10)
data = response.json()
if response.status_code == 200:
temp = data["main"]["temp"]
desc = data["weather"][0]["description"]
humidity = data["main"]["humidity"]
return f"Weather in {city}: {temp}°C, {desc.title()}, Humidity: {humidity}%"
else:
return f"Error fetching weather: {data.get('message', 'Unknown error')}"
except requests.RequestException as e:
return f"Network error: {str(e)}"
except Exception as e:
return f"Error processing weather data: {str(e)}"
def handle_tools_list(request_id: Any) -> Dict[str, Any]:
"""Enhanced tools list with weather functionality"""
tools = [
{
"name": "get_weather",
"description": "Get current weather conditions for any city worldwide",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name (e.g., 'London', 'Tokyo', 'New York')"
}
},
"required": ["city"]
}
}
]
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"tools": tools
}
}
def handle_tool_call(request_id: Any, params: Dict[str, Any]) -> Dict[str, Any]:
"""Enhanced tool execution with weather functionality"""
tool_name = params.get("name")
arguments = params.get("arguments", {})
try:
if tool_name == "get_weather":
city = arguments.get("city")
if not city:
raise ValueError("City name is required")
result = get_weather(city)
else:
raise ValueError(f"Unknown tool: {tool_name}")
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"content": [
{
"type": "text",
"text": result
}
]
}
}
except Exception as e:
return {
"jsonrpc": "2.0",
"id": request_id,
"error": {
"code": -32603,
"message": str(e)
}
}
# Include the same main() function and other handlers from the basic example
Recursos Avançados Explicados
Segurança de Variáveis de Ambiente: A chave de API é carregada de variáveis de ambiente, nunca codificada diretamente. Isso previne exposição acidental no controle de versão.
Tratamento Robusto de Erros: A função get_weather()
lida com múltiplos cenários de erro:
- Timeouts de rede e falhas de conexão
- Respostas de API inválidas e limitação de taxa (rate limiting)
- Dados JSON malformados
- Chaves de API ausentes ou inválidas
Esquema de Ferramenta Aprimorado: O esquema da ferramenta de clima inclui descrições detalhadas e exemplos, ajudando o Claude Code a entender como usar a ferramenta de forma eficaz.
Passo 5: Gerenciamento Profissional de Dependências e Configuração
Criando um Arquivo Requirements Adequado
requests>=2.28.0
python-dotenv>=1.0.0
Estratégia de fixação de versão: Usar requisitos de versão mínima (>=
) garante compatibilidade enquanto permite atualizações de segurança. Para servidores de produção, considere a fixação de versão exata.
Configuração Segura do Ambiente
Crie um arquivo .env
para gerenciamento de configuração:
# Weather API configuration
OPENWEATHER_API_KEY=your_actual_api_key_here
# Server configuration
MCP_LOG_LEVEL=INFO
MCP_DEBUG=false
# Optional: Rate limiting
MCP_MAX_REQUESTS_PER_MINUTE=60
Melhores práticas de segurança:
- Nunca commite arquivos
.env
para o controle de versão - Use chaves de API fortes e únicas
- Implemente limitação de taxa (rate limiting) para prevenir abuso
- Considere rotação de chave de API para uso em produção
Instalação e Isolamento de Dependências
# Create virtual environment for isolation
python3 -m venv mcp-env
source mcp-env/bin/activate # On Windows: mcp-env\\\\Scripts\\\\activate
# Install dependencies
pip install -r requirements.txt
# Verify installation
python3 -c "import requests; print('Dependencies installed successfully')"
Por que ambientes virtuais importam: O isolamento previne conflitos de dependência entre diferentes servidores MCP e a instalação Python do seu sistema.
Testando e Depurando Seu Servidor MCP
Estratégia Abrangente de Testes
Testar servidores MCP requer uma abordagem multicamadas porque você está lidando tanto com a conformidade do protocolo quanto com a correção funcional. Uma estratégia de teste sistemática previne que problemas cheguem à produção e torna a depuração muito mais fácil.
Pirâmide de Testes para Servidores MCP
- Testes Unitários: Teste de funções individuais
- Testes de Protocolo: Verificação de conformidade com JSON-RPC
- Testes de Integração: Teste de interação com o Claude Code
- Testes Fim a Fim: Validação completa do fluxo de trabalho
Camada 1: Teste Manual do Protocolo
Testando Métodos MCP Essenciais
Antes de qualquer integração, verifique se seu servidor implementa o protocolo MCP corretamente:
# Test initialization handshake
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | python3 server.py
Estrutura de resposta esperada:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "your-server", "version": "1.0.0"}
}
}
Testando a Descoberta de Ferramentas
# Test tools list endpoint
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | python3 server.py
Lista de verificação de validação:
- A resposta inclui um array
tools
- Cada ferramenta tem
name
,description
, einputSchema
- O esquema segue a especificação JSON Schema
- Todos os campos obrigatórios estão marcados no esquema
Testando a Execução de Ferramentas
# Test actual tool functionality
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"London"}}}' | python3 server.py
O que verificar:
- A ferramenta executa sem erros
- A resposta inclui um array
content
- O conteúdo tem campos
type
e data adequados - As respostas de erro incluem códigos de erro adequados
Camada 2: Framework de Teste Automatizado
Criando Scripts de Teste
Crie um arquivo test_server.py
para testes automatizados:
#!/usr/bin/env python3
import json
import subprocess
import sys
def test_mcp_method(method, params=None):
"""Test a specific MCP method"""
request = {
"jsonrpc": "2.0",
"id": 1,
"method": method,
"params": params or {}
}
try:
result = subprocess.run(
[sys.executable, "server.py"],
input=json.dumps(request),
capture_output=True,
text=True,
timeout=10
)
return json.loads(result.stdout.strip())
except Exception as e:
return {"error": str(e)}
# Test suite
tests = [
("initialize", None),
("tools/list", None),
("tools/call", {"name": "hello_world", "arguments": {"name": "Test"}})
]
for method, params in tests:
response = test_mcp_method(method, params)
print(f"Testing {method}: {'✓ PASS' if 'result' in response else '✗ FAIL'}")
Camada 3: Teste de Integração com o Claude Code
Registro e Verificação do Servidor
# Register your server
claude mcp add --scope user test-server python3 /full/path/to/server.py
# Verify registration
claude mcp list | grep test-server
# Check server health
claude mcp get test-server
Teste de Integração ao Vivo
# Start Claude Code in test mode
claude
# In Claude Code, test tool discovery
/mcp
# Test tool execution
mcp__test-server__hello_world name:"Integration Test"
Padrão de nomenclatura de ferramenta: O Claude Code prefixa as ferramentas com mcp__<nome-do-servidor>__<nome-da-ferramenta>
para evitar conflitos de nomenclatura.
Técnicas Avançadas de Depuração
Habilitando Log de Depuração
Adicione logging abrangente ao seu servidor:
import logging
import sys
# Configure logging to stderr (won't interfere with JSON-RPC)
logging.basicConfig(
level=logging.DEBUG,
stream=sys.stderr,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def handle_tool_call(request_id, params):
logger.debug(f"Received tool call: {params}")
# ... your tool logic
logger.debug(f"Tool execution completed successfully")
Análise de Logs do Servidor MCP
O Claude Code mantém logs para cada servidor MCP:
# View recent logs (macOS)
tail -f ~/Library/Logs/Claude/mcp-server-*.log
# View recent logs (Linux)
tail -f ~/.config/claude/logs/mcp-server-*.log
# Search for errors
grep -i error ~/Library/Logs/Claude/mcp-server-*.log
Padrões Comuns de Depuração
Problema: Servidor inicia, mas as ferramentas não aparecem
Diagnóstico: Verifique o formato da resposta tools/list
Solução: Valide a conformidade com o esquema JSON
Problema: Chamadas de ferramenta falham silenciosamente
Diagnóstico: Verifique o tratamento de erros em tools/call
Solução: Adicione tratamento abrangente de exceções
Problema: Conexão do servidor cai
Diagnóstico: Verifique I/O sem buffer e tratamento adequado de exceções
Solução: Verifique a configuração de sys.stdout
e o tratamento de erros no loop principal
Teste de Desempenho e Confiabilidade
Teste de Carga do Seu Servidor
# Test multiple rapid requests
for i in {1..10}; do
echo '{"jsonrpc":"2.0","id":'$i',"method":"tools/list","params":{}}' | python3 server.py &
done
wait
Monitoramento de Memória e Recursos
# Monitor server resource usage
python3 -m memory_profiler server.py
# Check for memory leaks during extended operation
python3 -m tracemalloc server.py
Solução de Problemas Comuns
Problemas em Nível de Protocolo
- Respostas JSON inválidas: Use
json.loads()
para validar a saída - Campos obrigatórios ausentes: Verifique a conformidade com a especificação MCP
- Códigos de erro incorretos: Use códigos de erro JSON-RPC padrão
Problemas de Integração
- Servidor não aparecendo: Verifique as permissões de arquivo e o caminho do Python
- Ferramentas não acessíveis: Verifique a configuração de escopo e o registro
- Falhas de autenticação: Garanta a inicialização adequada do MCP
Melhores Práticas e Considerações de Segurança
Tratamento de Erros Pronto para Produção
Implementando Validação Robusta
O tratamento de erros em servidores MCP deve ser abrangente porque falhas podem quebrar toda a cadeia de comunicação com o Claude Code. Implemente validação em múltiplos níveis:
def validate_arguments(arguments: Dict[str, Any], required: List[str]):
"""Validate required arguments are present"""
missing = [field for field in required if field not in arguments]
if missing:
raise ValueError(f"Missing required fields: {', '.join(missing)}")
def handle_tool_call(request_id: Any, params: Dict[str, Any]) -> Dict[str, Any]:
"""Tool execution with proper validation"""
try:
tool_name = params.get("name")
arguments = params.get("arguments", {})
# Validate before processing
if tool_name == "get_weather":
validate_arguments(arguments, ["city"])
# Process tool logic here
except ValueError as ve:
return create_error_response(request_id, -32602, str(ve))
except Exception as e:
return create_error_response(request_id, -32603, f"Internal error: {str(e)}")
Padrões de Resposta de Erro
Siga as convenções de código de erro JSON-RPC 2.0:
- 32700: Erro de parsing (JSON inválido)
- 32600: Solicitação inválida (objeto de solicitação malformado)
- 32601: Método não encontrado (método MCP não suportado)
- 32602: Parâmetros inválidos (parâmetros errados para a ferramenta)
- 32603: Erro interno (falha na execução do lado do servidor)
Framework de Segurança Abrangente
1. Gerenciamento de Segredos
Nunca codifique informações sensíveis diretamente. Use uma abordagem em camadas para a configuração:
import os
from pathlib import Path
def load_config():
"""Load configuration with fallback hierarchy"""
# 1. Environment variables (highest priority)
api_key = os.environ.get("API_KEY")
# 2. Local .env file
if not api_key:
env_path = Path(".env")
if env_path.exists():
# Load from .env file
pass
# 3. System keyring (production)
if not api_key:
try:
import keyring
api_key = keyring.get_password("mcp-server", "api_key")
except ImportError:
pass
if not api_key:
raise ValueError("API key not found in any configuration source")
return {"api_key": api_key}
2. Sanitização e Validação de Entrada
Implemente validação de entrada rigorosa para prevenir ataques de injeção:
import re
from typing import Any, Dict
def sanitize_string_input(value: str, max_length: int = 100) -> str:
"""Sanitize string inputs"""
if not isinstance(value, str):
raise ValueError("Expected string input")
# Remove potentially dangerous characters
sanitized = re.sub(r'[<>"\\\\']', '', value)
# Limit length to prevent DoS
if len(sanitized) > max_length:
raise ValueError(f"Input too long (max {max_length} characters)")
return sanitized.strip()
def validate_city_name(city: str) -> str:
"""Validate city name input"""
sanitized = sanitize_string_input(city, 50)
# Allow only letters, spaces, and common punctuation
if not re.match(r'^[a-zA-Z\\\\s\\\\-\\\\.]+$', sanitized):
raise ValueError("Invalid city name format")
return sanitized
3. Limitação de Taxa e Proteção de Recursos
Implemente limitação de taxa para prevenir abuso:
import time
from collections import defaultdict
from threading import Lock
class RateLimiter:
def __init__(self, max_requests: int = 60, window_seconds: int = 60):
self.max_requests = max_requests
self.window_seconds = window_seconds
self.requests = defaultdict(list)
self.lock = Lock()
def allow_request(self, client_id: str = "default") -> bool:
"""Check if request is allowed under rate limit"""
now = time.time()
with self.lock:
# Clean old requests
self.requests[client_id] = [
req_time for req_time in self.requests[client_id]
if now - req_time < self.window_seconds
]
# Check limit
if len(self.requests[client_id]) >= self.max_requests:
return False
# Record this request
self.requests[client_id].append(now)
return True
# Global rate limiter instance
rate_limiter = RateLimiter()
Logging e Monitoramento Avançados
Implementação de Logging Estruturado
Use logging estruturado para melhor depuração e monitoramento:
import logging
import json
import sys
from datetime import datetime
class MCPFormatter(logging.Formatter):
"""Custom formatter for MCP server logs"""
def format(self, record):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"level": record.levelname,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName,
}
# Add extra context if available
if hasattr(record, 'tool_name'):
log_entry["tool_name"] = record.tool_name
if hasattr(record, 'request_id'):
log_entry["request_id"] = record.request_id
return json.dumps(log_entry)
# Configure structured logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(MCPFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
Monitoramento de Desempenho
Rastreie métricas de desempenho do servidor:
import time
import statistics
from collections import deque
class PerformanceMonitor:
def __init__(self, max_samples: int = 1000):
self.response_times = deque(maxlen=max_samples)
self.error_count = 0
self.request_count = 0
def record_request(self, duration: float, success: bool):
"""Record request metrics"""
self.request_count += 1
self.response_times.append(duration)
if not success:
self.error_count += 1
def get_stats(self) -> Dict[str, Any]:
"""Get current performance statistics"""
if not self.response_times:
return {"no_data": True}
return {
"total_requests": self.request_count,
"error_rate": self.error_count / self.request_count,
"avg_response_time": statistics.mean(self.response_times),
"p95_response_time": statistics.quantiles(self.response_times, n=20)[18],
"p99_response_time": statistics.quantiles(self.response_times, n=100)[98]
}
# Global performance monitor
perf_monitor = PerformanceMonitor()
Estratégias de Implantação e Manutenção
Gerenciamento de Versão
Implemente versionamento adequado para seus servidores MCP:
__version__ = "1.2.3"
__mcp_version__ = "2024-11-05"
def get_server_info():
"""Return server information for MCP initialize"""
return {
"name": "my-production-server",
"version": __version__,
"mcp_protocol_version": __mcp_version__,
"capabilities": ["tools", "resources"], # Declare what you support
}
Implementação de Verificação de Saúde (Health Check)
Adicione capacidades de verificação de saúde para monitoramento:
def handle_health_check(request_id: Any) -> Dict[str, Any]:
"""Health check endpoint for monitoring"""
try:
# Test core functionality
test_db_connection() # Example health check
test_external_apis() # Example health check
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"status": "healthy",
"timestamp": datetime.utcnow().isoformat(),
"version": __version__,
"uptime_seconds": time.time() - start_time,
"performance": perf_monitor.get_stats()
}
}
except Exception as e:
return {
"jsonrpc": "2.0",
"id": request_id,
"result": {
"status": "unhealthy",
"error": str(e),
"timestamp": datetime.utcnow().isoformat()
}
}
Manipulação de Desligamento Gratuito (Graceful Shutdown)
Implemente limpeza adequada no desligamento do servidor:
import signal
import sys
class MCPServer:
def __init__(self):
self.running = True
self.active_requests = set()
# Register signal handlers
signal.signal(signal.SIGINT, self.shutdown_handler)
signal.signal(signal.SIGTERM, self.shutdown_handler)
def shutdown_handler(self, signum, frame):
"""Handle graceful shutdown"""
logger.info(f"Received signal {signum}, initiating graceful shutdown")
self.running = False
# Wait for active requests to complete
timeout = 30 # seconds
start_time = time.time()
while self.active_requests and (time.time() - start_time) < timeout:
time.sleep(0.1)
logger.info("Shutdown complete")
sys.exit(0)
Casos de Uso do Mundo Real e Aplicações Avançadas
Padrões de Integração Empresarial
Servidores MCP se destacam em ambientes empresariais onde o Claude Code precisa integrar-se com sistemas de negócio existentes. Aqui estão padrões de integração comprovados:
Servidores de Integração de Banco de Dados
- Consulta de dados de cliente: Consultar sistemas CRM por informações de cliente
- Gerenciamento de estoque: Verificação e atualização em tempo real do nível de estoque
- Dashboards de análise: Gerar relatórios de sistemas de business intelligence
- Criação de trilha de auditoria: Registrar decisões assistidas por IA para conformidade
Automação de Fluxo de Trabalho de Desenvolvimento
- Integração de pipeline CI/CD: Acionar builds, implantações e testes
- Análise de qualidade de código: Integrar com SonarQube, ESLint, ou linters personalizados
- Geração de documentação: Gerar automaticamente documentação de API a partir de anotações de código
- Rastreamento de issues: Criar, atualizar e consultar issues Jira/GitHub
Monitoramento e Operações de Sistema
- Monitoramento de infraestrutura: Consultar Prometheus, Grafana, ou métricas personalizadas
- Análise de logs: Buscar e analisar logs de aplicação
- Otimização de desempenho: Identificar gargalos e sugerir melhorias
- Escaneamento de segurança: Integrar com scanners de vulnerabilidade e ferramentas de segurança
Padrões de Arquitetura Avançada
Orquestração Multi-Servidor
Para fluxos de trabalho complexos, projete servidores MCP que se coordenam entre si:
# Server coordination pattern
def coordinate_workflow(workflow_id: str, steps: List[Dict]) -> Dict:
"""Coordinate multi-step workflow across servers"""
results = {}
for step in steps:
server_name = step["server"]
tool_name = step["tool"]
params = step["params"]
# Call other MCP server through Claude Code
result = call_mcp_tool(server_name, tool_name, params)
results[step["id"]] = result
# Handle dependencies between steps
if step.get("depends_on"):
inject_dependencies(params, results, step["depends_on"])
return {"workflow_id": workflow_id, "results": results}
Cache e Otimização de Desempenho
Implemente cache inteligente para dados frequentemente solicitados:
import hashlib
import pickle
from datetime import datetime, timedelta
class IntelligentCache:
def __init__(self, default_ttl: int = 3600):
self.cache = {}
self.default_ttl = default_ttl
def get_cache_key(self, tool_name: str, params: Dict) -> str:
"""Generate consistent cache key"""
key_data = f"{tool_name}:{json.dumps(params, sort_keys=True)}"
return hashlib.md5(key_data.encode()).hexdigest()
def get(self, tool_name: str, params: Dict) -> Optional[Any]:
"""Get cached result if valid"""
key = self.get_cache_key(tool_name, params)
if key in self.cache:
data, expiry = self.cache[key]
if datetime.now() < expiry:
return data
else:
del self.cache[key]
return None
def set(self, tool_name: str, params: Dict, result: Any, ttl: Optional[int] = None):
"""Cache result with TTL"""
key = self.get_cache_key(tool_name, params)
expiry = datetime.now() + timedelta(seconds=ttl or self.default_ttl)
self.cache[key] = (result, expiry)
Estratégias de Implantação em Produção
Implantação Containerizada
Empacote seu servidor MCP como um contêiner Docker para implantação consistente:
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \\\\
curl \\\\
&& rm -rf /var/lib/apt/lists/*
# Copy and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY server.py .
COPY config/ ./config/
# Create non-root user
RUN useradd -m -s /bin/bash mcpuser
USER mcpuser
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\\\
CMD python3 -c "import requests; requests.get('<http://localhost:8080/health>')"
CMD ["python3", "server.py"]
Implantação em Kubernetes
Implante servidores MCP em Kubernetes para escalabilidade e confiabilidade:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-weather-server
spec:
replicas: 3
selector:
matchLabels:
app: mcp-weather-server
template:
metadata:
labels:
app: mcp-weather-server
spec:
containers:
- name: mcp-server