MÓDULO 3.4

🔢 Server de Calculadora

Construa um server com 4 operações matemáticas — seu primeiro server multi-tool com validação de entrada.

6
Tópicos
35
Minutos
Intermediário
Nível
Prático
Tipo
1

🎯 Planejando as Tools

Antes de escrever qualquer código, vamos planejar nosso server de calculadora. A ideia é criar quatro tools matemáticas básicas: somar, subtrair, multiplicar e dividir. Cada uma receberá dois números de ponto flutuante (float) como parâmetros e retornará o resultado da operação. Este será o seu primeiro server com múltiplas tools — um passo importante na construção de servers MCP mais complexos.

💎 Conceito Principal

Nosso server terá 4 tools, todas seguindo o mesmo padrão de assinatura:

somar(a: float, b: float) → float

subtrair(a: float, b: float) → float

multiplicar(a: float, b: float) → float

dividir(a: float, b: float) → float # com validação de b != 0

Todas recebem dois floats e retornam um float. A exceção é a divisão, que precisa validar se o divisor é zero antes de executar a operação. Esse padrão consistente facilita tanto a implementação quanto o uso pelo modelo de IA.

💡 Dica Prática

Planejar as tools antes de codificar é uma boa prática essencial. Defina o nome, os parâmetros (com tipos) e o retorno de cada tool. Isso garante consistência, facilita a documentação automática gerada pelo FastMCP e ajuda o modelo de IA a entender quando e como usar cada ferramenta. Pense nas tools como uma API — quanto mais previsível, melhor.

2

➕ Soma e Subtração

Vamos começar pelas operações mais simples: soma e subtração. São tools diretas, sem necessidade de validação especial. Elas servem como base para entender o padrão que será repetido nas demais operações. Com o FastMCP, cada tool é apenas uma função Python decorada — simples assim.

💎 Conceito Principal

# server_calculadora.py

from mcp.server.fastmcp import FastMCP


mcp = FastMCP("Calculadora")


@mcp.tool()

def somar(a: float, b: float) -> float:

"""Soma dois números."""

return a + b


@mcp.tool()

def subtrair(a: float, b: float) -> float:

"""Subtrai b de a."""

return a - b

Note como os type hints (a: float, b: float) são fundamentais. O FastMCP usa essas anotações para gerar automaticamente o schema JSON que o cliente MCP envia ao modelo. Sem type hints, o modelo não sabe que tipo de dado enviar.

💡 Dica Prática

Sempre escreva docstrings nas suas tools. A docstring vira a descrição da tool no schema MCP — é ela que o modelo lê para decidir qual tool usar. Uma docstring clara como "Soma dois números" é muito melhor do que não ter docstring nenhuma.

📊 Dados e Pesquisa

O FastMCP converte automaticamente os type hints Python em JSON Schema. Um parâmetro float vira {"type": "number"} no schema. Um str vira {"type": "string"}. Essa conversão automática elimina a necessidade de escrever schemas manualmente — basta anotar as funções Python corretamente e o FastMCP cuida do resto.

3

✖️ Multiplicação

A tool de multiplicação segue exatamente o mesmo padrão das anteriores. Isso é intencional — manter consistência entre as tools facilita a vida do desenvolvedor e do modelo. Aqui também é uma boa oportunidade para entender como o FastMCP gera o schema automaticamente a partir da sua função Python.

💎 Conceito Principal

@mcp.tool()

def multiplicar(a: float, b: float) -> float:

"""Multiplica dois números."""

return a * b

