from fastmcp import FastMCP

mcp = FastMCP()

@mcp.tool(description="Suma dos números enteros.")
def add(a: int, b: int) -> int:
    return a + b

@mcp.tool(description="Resta dos números enteros.")
def subtract(a: int, b: int) -> int:
    return a - b

@mcp.tool(description="Multiplica dos números enteros.")
def multiply(a: int, b: int) -> int:
    return a * b

@mcp.tool(description="Divide dos números y devuelve el resultado flotante.")
def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("No se puede dividir entre cero.")
    return a / b

@mcp.tool(description="Calcula el módulo de dos números enteros.")
def modulo(a: int, b: int) -> int:
    return a % b

@mcp.tool(description="Concatena dos cadenas de texto.")
def concat(a: str, b: str) -> str:
    return a + b

@mcp.tool(description="Devuelve la longitud de una cadena.")
def string_length(s: str) -> int:
    return len(s)

@mcp.tool(description="Convierte una cadena a mayúsculas.")
def to_upper(s: str) -> str:
    return s.upper()

@mcp.tool(description="Convierte una cadena a minúsculas.")
def to_lower(s: str) -> str:
    return s.lower()

@mcp.tool(description="Devuelve la suma de todos los elementos en una lista de enteros.")
def sum_list(numbers: list[int]) -> int:
    return sum(numbers)

@mcp.tool(description="Devuelve el valor máximo en una lista de enteros.")
def max_in_list(numbers: list[int]) -> int:
    return max(numbers)

@mcp.tool(description="Verifica si un número es par.")
def is_even(n: int) -> bool:
    return n % 2 == 0

@mcp.tool(description="Verifica si una cadena es un palíndromo.")
def is_palindrome(s: str) -> bool:
    return s == s[::-1]

@mcp.tool(description="Calcula el factorial de un número entero positivo.")
def factorial(n: int) -> int:
    if n < 0:
        raise ValueError("El factorial no está definido para negativos.")
    if n == 0:
        return 1
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

@mcp.tool(description="Devuelve los primeros n números de Fibonacci.")
def fibonacci(n: int) -> list[int]:
    if n <= 0:
        return []
    seq = [0, 1]
    while len(seq) < n:
        seq.append(seq[-1] + seq[-2])
    return seq[:n]

@mcp.tool(description="Devuelve si un número es primo.")
def is_prime(n: int) -> bool:
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True


if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="127.0.0.1", port=4200, path="/math")

    # mcp.run(transport="stdio")