Como Construir Seu Primeiro Servidor MCP: Tutorial Passo a Passo

Pré-requisitos
Antes de começar, certifique-se de ter o seguinte preparado:
- Python 3.10 ou superior instalado.
- Conhecimento básico de funções Python e código assíncrono.
- uv (gerenciador de pacotes Python rápido) – instale com
curl -LsSf https://astral.sh/uv/install.sh | sh. - Um cliente MCP como Claude Desktop (baixe em claude.ai/download e mantenha-o atualizado).
- Um editor de texto ou IDE.
Não é necessária experiência prévia com MCP. Vamos construir um servidor MCP de clima prático que permite à IA consultar alertas meteorológicos em tempo real e previsões dos EUA via API do National Weather Service.
Passo和被 1: Configurar o Ambiente
Crie um diretório de projeto limpo e inicialize-o com uv:
mkdir weather-mcp-server
cd weather-mcp-server
uv init
uv venv
source .venv/bin/activate # No Windows: .venv\Scripts\activate
uv add "mcp[cli]" httpx
Isso instala o SDK Python oficial do MCP (FastMCP) e httpx para chamadas de API. Seu projeto agora tem um pyproject.toml e um ambiente virtual.
Resultado esperado: Uma nova pasta .venv e dependências listadas em uv.lock.
Passo 2: Criar o Código do Servidor MCP
Crie o arquivo principal:
touch weather.py
Cole este código completo e pronto para execução em weather.py:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Inicializar o servidor MCP
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
# Função auxiliar para chamar a API NWS com segurança
async def make_nws_request(url: str) -> dict[str, Any] | None:
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
# Formatar alertas meteorológicos de forma organizada para a IA
def format_alert(feature: dict) -> str:
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")}
"""
# Ferramenta 1: Obter alertas meteorológicos ativos para um estado dos EUA
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get current weather alerts for a U.S. state (e.g., "CA" or "TX")."""
url = f"{NWS_API_BASE}/alerts/active/area/{state.upper()}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return f"No active alerts for {state.upper()}."
alerts = [format_alert(f) for f in data["features"]]
return "\n---\n".join(alerts)
Ferramenta 2: Obter previsão de 5 dias para qualquer lat/long
@mcp.tool() async def get_forecast(latitude: float, longitude: float) -> str: """Obter previsão do tempo para uma latitude e longitude específicas.""" 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." 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 a previsão detalhada." periods = forecast_data["properties"]["periods"][:5] forecasts = [] for period in periods: forecast = f""" {period["name"]}: Temperatura: {period["temperature"]}°{period["temperatureUnit"]} Vento: {period["windSpeed"]} {period["windDirection"]} Previsão: {period["detailedForecast"]} """ forecasts.append(forecast) return "\n---\n".join(forecasts)
def main(): mcp.run(transport="stdio")
if name == "main": main()
**Conceitos-chave explicados:**
- Os decoradores `@mcp.tool()` transformam funções assíncronas regulares em ferramentas MCP que a IA pode descobrir e chamar.
- O servidor é executado via **stdio** (entrada/saída padrão) – o padrão para servidores MCP locais.
- Todos os logs devem ir para stderr (o FastMCP lida com isso automaticamente).
## Etapa移动到apa 3: Testar o Servidor Localmente
Execute o servidor:
```bash
uv run weather.py
Saída esperada: O terminal permanece aberto e em silêncio (isso é normal para servidores stdio). Você verá mensagens JSON-RPC apenas quando um cliente MCP se conectar.
Deixe este terminal em execução para a próxima etapa.
Etapa 4: Conectar o Servidor MCP ao Claude Desktop
- Abra o Claude Desktop.
- Crie ou edite o arquivo de configuração em:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
Adicione esta entrada exata (substitua /CAMINHO/ABSOLUTO/PARA/weather-mcp-server pelo caminho real da sua pasta):
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/CAMINHO/ABSOLUTO/PARA/weather-mcp-server",
"run",
"weather.py"
]
}
}
}
- Feche completamente o Claude Desktop (Cmd+Q no macOS ou feche pela bandeja do sistema no Windows) e reinicie-o.
- No Claude, clique em “Add files, connectors, and more” → passe o mouse sobre Connectors → você deve ver “weather” listado.
Etapa 5: Usar Seu Servidor MCP com IA
Experimente estes prompts no Claude Desktop:
- “Quais são os alertas climáticos ativos no Texas?”
- “Me dê a previsão para São Francisco (use lat 37.77, long -122.41).”
- “Verifique alertas na Califórnia e me diga se preciso me preparar para algo.”
O Claude descobrirá automaticamente as ferramentas, solicitará sua aprovação na primeira vez e retornará resultados formatados.
Comportamento esperado: A IA chama suas ferramentas nos bastidores e mostra respostas em linguagem natural.
Problemas Comuns e Solução de Problemas
-
Servidor não aparece no Claude:
- Verifique novamente se o JSON é válido (sem vírgulas no final).
- Use um caminho absoluto na configuração.
- Reinicie o Claude completamente.
- Verifique os logs:
~/Library/Logs/Claude/mcp*.log(macOS) ou equivalente no Windows.
-
Erros de API ou sem dados:
- A API NWS só funciona para locais nos EUA.
- Use códigos de estado de duas letras (CA, TX, etc.).
- As coordenadas devem ser lat/long válidas.
-
“Comando não encontrado”:
- Certifique-se de que o uv está no seu PATH e o ambiente virtual está ativado.
- Execute
uv --versionpara verificar a instalação.
-
Timeout ou resposta lenta:
- Aumente o timeout em
make_nws_requestse necessário. - A NWS tem limites de taxa – evite spam em produção.
- Aumente o timeout em
-
Problemas de permissão:
- No macOS, conceda ao Claude Desktop acesso total ao disco em Configurações do Sistema → Privacidade e Segurança.
Próximos Passos
- Adicione mais ferramentas: Crie ferramentas para bancos de dados, GitHub, Slack ou suas próprias APIs usando o mesmo padrão
@mcp.tool(). - Adicione recursos e prompts: Use
mcp.resource()emcp.prompt()para dados tipo arquivo e instruções reutilizáveis. - Implante remotamente: Mude para transporte HTTP/SSE e hospede no AWS Lambda, Vercel ou qualquer servidor (o FastMCP suporta
stateless_http=True). - Suporte a múltiplas linguagens: Experimente os SDKs oficiais TypeScript, Go ou Rust para a mesma funcionalidade.
- Compartilhe seu servidor: Publique o repositório para que outros possam adicioná-lo via
npxou Docker.
Agora você tem um servidor MCP totalmente funcional que qualquer cliente de IA compatível pode usar. Experimente, estenda as ferramentas e comece a construir integrações poderosas de IA hoje!