Quando o FastMCP registra essa tool, ele gera automaticamente um schema como: {"name": "multiplicar", "description": "Multiplica dois números.", "inputSchema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]}}. Tudo isso a partir de uma simples função Python com type hints e docstring.

❌ Evitar
  • Funções sem type hints (o schema fica vazio)
  • Funções sem docstring (sem descrição para o modelo)
  • Nomes genéricos como "calcular" ou "func1"
  • Misturar lógica de negócio com formatação
✅ Fazer
  • Type hints em todos os parâmetros e retorno
  • Docstrings claras e descritivas
  • Nomes específicos: somar, subtrair, multiplicar
  • Uma responsabilidade por tool
4

➗ Divisão com Validação

A divisão é diferente das demais operações porque tem um caso especial perigoso: a divisão por zero. Se o usuário pedir para dividir qualquer número por zero e a tool simplesmente executar a / b, o Python lançará um ZeroDivisionError e o server pode crashar. Precisamos validar a entrada antes de executar a operação.

💎 Conceito Principal

@mcp.tool()

def dividir(a: float, b: float) -> str:

"""Divide a por b. Retorna erro se b for zero."""

if b == 0:

return "Erro: divisão por zero não é permitida."

return f"{a / b}"

Ao invés de deixar a exceção estourar, retornamos uma mensagem de erro amigável como string. O modelo recebe essa mensagem e pode informar o usuário de forma natural: "Não é possível dividir por zero." Isso é muito melhor do que um traceback Python incompreensível.

🚨 Alerta

Nunca deixe uma tool crashar! Uma exceção não tratada pode derrubar o server MCP inteiro, desconectando o cliente. Sempre valide entradas, use try/except quando necessário, e retorne mensagens de erro claras. O modelo sabe lidar com mensagens de erro — ele não sabe lidar com um server que parou de responder.

❌ Evitar
  • Deixar exceções propagarem sem tratamento
  • Retornar tracebacks Python como resposta
  • Ignorar casos extremos (zero, None, etc.)
  • Confiar que o modelo sempre envia dados válidos
✅ Fazer
  • Validar entradas antes de processar
  • Retornar mensagens de erro amigáveis
  • Usar try/except para erros inesperados
  • Testar com inputs inválidos propositalmente
5

🧪 Testando Todas as Tools

Com as 4 tools implementadas, é hora de configurar o server no Claude Desktop e testar cada operação. O objetivo é verificar que o Claude identifica corretamente qual tool usar para cada pergunta e que todas as operações retornam resultados corretos — incluindo o tratamento de divisão por zero.

💎 Conceito Principal

Adicione o server ao claude_desktop_config.json e reinicie o Claude Desktop. Depois, não se esqueça de adicionar o bloco de inicialização ao final do arquivo:

if __name__ == "__main__":

mcp.run()

Agora teste as tools com perguntas naturais. O Claude vai escolher automaticamente a tool correta para cada operação.

📋 Sequência de testes recomendada
Teste 1 — Soma

"Quanto é 15 + 27?" — O Claude deve usar a tool somar e retornar 42.

Teste 2 — Subtração

"Qual é 100 menos 37?" — O Claude deve usar subtrair e retornar 63.

Teste 3 — Multiplicação

"Multiplique 8 por 7." — O Claude deve usar multiplicar e retornar 56.

Teste 4 — Divisão normal

"Divida 100 por 4." — O Claude deve usar dividir e retornar 25.

Teste 5 — Divisão por zero

"Divida 100 por 0." — O Claude deve receber a mensagem de erro e explicar que divisão por zero não é possível.

💡 Dica Prática

Teste também com números decimais ("Quanto é 3.14 vezes 2?") e com números negativos ("Subtraia 50 de 30"). Verifique se o Claude consegue encadear operações: "Some 10 e 20, depois multiplique por 3" — ele deve chamar as tools na ordem correta.

6

🔧 Melhorias e Refatoração

Agora que o server básico funciona, podemos pensar em melhorias. Arredondamento de resultados, suporte explícito a inteiros e floats, e a adição de novas operações como potenciação. Essas melhorias transformam um server de demonstração em algo mais robusto e profissional.

💎 Conceito Principal

Algumas melhorias práticas para o server de calculadora:

  • 1. Arredondamento: Use round(resultado, 10) para evitar problemas de ponto flutuante como 0.1 + 0.2 = 0.30000000000000004.
  • 2. Union types: Use a: int | float para aceitar tanto inteiros quanto floats explicitamente.
  • 3. Nova tool: Adicione potenciar(base: float, expoente: float) como exercício — segue o mesmo padrão das demais.
💡 Dica Prática

Como exercício, implemente a tool potenciar(base: float, expoente: float). Ela deve retornar base ** expoente. Pense: precisa de validação especial? O que acontece com 0 ** 0? E com expoentes negativos? Pratique o pensamento de "o que pode dar errado?" — essa mentalidade vai te servir em todo server MCP que construir.

❌ Evitar
  • Deixar problemas de ponto flutuante sem tratamento
  • Criar uma única tool "calcular" que faz tudo
  • Adicionar complexidade sem necessidade
  • Esquecer de testar as melhorias
✅ Fazer
  • Arredondar resultados de ponto flutuante
  • Manter tools separadas por operação
  • Adicionar novas tools incrementalmente
  • Testar cada melhoria isoladamente

📝 Resumo do Módulo

  • Planejamos 4 tools com assinaturas consistentes: somar, subtrair, multiplicar e dividir.
  • Implementamos soma e subtração como funções simples com type hints e docstrings.
  • Entendemos como o FastMCP gera schemas JSON automaticamente a partir de type hints Python.
  • Adicionamos validação de divisão por zero — retornando mensagem de erro ao invés de crashar.
  • Testamos todas as tools no Claude Desktop com diferentes tipos de entrada.
  • Exploramos melhorias como arredondamento, union types e novas operações.

Próximo Módulo: 3.5 — Server de Consulta ao Clima