Skip to main content
Glama
leo4life2

Minecraft MCP Server

by leo4life2

sleepInNearbyBed

Locate and use the nearest bed within a specified distance to restore player health and reset spawn points in Minecraft, enabling efficient gameplay progress.

Instructions

Find and sleep in a nearby bed

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
maxDistanceNoMaximum distance to search for bed (default: 30)

Implementation Reference

  • Main handler function that implements the logic for finding a nearby bed, navigating to it, checking if it's nighttime, sleeping in the bed, and handling wake-up conditions including interruptions and other players' sleep status.
    export const sleepInNearbyBed = async (
      bot: Bot,
      params: ISkillParams,
      serviceParams: ISkillServiceParams,
    ): Promise<boolean> => {
      const skillName = 'sleepInNearbyBed';
      const requiredParams: string[] = [];
      const isParamsValid = validateSkillParams(
        { ...serviceParams },
        requiredParams,
        skillName,
      );
      if (!isParamsValid) {
        serviceParams.cancelExecution?.();
        bot.emit(
          'alteraBotEndObservation',
          `Mistake: You didn't provide all of the required parameters ${requiredParams.join(', ')} for the ${skillName} skill.`,
        );
        return false;
      }
    
      const defaultParams = {
        maxDistance: 10,
      };
      const unpackedParams = {
        maxDistance: params.maxDistance ?? defaultParams.maxDistance,
        signal: serviceParams.signal,
      };
      const { maxDistance, signal } = unpackedParams;
      const TIME_TO_FALL_ASLEEP_S = 10;
      const SLEEP_IN_TICKS = TIME_TO_FALL_ASLEEP_S * 20;
    
      // Find the nearest bed within the specified range
      const bed = bot.findBlock({
        matching: (block) => bot.isABed(block),
        maxDistance: maxDistance,
      });
    
      // No bed is found
      if (!bed) {
        bot.emit(
          'alteraBotEndObservation',
          `Mistake: you tried to sleep in a bed nearby but found no bed around.`,
        );
        return false;
      }
      console.log(
        `Found a bed at {${bed.position.x},${bed.position.y},${bed.position.z}}.`,
      );
    
      // Get to bed
      try {
        navigateToLocation(bot, {
          x: bed.position.x,
          y: bed.position.y,
          z: bed.position.z,
          signal,
          range: 1,
        });
      } catch (error) {
        bot.emit(
          'alteraBotEndObservation',
          `You tried to navigate to bed at {${bed.position.x},${bed.position.y},${bed.position.z}} but could not.`,
        );
      }
    
      console.log(
        `Searching for a bed within ${maxDistance} blocks to sleep in.`,
      );
      // It's day time, can't sleep
      if (!(bot.time.timeOfDay >= 13000 && bot.time.timeOfDay <= 23000)) {
        bot.emit(
          'alteraBotEndObservation',
          `Mistake: you tried to sleep but it is daytime.`,
        );
        return false;
      }
    
      // Attempt to go to the bed and sleep
      try {
        await bot.sleep(bed);
        bot.emit('alteraBotTextObservation', `You have started sleeping.`);
        let cur_sleep_ticks = 0;
        let woke_up_naturally = false;
    
        const checkForWake = () => {
          console.log(`Woke up naturally.`);
          woke_up_naturally = true;
        };
    
        // Set up a promise that resolves when the bot wakes up
        new Promise((resolve) => {
          bot.once('wake', checkForWake);
          resolve(true);
        });
    
        while (cur_sleep_ticks < SLEEP_IN_TICKS && !woke_up_naturally) {
          if (isSignalAborted(signal)) {
            // You interrupted your own sleep
            bot.removeListener('wake', checkForWake);
            return bot.emit(
              'alteraBotEndObservation',
              `You decided to do something else instead of sleeping.`,
            );
          }
          await bot.waitForTicks(1);
          cur_sleep_ticks++;
        }
        bot.removeListener('wake', checkForWake);
    
        // Have to wait >20 ticks for game time to update
        await bot.waitForTicks(40);
        console.log(
          `BOT DONE SLEEPING, TIME: ${bot.time.timeOfDay} SLEEP TICKS: ${cur_sleep_ticks}, WOKE UP NATURALLY: ${woke_up_naturally}`,
        );
        // At this point, you finished sleeping without getting interrupted, but you don't know if you've slept through the whole night
        if (bot.time.timeOfDay < 13000 || bot.time.timeOfDay > 23000) {
          bot.emit(
            'alteraBotEndObservation',
            `You have slept through the entire night and have woken up naturally.`,
          );
          return true;
        } else {
          const msg = checkOtherPlayersSleeping(bot);
          bot.emit(
            'alteraBotEndObservation',
            `You woke up before the night was skipped. ${msg}`,
          );
          bot.wake();
          return false;
        }
      } catch (error) {
        const err_str = `ERROR: You tried to sleep in the nearby bed but failed because ${error}`;
        console.error(err_str);
        bot.emit('alteraBotEndObservation', err_str);
        return false;
      }
    };
  • Registration entry in SKILL_METADATA for the sleepInNearbyBed skill, including description, input parameters schema (maxDistance), and required fields.
    sleepInNearbyBed: {
        description: "Find and sleep in a nearby bed",
        params: {
            maxDistance: { type: "number", description: "Maximum distance to search for bed (default: 30)" }
        },
        required: []
    },
  • Helper function called by the handler to determine why the bot woke up prematurely by checking if other players are sleeping.
    const checkOtherPlayersSleeping = (bot: Bot): string => {
      // If the bot woke up and it is still nighttime, it suggests other players didn't sleep
      const playerNames = Object.keys(bot.players);
      const sleepingPlayers = [];
      const awakePlayers: string[] = [];
    
      playerNames.forEach((name) => {
        const playerEntity = bot.players[name].entity;
        if (!(name == bot.username)) {
          if (playerEntity && (playerEntity as any).isSleeping) {
            sleepingPlayers.push(name);
          } else {
            awakePlayers.push(name);
          }
        }
      });
    
      if (awakePlayers.length > 0) {
        return `Players that were not sleeping: ${awakePlayers.join(', ')}.`;
      } else {
        return `ERROR: You don't know why you did not sleep, because it is neither you interrupting your own sleep or other players.`;
      }
    };
  • Construction of the inputSchema for skills from SKILL_METADATA during registration in loadSkills function.
        type: "object",
        properties: metadata.params,
        required: metadata.required
    },
    execute: createSkillExecutor(skillName)

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/leo4life2/minecraft-mcp-http'

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