Skip to main content
Glama

retrieveItemsFromNearbyFurnace

Automatically fetch smelted items from a furnace in Minecraft using this tool, enabling efficient resource management and automation in gameplay.

Instructions

Retrieve smelted items from a nearby furnace

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Main handler function that finds nearby furnaces, navigates to them, opens each one, and retrieves items from input, fuel, or output slots based on furnace state.
    export const retrieveItemsFromNearbyFurnace = async ( bot: Bot, params: ISkillParams, serviceParams: ISkillServiceParams, ): Promise<boolean> => { const skillName = 'retrieveItemsFromNearbyFurnace'; const requiredParams: string[] = []; if ( !validateSkillParams( params, requiredParams, skillName, ) ) { serviceParams.cancelExecution?.(); bot.emit( 'alteraBotEndObservation', `Mistake: You didn't provide all of the required parameters ${requiredParams.join(', ')} for the ${skillName} skill.`, ); return false; } const {signal, getStatsData, setStatsData} = serviceParams; const furnacePositions = findNearbyFurnaces(bot, { searchRadius: 10, maxFurnaces: 10, }); if (furnacePositions.length === 0) { return bot.emit( 'alteraBotEndObservation', 'You tried to retrieve items from a nearby furnace but no furnaces were found nearby.', ); } let msg = ''; bot.emit( 'alteraBotStartObservation', `You are retrieving items from ${furnacePositions.length} furnaces nearby.`, ); for (const furnaceBlock of furnacePositions .map((pos) => bot.blockAt(pos)) .filter(Boolean)) { const location = `(${Math.floor(furnaceBlock.position.x)}, ${Math.floor(furnaceBlock.position.y)}, ${Math.floor(furnaceBlock.position.z)})`; if (isInventoryFull(bot)) { return bot.emit( 'alteraBotEndObservation', `You tried to retrieve items at furnace location ${location} but your inventory is full.`, ); } try { await cancelableMove(bot, { goal: new GoalNear( furnaceBlock.position.x, furnaceBlock.position.y, furnaceBlock.position.z, 2, ), signal, }); if (isSignalAborted(signal)) { return bot.emit( 'alteraBotTextObservation', interrupt_message_accumulated_items(msg), ); } bot.lookAt(furnaceBlock.position.offset(0.5, 0.5, 0.5)); console.log(`You are looking at the furnace at ${location}.`); const [furnace, cur_msg] = await _retrieveItemFromSingleFurnace(bot, { furnaceBlock, getStatsData, setStatsData, }); msg += cur_msg; console.log(`Furnace object: ${furnace}`); if (isSignalAborted(signal)) { furnace?.close(); return bot.emit( 'alteraBotTextObservation', interrupt_message_accumulated_items(msg), ); } } catch (err) { const error = err as Error; console.log(error?.message ?? String(error)); bot.emit( 'alteraBotTextObservation', `You can't reach the furnace at ${location}. It was too difficult to reach it.`, ); continue; } } return bot.emit('alteraBotEndObservation', msg); };
  • Schema definition for the tool, indicating no input parameters are required.
    retrieveItemsFromNearbyFurnace: { description: "Retrieve smelted items from a nearby furnace", params: {}, required: [] },
  • Function that registers all skills including retrieveItemsFromNearbyFurnace by loading metadata and creating SkillDefinition objects for MCP tool registration.
    export async function loadSkills(): Promise<SkillDefinition[]> { const skills: SkillDefinition[] = []; for (const [skillName, metadata] of Object.entries(SKILL_METADATA)) { skills.push({ name: skillName, description: metadata.description, inputSchema: { type: "object", properties: metadata.params, required: metadata.required }, execute: createSkillExecutor(skillName) }); } return skills; }
  • Core helper function that handles interaction with a single furnace: opens it, calculates fuel and smelting progress, retrieves items accordingly, and generates status messages.
    const _retrieveItemFromSingleFurnace = async ( bot: Bot, options: ILRetrieveItemFromSingleFurnaceOptions, ) => { /* Atomic function that retrieves items from a single furnace. Note that no text observations are emitted here. We leave it to the outside function to handle text observations. Behavior: - If furnace is in progress, take output items - If furnace is not in progress, take all items if there are any. */ const {furnaceBlock, getStatsData, setStatsData} = options; const smeltTime = 10; const location = `${Math.floor(furnaceBlock.position.x)}, ${Math.floor(furnaceBlock.position.y)}, ${Math.floor(furnaceBlock.position.z)}`; /* Mineflayer currently does not update the furnace item and fuel progress correctly. Item smelting and fuel burning progress are both null due to packet update errors. The code block below is a temporary workaround to get the progress of the furnace. */ const furnaceInfo: any = {}; // This is a temporary workaround to get the progress of the furnace. Not found the type in mineflayer. const furnaceInfoFunction = (packet: any) => { furnaceInfo[packet.property] = packet.value; }; bot._client.on('craft_progress_bar', furnaceInfoFunction); const furnace = await asyncwrap({ func: async () => { return await bot.openFurnace(furnaceBlock); }, getStatsData, setStatsData, }); await bot.waitForTicks(1); bot._client.removeListener('craft_progress_bar', furnaceInfoFunction); getFuelSeconds(furnace, furnaceInfo); getItemProgress(furnace, furnaceInfo); console.log(`Current fuel progress: ${furnace.fuelSeconds}`); console.log(`Current item progress: ${furnace.progressSeconds}`); const furnaceFuelSeconds = furnace.fuelSeconds.toFixed(1); const furnaceProgressSeconds = furnace.progressSeconds.toFixed(1); const retrieve_message_parts = []; let retrieve_message = ''; try { // If furnace is not smelting, take out all items. if (furnaceProgressSeconds == 10 || furnaceProgressSeconds == 0) { console.log('Furnace is not smelting. Taking out all items.'); if (furnace.inputItem()) { const ir = await furnace.takeInput(); retrieve_message_parts.push( `you retrieved ${ir.count} ${ir.displayName} from the furnace input slot`, ); } if (furnace.fuelItem()) { const fr = await furnace.takeFuel(); retrieve_message_parts.push( `you retrieved ${fr.count} ${fr.displayName} from the furnace fuel slot`, ); } if (furnace.outputItem()) { const outr = await furnace.takeOutput(); retrieve_message_parts.push( `you retrieved ${outr.count} ${outr.displayName} from the furnace output slot`, ); } if (retrieve_message_parts.length != 0) { retrieve_message = `At furnace location (${location}),`; for (let i = 0; i < retrieve_message_parts.length; i++) { if ( retrieve_message_parts.length > 1 && i == retrieve_message_parts.length - 1 ) { retrieve_message += 'and '; } retrieve_message += retrieve_message_parts[i]; if (i < retrieve_message_parts.length - 1) { retrieve_message += ', '; } else { retrieve_message += '. '; } } } else { retrieve_message = `There were no items to retrieve at furnace location (${location}). `; } retrieve_message += `This furnace is currently free for smelting. `; } else { // If furnace is in use, just take out the output items if there are any and then wait const total_wait_time = furnaceProgressSeconds + (furnace.inputItem().count - 1) * smeltTime; if (furnace.outputItem()) { const outr = await furnace.takeOutput(); retrieve_message += `At furnace location (${location}), you retrieved ${outr.count} ${outr.displayName} from the furnace output slot, and `; retrieve_message += `the next ${outr.displayName} will be smelted in ${furnaceProgressSeconds} seconds. `; retrieve_message += `This furnace will be free for smelting in ${total_wait_time} seconds. `; } else { retrieve_message += `Furnace at location (${location}) is currently smelting. `; retrieve_message += `The next item will be smelted in ${furnaceProgressSeconds} seconds. `; retrieve_message += `It will be free for smelting in ${total_wait_time} seconds. `; } } } catch (error) { retrieve_message = `ERROR: Failed to retrieve items from the furnace due to: ${error}`; } finally { console.log(retrieve_message); // bot.emit('alteraBotTextObservation', `${retrieve_message}`); furnace.close(); return [furnace, retrieve_message]; } };

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