Skip to main content
Glama
leo4life2

Minecraft MCP Server

by leo4life2

runAway

Escape threats in Minecraft by specifying the threat type, name, and run distance. Integrates with the MCP Server to enable AI-controlled character movement for survival scenarios.

Instructions

Run away from a threat

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
runDistanceNoDistance to run away (default: 20)
targetNameNoOptional: Specific name of the threat
targetTypeYesType of threat: 'player', 'mob', or 'animal'

Implementation Reference

  • The core handler function implementing the 'runAway' tool logic. Detects nearby hostile mobs or specified targets, computes a weighted escape vector, and uses pathfinder to move to a safe distance.
    export const runAway = async ( bot: Bot, params: ISkillParams, serviceParams: ISkillServiceParams, ): Promise<boolean> => { const skillName = 'runAway'; const requiredParams: string[] = []; const isParamsValid = validateSkillParams( params, 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 unpackedParams = { targetType: params.targetType ?? 'mob', targetName: params.targetName ?? '', runDistance: params.runDistance ?? 10, signal: serviceParams.signal, }; let { targetType, targetName, runDistance, signal } = unpackedParams; // Define the radius within which you want to detect mobs const NEARBY_ENTITY_RADIUS = bot.nearbyEntityRadius; const MIN_DISTANCE = 0.01; // Minimum distance to avoid extremely small values targetName = targetName ?? ''; const targetStr = targetName ? targetName : targetType; targetName = targetName.replace(/\s/g, '_'); // Replace spaces in name with _ if (targetType == 'mob') { targetType = 'hostile'; } // Check if entities are available if (!bot.entities) return; const allEntities = Object.values(bot.entities); // Filter function to identify mobs within the specified radius const isNearbyEntity = (entity: Entity) => { return ( entity.position.distanceTo(bot.entity.position) < NEARBY_ENTITY_RADIUS ); }; // Filter for nearby hostile mobs const hostileMobs = allEntities.filter((entity) => { const version = parseInt(bot.version.split('.')[1]); const NBT_HEALTH = version < 10 ? 6 : version < 14 ? 7 : version < 17 ? 8 : 9; if (targetName) { if (targetType === 'player') { const closestPlayer = findClosestPlayerByName(bot, { name: targetName }); return ( isNearbyEntity(entity) && entity.username !== bot.entity.username && entity.username == closestPlayer.username ); } else { return ( isNearbyEntity(entity) && entity.name.toLowerCase() === targetName.toLowerCase() ); } } return ( isNearbyEntity(entity) && entity.type === targetType && entity.metadata[NBT_HEALTH] && entity.username !== bot.entity.username ); }); // Check if there are no hostile mobs if (hostileMobs.length === 0) { return bot.emit( 'alteraBotEndObservation', `There are no ${targetType}s to run away from.`, ); } // Calculate the weighted vector direction to run away const runVector = { x: 0, y: 0, z: 0 }; hostileMobs.forEach((mob) => { const vector = { x: bot.entity.position.x - mob.position.x, y: bot.entity.position.y - mob.position.y, z: bot.entity.position.z - mob.position.z, }; const distance = Math.sqrt(vector.x ** 2 + vector.y ** 2 + vector.z ** 2); const weight = 1 / Math.max(distance, MIN_DISTANCE); // Avoid division by extremely small values runVector.x += vector.x * weight; runVector.y += vector.y * weight; runVector.z += vector.z * weight; }); // Normalize the resulting vector const vectorLength = Math.sqrt( runVector.x ** 2 + runVector.y ** 2 + runVector.z ** 2, ); if (vectorLength > 0) { runVector.x /= vectorLength; runVector.y /= vectorLength; runVector.z /= vectorLength; } // Determine the destination position const runDestination = new Vec3( bot.entity.position.x + runVector.x * runDistance, bot.entity.position.y + runVector.y * runDistance, bot.entity.position.z + runVector.z * runDistance, ); if (bot.pathfinder.isMoving()) await bot.pathfinder.stop(); await bot.waitForTicks(1); // give the pathfinder some time to stop // Make the bot move to the destination position const goal = new GoalXZ(runDestination.x, runDestination.z); // execute a cancelable move to the destination const result = await cancelableMove(bot, { goal, signal }); // check signal 1st if (isSignalAborted(signal)) { return bot.emit( 'alteraBotEndObservation', `You decided to do something else and stop running away.`, ); } if (result.error) { return bot.emit( 'alteraBotEndObservation', `You couldn't finish running away, but did your best.`, ); } // Print out the list of all nearby hostile mobs // const hostileMobNames = hostileMobs.map(entity => entity.name); // const uniqueHostileMobTypes = [...new Set(hostileMobNames)]; // console.log(`Nearby hostile mobs: ${hostileMobNames.join(', ')}`); return bot.emit('alteraBotEndObservation', `You have finished running away!`); };
  • Input schema and metadata definition for the 'runAway' tool used during registration, specifying parameters like targetType (required), targetName, and runDistance.
    runAway: { description: "Run away from a threat", params: { targetType: { type: "string", description: "Type of threat: 'player', 'mob', or 'animal'" }, targetName: { type: "string", description: "Optional: Specific name of the threat" }, runDistance: { type: "number", description: "Distance to run away (default: 20)" } }, required: ["targetType"] },
  • Generic registration logic in loadSkills() that registers all skills including 'runAway' from SKILL_METADATA by creating SkillDefinition objects with schema and dynamic executor.
    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; }

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