Add files via upload
This commit is contained in:
253
GenAI/mcp/sample1/mcp_server.py
Normal file
253
GenAI/mcp/sample1/mcp_server.py
Normal file
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Servidor MCP com ferramentas matemáticas: soma, subtração, multiplicação e divisão.
|
||||
Inclui tratamento de erros e validações.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from mcp.server import Server
|
||||
from mcp.types import Tool, TextContent
|
||||
from mcp.server.stdio import stdio_server
|
||||
|
||||
|
||||
# Criar instância do servidor MCP
|
||||
app = Server("math-tools-server")
|
||||
|
||||
|
||||
@app.list_tools()
|
||||
async def list_tools() -> list[Tool]:
|
||||
"""Lista as ferramentas disponíveis no servidor."""
|
||||
return [
|
||||
Tool(
|
||||
name="soma",
|
||||
description="Realiza a soma de dois números inteiros",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"numero1": {
|
||||
"type": "integer",
|
||||
"description": "Primeiro número inteiro"
|
||||
},
|
||||
"numero2": {
|
||||
"type": "integer",
|
||||
"description": "Segundo número inteiro"
|
||||
}
|
||||
},
|
||||
"required": ["numero1", "numero2"]
|
||||
}
|
||||
),
|
||||
Tool(
|
||||
name="subtracao",
|
||||
description="Realiza a subtração de dois números inteiros (numero1 - numero2)",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"numero1": {
|
||||
"type": "integer",
|
||||
"description": "Primeiro número inteiro (minuendo)"
|
||||
},
|
||||
"numero2": {
|
||||
"type": "integer",
|
||||
"description": "Segundo número inteiro (subtraendo)"
|
||||
}
|
||||
},
|
||||
"required": ["numero1", "numero2"]
|
||||
}
|
||||
),
|
||||
Tool(
|
||||
name="multiplicacao",
|
||||
description="Realiza a multiplicação de dois números inteiros",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"numero1": {
|
||||
"type": "integer",
|
||||
"description": "Primeiro número inteiro"
|
||||
},
|
||||
"numero2": {
|
||||
"type": "integer",
|
||||
"description": "Segundo número inteiro"
|
||||
}
|
||||
},
|
||||
"required": ["numero1", "numero2"]
|
||||
}
|
||||
),
|
||||
Tool(
|
||||
name="divisao",
|
||||
description="Realiza a divisão de dois números inteiros (numero1 / numero2). Retorna resultado como float.",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"numero1": {
|
||||
"type": "integer",
|
||||
"description": "Primeiro número inteiro (dividendo)"
|
||||
},
|
||||
"numero2": {
|
||||
"type": "integer",
|
||||
"description": "Segundo número inteiro (divisor)"
|
||||
}
|
||||
},
|
||||
"required": ["numero1", "numero2"]
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@app.call_tool()
|
||||
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
||||
"""Executa a ferramenta solicitada com tratamento de erros."""
|
||||
|
||||
# Validar argumentos comuns
|
||||
numero1 = arguments.get("numero1")
|
||||
numero2 = arguments.get("numero2")
|
||||
|
||||
if numero1 is None or numero2 is None:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": "Ambos os números são obrigatórios",
|
||||
"operacao": name
|
||||
})
|
||||
)]
|
||||
|
||||
# Validar tipos
|
||||
if not isinstance(numero1, int) or not isinstance(numero2, int):
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": "Os números devem ser inteiros",
|
||||
"operacao": name,
|
||||
"numero1_tipo": type(numero1).__name__,
|
||||
"numero2_tipo": type(numero2).__name__
|
||||
})
|
||||
)]
|
||||
|
||||
# Executar operação específica
|
||||
if name == "soma":
|
||||
try:
|
||||
resultado = numero1 + numero2
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"operacao": "soma",
|
||||
"numero1": numero1,
|
||||
"numero2": numero2,
|
||||
"resultado": resultado,
|
||||
"expressao": f"{numero1} + {numero2} = {resultado}"
|
||||
})
|
||||
)]
|
||||
except Exception as e:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": f"Erro ao executar soma: {str(e)}",
|
||||
"operacao": "soma"
|
||||
})
|
||||
)]
|
||||
|
||||
elif name == "subtracao":
|
||||
try:
|
||||
resultado = numero1 - numero2
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"operacao": "subtracao",
|
||||
"numero1": numero1,
|
||||
"numero2": numero2,
|
||||
"resultado": resultado,
|
||||
"expressao": f"{numero1} - {numero2} = {resultado}"
|
||||
})
|
||||
)]
|
||||
except Exception as e:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": f"Erro ao executar subtração: {str(e)}",
|
||||
"operacao": "subtracao"
|
||||
})
|
||||
)]
|
||||
|
||||
elif name == "multiplicacao":
|
||||
try:
|
||||
resultado = numero1 * numero2
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"operacao": "multiplicacao",
|
||||
"numero1": numero1,
|
||||
"numero2": numero2,
|
||||
"resultado": resultado,
|
||||
"expressao": f"{numero1} × {numero2} = {resultado}"
|
||||
})
|
||||
)]
|
||||
except Exception as e:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": f"Erro ao executar multiplicação: {str(e)}",
|
||||
"operacao": "multiplicacao"
|
||||
})
|
||||
)]
|
||||
|
||||
elif name == "divisao":
|
||||
# Validação específica: divisão por zero
|
||||
if numero2 == 0:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": "Divisão por zero não é permitida",
|
||||
"operacao": "divisao",
|
||||
"numero1": numero1,
|
||||
"numero2": numero2
|
||||
})
|
||||
)]
|
||||
|
||||
try:
|
||||
resultado = numero1 / numero2
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"operacao": "divisao",
|
||||
"numero1": numero1,
|
||||
"numero2": numero2,
|
||||
"resultado": resultado,
|
||||
"resultado_inteiro": numero1 // numero2,
|
||||
"resto": numero1 % numero2,
|
||||
"expressao": f"{numero1} ÷ {numero2} = {resultado}"
|
||||
})
|
||||
)]
|
||||
except Exception as e:
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": f"Erro ao executar divisão: {str(e)}",
|
||||
"operacao": "divisao"
|
||||
})
|
||||
)]
|
||||
|
||||
else:
|
||||
# Operação não implementada
|
||||
return [TextContent(
|
||||
type="text",
|
||||
text=json.dumps({
|
||||
"error": f"Operação '{name}' não está implementada",
|
||||
"operacao_solicitada": name,
|
||||
"operacoes_disponiveis": ["soma", "subtracao", "multiplicacao", "divisao"],
|
||||
"mensagem": "Por favor, utilize uma das operações disponíveis: soma, subtração, multiplicação ou divisão"
|
||||
})
|
||||
)]
|
||||
|
||||
|
||||
async def main():
|
||||
"""Inicia o servidor MCP via stdio."""
|
||||
async with stdio_server() as (read_stream, write_stream):
|
||||
await app.run(
|
||||
read_stream,
|
||||
write_stream,
|
||||
app.create_initialization_options()
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user