Skip to main content
Glama
vandewilly

MCP Dice Roller

by vandewilly

roll_dice

Roll dice using standard notation like '2d6' or '1d20+5' for tabletop games, character stats, and random number generation.

Instructions

Roll dice using standard dice notation (e.g., '2d6', '1d20+5', '3d8-2').

Args: notation: Dice notation string. Examples: - '1d6' - Roll one 6-sided die - '2d6' - Roll two 6-sided dice - '1d20+5' - Roll one 20-sided die and add 5 - '3d8-2' - Roll three 8-sided dice and subtract 2 - '4d6kh3' - Roll 4d6, keep highest 3 (D&D stat rolling) - '2d20kl1' - Roll 2d20, keep lowest 1 (disadvantage)

Returns: Dictionary with rolls, modifier, and total

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
notationNo1d6

Implementation Reference

  • The roll_dice function is defined here as an MCP tool, containing the logic to parse dice notation and simulate dice rolls.
    @mcp.tool()
    def roll_dice(notation: str = "1d6") -> dict:
        """
        Roll dice using standard dice notation (e.g., '2d6', '1d20+5', '3d8-2').
    
        Args:
            notation: Dice notation string. Examples:
                - '1d6' - Roll one 6-sided die
                - '2d6' - Roll two 6-sided dice
                - '1d20+5' - Roll one 20-sided die and add 5
                - '3d8-2' - Roll three 8-sided dice and subtract 2
                - '4d6kh3' - Roll 4d6, keep highest 3 (D&D stat rolling)
                - '2d20kl1' - Roll 2d20, keep lowest 1 (disadvantage)
    
        Returns:
            Dictionary with rolls, modifier, and total
        """
        notation = notation.lower().strip()
    
        # Parse the notation: XdY[kh/kl Z][+/-M]
        pattern = r"^(\d+)d(\d+)(?:(kh|kl)(\d+))?([+-]\d+)?$"
        match = re.match(pattern, notation)
    
        if not match:
            return {
                "error": f"Invalid dice notation: '{notation}'",
                "hint": "Use format like '2d6', '1d20+5', '4d6kh3'",
            }
    
        num_dice = int(match.group(1))
        die_sides = int(match.group(2))
        keep_type = match.group(3)  # 'kh' or 'kl' or None
        keep_count = int(match.group(4)) if match.group(4) else None
        modifier = int(match.group(5)) if match.group(5) else 0
    
        # Validate inputs
        if num_dice < 1 or num_dice > 100:
            return {"error": "Number of dice must be between 1 and 100"}
        if die_sides < 2 or die_sides > 1000:
            return {"error": "Die sides must be between 2 and 1000"}
        if keep_count and keep_count > num_dice:
            return {"error": f"Cannot keep {keep_count} dice when only rolling {num_dice}"}
    
        # Roll the dice
        rolls = [random.randint(1, die_sides) for _ in range(num_dice)]
        original_rolls = rolls.copy()
    
        # Apply keep highest/lowest
        kept_rolls = rolls
        dropped_rolls = []
        if keep_type and keep_count:
            sorted_rolls = sorted(rolls, reverse=(keep_type == "kh"))
            kept_rolls = sorted_rolls[:keep_count]
            dropped_rolls = sorted_rolls[keep_count:]
    
        subtotal = sum(kept_rolls)
        total = subtotal + modifier
    
        result = {
            "notation": notation,
            "rolls": original_rolls,
            "kept": kept_rolls if keep_type else original_rolls,
            "dropped": dropped_rolls if dropped_rolls else None,
            "subtotal": subtotal,
            "modifier": modifier if modifier != 0 else None,
            "total": total,
        }
    
        # Clean up None values
        return {k: v for k, v in result.items() if v is not None}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vandewilly/mcp-dice-roller'

If you have feedback or need assistance with the MCP directory API, please join our Discord server