tradeWithVillager
Execute trades with Minecraft villagers by specifying trade index and quantity to exchange items through the MCP Minecraft Remote server.
Instructions
Trade with a nearby villager
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| villagerName | No | Name or identifier of the villager (optional) | |
| tradeIndex | Yes | Index of the trade from listTrades (1-based) | |
| count | No | Number of times to perform the trade |
Implementation Reference
- src/tools/trading.ts:146-211 (handler)Handler function that locates a nearby villager, opens the trading window, executes the specified trade based on index and count, closes the window, and responds with success or error.async ({ villagerName, tradeIndex, count }) => { if (!botState.isConnected || !botState.bot) { return createNotConnectedResponse() } try { // Find villagers in range (using a default range of 4 blocks) const villagers = Object.values(botState.bot.entities).filter( (entity) => { if (!entity || !entity.position || !botState.bot) return false const distance = entity.position.distanceTo( botState.bot.entity.position ) return ( distance <= 4 && String(entity.type) === 'villager' && (!villagerName || (entity.name && entity.name .toLowerCase() .includes(villagerName.toLowerCase()))) ) } ) if (villagers.length === 0) { return createSuccessResponse( villagerName ? `No villager named "${villagerName}" found nearby.` : 'No villagers found nearby.' ) } // Choose the closest villager if multiple are found const villager = villagers.reduce((closest, current) => { if (!closest.position || !current.position || !botState.bot) return current const distClosest = closest.position.distanceTo( botState.bot.entity.position ) const distCurrent = current.position.distanceTo( botState.bot.entity.position ) return distCurrent < distClosest ? current : closest }) // We need to use the real Villager class // First step is to use openVillager method const villagerEntity = await botState.bot.openVillager(villager as any) await botState.bot.trade(villagerEntity, tradeIndex - 1, count) // Close the trading window if open if (botState.bot.currentWindow) { await botState.bot.closeWindow(botState.bot.currentWindow) } return createSuccessResponse( `Successfully traded with villager ${ villager.name || 'Unknown' }, trade #${tradeIndex} (x${count})` ) } catch (error) { return createErrorResponse(error) } }
- src/tools/trading.ts:132-145 (schema)Zod input schema defining parameters for the tradeWithVillager tool: optional villagerName (string), required tradeIndex (number, 1-based), optional count (number, default 1).{ villagerName: z .string() .optional() .describe('Name or identifier of the villager (optional)'), tradeIndex: z .number() .describe('Index of the trade from listTrades (1-based)'), count: z .number() .optional() .default(1) .describe('Number of times to perform the trade'), },
- src/tools/trading.ts:130-212 (registration)Direct registration of the 'tradeWithVillager' tool using server.tool(), specifying name, description, input schema, and inline handler function.'tradeWithVillager', 'Trade with a nearby villager', { villagerName: z .string() .optional() .describe('Name or identifier of the villager (optional)'), tradeIndex: z .number() .describe('Index of the trade from listTrades (1-based)'), count: z .number() .optional() .default(1) .describe('Number of times to perform the trade'), }, async ({ villagerName, tradeIndex, count }) => { if (!botState.isConnected || !botState.bot) { return createNotConnectedResponse() } try { // Find villagers in range (using a default range of 4 blocks) const villagers = Object.values(botState.bot.entities).filter( (entity) => { if (!entity || !entity.position || !botState.bot) return false const distance = entity.position.distanceTo( botState.bot.entity.position ) return ( distance <= 4 && String(entity.type) === 'villager' && (!villagerName || (entity.name && entity.name .toLowerCase() .includes(villagerName.toLowerCase()))) ) } ) if (villagers.length === 0) { return createSuccessResponse( villagerName ? `No villager named "${villagerName}" found nearby.` : 'No villagers found nearby.' ) } // Choose the closest villager if multiple are found const villager = villagers.reduce((closest, current) => { if (!closest.position || !current.position || !botState.bot) return current const distClosest = closest.position.distanceTo( botState.bot.entity.position ) const distCurrent = current.position.distanceTo( botState.bot.entity.position ) return distCurrent < distClosest ? current : closest }) // We need to use the real Villager class // First step is to use openVillager method const villagerEntity = await botState.bot.openVillager(villager as any) await botState.bot.trade(villagerEntity, tradeIndex - 1, count) // Close the trading window if open if (botState.bot.currentWindow) { await botState.bot.closeWindow(botState.bot.currentWindow) } return createSuccessResponse( `Successfully traded with villager ${ villager.name || 'Unknown' }, trade #${tradeIndex} (x${count})` ) } catch (error) { return createErrorResponse(error) } } )
- src/tools/index.ts:40-40 (registration)Call to registerTradingTools() inside registerAllTools(), which performs the tool registrations for trading tools including tradeWithVillager.registerTradingTools()
- src/index.ts:7-7 (registration)Top-level call to registerAllTools() in the main entry point, which triggers the chain of registrations leading to tradeWithVillager.registerAllTools()