This website uses cookies

Read our Privacy policy and Terms of use for more information.

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ógicos

  • get_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:

  1. Resources: Dados similares a arquivos que podem ser lidos pelos clientes (como respostas de APIs ou conteúdo de arquivos)

  2. Tools: Funções que podem ser chamadas pelo LLM (com aprovação do usuário)

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

  1. O cliente envia sua pergunta para o Claude

  2. Claude analisa as ferramentas disponíveis e decide qual(is) usar

  3. O cliente executa a(s) ferramenta(s) escolhida(s) através do servidor MCP

  4. Os resultados são enviados de volta para o Claude

  5. Claude formula uma resposta em linguagem natural

  6. A resposta é exibida para você

Troubleshooting comum

Servidor não aparece no Claude

  1. Verifique a sintaxe do arquivo claude_desktop_config.json

  2. Certifique-se de que o caminho para seu projeto é absoluto, não relativo

  3. 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.log contém logging geral sobre conexões MCP

  • Arquivos nomeados mcp-server-SERVERNAME.log contê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:

  1. Verifique os logs do Claude para erros

  2. Verifique se seu servidor compila e executa sem erros

  3. 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.

Veja outros artigos

Mais artigos
caret-right