Como Criar um Servidor MCP Rápido para Claude Code

Audrey Lopez

Audrey Lopez

12 junho 2025

Como Criar um Servidor MCP Rápido para Claude Code

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 ótima ferramenta de Teste de API que gera Documentação de API bonita?

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!
botão

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:

Fluxo de Comunicação Explicado

Quando o Claude Code precisa usar uma ferramenta externa, veja o que acontece:

  1. Fase de Descoberta: O Claude Code consulta seu servidor por ferramentas disponíveis
  2. Validação de Esquema: Seu servidor responde com definições de ferramentas e esquemas de entrada
  3. Seleção de Ferramenta: O Claude Code escolhe ferramentas apropriadas com base nas solicitações do usuário
  4. Fase de Execução: O Claude Code envia chamadas de ferramenta com parâmetros validados
  5. 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:

Para Desenvolvimento TypeScript/JavaScript:

Dependências Essenciais:

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:

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:

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:

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:

  1. Verificar a configuração do escopo atual:
claude mcp list

  1. Verificar se você não está em um diretório com escopo de projeto conflitante:
ls .mcp.json

  1. 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:

  1. Configuração da Estrutura do Servidor: Criando a estrutura básica de arquivos e ponto de entrada
  2. Implementação do Protocolo: Implementando os métodos MCP necessários
  3. Definição de Ferramentas: Definindo quais ferramentas seu servidor fornece
  4. Registro e Teste: Adicionando o servidor ao Claude Code e verificando a funcionalidade
  5. 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:

  1. initialize: Estabelece a conexão e declara as capacidades do servidor
  2. tools/list: Retorna as ferramentas disponíveis e seus esquemas
  3. tools/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:

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:

  1. Verificação de Sintaxe: python3 -m py_compile server.py
  2. Teste de Importação: python3 -c "import json, sys, os"
  3. 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:

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:

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ê:

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:

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:

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

  1. Testes Unitários: Teste de funções individuais
  2. Testes de Protocolo: Verificação de conformidade com JSON-RPC
  3. Testes de Integração: Teste de interação com o Claude Code
  4. 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:

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:

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

  1. Respostas JSON inválidas: Use json.loads() para validar a saída
  2. Campos obrigatórios ausentes: Verifique a conformidade com a especificação MCP
  3. Códigos de erro incorretos: Use códigos de erro JSON-RPC padrão

Problemas de Integração

  1. Servidor não aparecendo: Verifique as permissões de arquivo e o caminho do Python
  2. Ferramentas não acessíveis: Verifique a configuração de escopo e o registro
  3. 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:

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

Automação de Fluxo de Trabalho de Desenvolvimento

Monitoramento e Operações de Sistema

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

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs