- Data Hackers Newsletter
- Posts
- Como criar seu próprio servidor de MCP
Como criar seu próprio servidor de MCP
Um guia prático para construir seu primeiro servidor Model Context Protocol (MCP) do zero e conectá-lo ao Claude for Desktop
Como criar seu próprio servidor de MCP
Construir seu próprio servidor Model Context Protocol (MCP) pode parecer intimidador no início, mas este guia vai mostrar que é mais simples do que você imagina. Vamos criar um servidor de previsão do tempo passo a passo e conectá-lo ao Claude for Desktop.
O que vamos construir
Nosso servidor de exemplo vai expor duas ferramentas principais:
get_alerts: Para buscar alertas meteorológicosget_forecast: Para obter previsões do tempo
Embora este tutorial use o Claude for Desktop como cliente MCP para simplificar, vale lembrar que servidores MCP podem se conectar a qualquer cliente compatível. A comunidade já desenvolveu diversos clientes alternativos, e você pode até mesmo construir o seu próprio.
Conceitos fundamentais do MCP
Antes de começarmos, é importante entender os três tipos principais de capacidades que servidores MCP podem fornecer:
Resources: Dados similares a arquivos que podem ser lidos pelos clientes (como respostas de APIs ou conteúdo de arquivos)
Tools: Funções que podem ser chamadas pelo LLM (com aprovação do usuário)
Prompts: Templates pré-escritos que ajudam usuários a realizar tarefas específicas
Nosso foco neste tutorial será principalmente em tools (ferramentas).
Escolha sua linguagem de programação
O MCP suporta múltiplas linguagens de programação. Neste tutorial, vamos focar em Python e TypeScript, mas você também pode usar Java, Kotlin, C# ou Rust. Escolha a linguagem com a qual você se sente mais confortável.
Configurando o ambiente (Python)
Requisitos do sistema:
Python 3.10 ou superior
Python MCP SDK 1.2.0 ou superior
Importante sobre logging em servidores MCP
Para servidores baseados em STDIO, nunca escreva para stdout. Isso vai corromper as mensagens JSON-RPC e quebrar seu servidor. A função print() escreve para stdout por padrão, mas pode ser usada com segurança especificando file=sys.stderr.
Para servidores baseados em HTTP, logging padrão de saída é aceitável, pois não interfere com as respostas HTTP.
Instalando as dependências
Primeiro, vamos instalar o uv e configurar nosso projeto Python:
macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows:
Baixe o instalador do site oficial do uv.
Após a instalação, reinicie seu terminal e execute:
# Criar diretório para o projeto
uv init weather
cd weather
# Criar ambiente virtual e ativá-lo
uv venv
source .venv/bin/activate # No Windows: .venv\Scripts\activate
# Instalar dependências
uv add "mcp[cli]" httpx
# Criar arquivo do servidor
touch weather.py
Construindo o servidor
Importando pacotes e configurando a instância
Adicione ao topo do seu arquivo weather.py:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Inicializar servidor FastMCP
mcp = FastMCP("weather")
# Constantes
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
A classe FastMCP usa type hints do Python e docstrings para gerar automaticamente definições de ferramentas, facilitando a criação e manutenção de tools MCP.
Funções auxiliares
Vamos adicionar funções auxiliares para consultar e formatar dados da API do National Weather Service:
async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Fazer uma requisição para a API NWS com tratamento de erros apropriado."""
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
def format_alert(feature: dict) -> str:
"""Formatar um alerta em uma string legível."""
props = feature["properties"]
return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""
Implementando a execução das ferramentas
O handler de execução de ferramentas é responsável por executar a lógica de cada tool:
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Obter alertas meteorológicos para um estado dos EUA.
Args:
state: Código de duas letras do estado dos EUA (ex: CA, NY)
"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Não foi possível buscar alertas ou nenhum alerta encontrado."
if not data["features"]:
return "Nenhum alerta ativo para este estado."
alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts)
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Obter previsão do tempo para uma localização.
Args:
latitude: Latitude da localização
longitude: Longitude da localização
"""
# Primeiro, obter o endpoint da grade de previsão
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url)
if not points_data:
return "Não foi possível buscar dados de previsão para esta localização."
# Obter a URL de previsão da resposta de pontos
forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url)
if not forecast_data:
return "Não foi possível buscar previsão detalhada."
# Formatar os períodos em uma previsão legível
periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]: # Mostrar apenas os próximos 5 períodos
forecast = f"""
{period["name"]}:
Temperature: {period["temperature"]}°{period["temperatureUnit"]}
Wind: {period["windSpeed"]} {period["windDirection"]}
Forecast: {period["detailedForecast"]}
"""
forecasts.append(forecast)
return "\n---\n".join(forecasts)
Executando o servidor
Por fim, vamos inicializar e executar o servidor:
def main():
# Inicializar e executar o servidor
mcp.run(transport="stdio")
if __name__ == "__main__":
main()
Seu servidor está completo! Execute uv run weather.py para iniciar o servidor MCP, que ficará aguardando mensagens de hosts MCP.
Testando com Claude for Desktop
Instalação e configuração
Primeiro, certifique-se de ter o Claude for Desktop instalado e atualizado para a versão mais recente. Você pode baixá-lo em claude.ai/download.
Nota: Claude for Desktop ainda não está disponível para Linux. Usuários Linux podem prosseguir para construir um cliente MCP próprio.
Configurando o servidor
Abra o arquivo de configuração do Claude for Desktop em ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\Claude\claude_desktop_config.json (Windows). Crie o arquivo se ele não existir.
Por exemplo, usando VS Code:
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
Adicione seu servidor na chave mcpServers:
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/CAMINHO/ABSOLUTO/PARA/PASTA/weather",
"run",
"weather.py"
]
}
}
}
Importante: Use sempre o caminho absoluto para seu servidor. Você pode obtê-lo executando pwd no macOS/Linux ou cd no Windows Command Prompt. No Windows, use barras duplas (\\) ou barras normais (/) no caminho JSON.
Salve o arquivo e reinicie completamente o Claude for Desktop:
Windows: Clique com o botão direito no ícone do Claude na bandeja do sistema e selecione "Sair"
macOS: Use Cmd+Q ou selecione "Quit Claude" na barra de menu
Simplesmente fechar a janela não encerra completamente a aplicação.
Testando o servidor
Após reiniciar o Claude for Desktop, procure pelo ícone "Add files, connectors, and more /" na interface. Clique no ícone de mais (+) e passe o mouse sobre o menu "Connectors". Você deve ver o servidor weather listado.
Agora teste seu servidor com comandos como:
"Qual é a previsão do tempo em Sacramento?"
"Quais são os alertas meteorológicos ativos no Texas?"
Nota: Como estamos usando o National Weather Service dos EUA, as consultas funcionarão apenas para localizações americanas.
Como funciona por baixo dos panos
Quando você faz uma pergunta:
O cliente envia sua pergunta para o Claude
Claude analisa as ferramentas disponíveis e decide qual(is) usar
O cliente executa a(s) ferramenta(s) escolhida(s) através do servidor MCP
Os resultados são enviados de volta para o Claude
Claude formula uma resposta em linguagem natural
A resposta é exibida para você
Troubleshooting comum
Servidor não aparece no Claude
Verifique a sintaxe do arquivo
claude_desktop_config.jsonCertifique-se de que o caminho para seu projeto é absoluto, não relativo
Reinicie o Claude for Desktop completamente
Obtendo logs do Claude for Desktop
Os logs relacionados ao MCP são gravados em ~/Library/Logs/Claude:
mcp.logcontém logging geral sobre conexões MCPArquivos nomeados
mcp-server-SERVERNAME.logcontêm logs de erro do servidor específico
Execute o seguinte comando para visualizar logs recentes:
tail -n 20 -f ~/Library/Logs/Claude/mcp*.log
Chamadas de ferramentas falham silenciosamente
Se o Claude tenta usar as ferramentas mas elas falham:
Verifique os logs do Claude para erros
Verifique se seu servidor compila e executa sem erros
Tente reiniciar o Claude for Desktop
Próximos passos
Agora que você construiu seu primeiro servidor MCP, aqui estão algumas sugestões para continuar:
Construa um cliente MCP: Aprenda a criar seu próprio cliente que pode se conectar ao seu servidor
Explore servidores de exemplo: Confira a galeria de servidores MCP oficiais e implementações da comunidade
Aprenda debugging avançado: Domine técnicas de debugging para servidores MCP
Use LLMs para acelerar o desenvolvimento: Aprenda a usar Claude e outros LLMs para construir servidores MCP mais rapidamente
Recursos adicionais
Recurso | Descrição |
|---|---|
SDK Python | Documentação completa do SDK MCP para Python |
SDK TypeScript | Guias e referências para desenvolvimento em TypeScript |
Especificação MCP | Documentação técnica completa do protocolo |
Comunidade | Fórum da comunidade para tirar dúvidas e compartilhar projetos |
Conclusão
Você acabou de construir seu primeiro servidor MCP funcional! Este é apenas o começo - o Model Context Protocol abre um mundo de possibilidades para integrar LLMs com ferramentas e dados externos. Continue experimentando, construindo e compartilhando suas criações com a comunidade.
Lembre-se: a melhor maneira de aprender é construindo. Experimente adicionar novas ferramentas ao seu servidor, conecte-se a outras APIs, e explore as capacidades completas do MCP.