Skip to main content

Python library for controlling Minecraft servers with python code.

Project description

MCPyLib - Python Client Library

Python client library for controlling Minecraft servers remotely.

Installation

Install MCPyLib using pip:

pip install mcpylib

Or using uv (faster alternative):

uv pip install mcpylib
Want faster package management? Try uv!

uv is a blazing-fast Python package manager (10-100x faster than pip).

Install uv

# On macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# On macOS with Homebrew
brew install uv

# On Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install MCPyLib with uv

uv pip install mcpylib

Run scripts with uv

uv run python your_script.py

Why use uv?

  • Fast: 10-100x faster than pip
  • Reliable: Automatic dependency locking
  • Simple: One command to set up everything
  • Isolated: Automatic virtual environment management

Quick Start

Create and run your first script

# quickstart.py
from mcpylib import MCPyLib

# Initialize client
mc = MCPyLib(
    ip="127.0.0.1",      # Server IP
    port=65535,          # Server port
    token="your_token"   # Authentication token
)

# Set a diamond block
mc.setblock(100, 64, 200, "minecraft:diamond_block")

# Get block type
block = mc.getblock(100, 64, 200)
print(f"Block: {block}")  # Output: Block: minecraft:diamond_block

# Fill a 10x10x10 region with glass
count = mc.fill(0, 60, 0, 10, 70, 10, "minecraft:glass")
print(f"Filled {count} blocks")

# Get player position
pos = mc.getPos("Steve")
print(f"Player at: {pos}")  # Output: Player at: [100, 64, 200]

Run the script

# With uv (recommended)
uv run python quickstart.py

# Or with pip
python quickstart.py

API Reference

MCPyLib Class

Constructor

MCPyLib(ip="127.0.0.1", port=65535, token="", timeout=10.0)

Parameters:

  • ip (str): Server IP address
  • port (int): Server port
  • token (str): Authentication token from server
  • timeout (float): Socket timeout in seconds

Methods

setblock()
setblock(x: int, y: int, z: int, block_name: str, block_state: dict = None, nbt: dict = None) -> int

Set a block at the specified coordinates with optional block state and NBT data.

Parameters:

  • x, y, z (int): Block coordinates
  • block_name (str): Block type (e.g., "minecraft:stone" or "stone")
  • block_state (dict, optional): Block state properties like direction, rotation, etc.
  • nbt (dict, optional): NBT data for block entities (signs, chests, etc.)

Returns:

  • 1 if successful

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid coordinates, block type, or state properties

Example:

# Basic block placement
mc.setblock(100, 64, 200, "minecraft:diamond_block")
mc.setblock(101, 64, 200, "gold_block")  # "minecraft:" prefix is optional

# Place a stair facing north
mc.setblock(100, 64, 201, "oak_stairs", block_state={"facing": "north", "half": "bottom"})

# Place a fence gate facing east
mc.setblock(100, 64, 202, "oak_fence_gate", block_state={"facing": "east", "open": "false"})

# Place a log with horizontal axis
mc.setblock(100, 64, 203, "oak_log", block_state={"axis": "x"})

# Place a sign with text
mc.setblock(100, 64, 204, "oak_sign",
    block_state={"rotation": "0"},
    nbt={"Text1": "Hello", "Text2": "World", "Text3": "", "Text4": ""}
)

# Place a chest with custom name
mc.setblock(100, 64, 205, "chest",
    block_state={"facing": "north"},
    nbt={"CustomName": '{"text":"My Chest"}'}
)

# Place a waterlogged fence
mc.setblock(100, 64, 206, "oak_fence", block_state={"waterlogged": "true"})

Common Block State Properties:

  • facing: Direction the block faces ("north", "south", "east", "west", "up", "down")
  • rotation: Rotation for signs and banners ("0" to "15")
  • axis: Axis for logs and pillars ("x", "y", "z")
  • half: Upper or lower half ("top", "bottom")
  • shape: Stair shape ("straight", "inner_left", "inner_right", "outer_left", "outer_right")
  • open: Whether doors/gates are open ("true", "false")
  • powered: Whether redstone components are powered ("true", "false")
  • waterlogged: Whether block contains water ("true", "false")
getblock()
getblock(x: int, y: int, z: int) -> str

Get the block type at coordinates.

Parameters:

  • x, y, z (int): Block coordinates

Returns:

  • Block type as string (e.g., "minecraft:stone")

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid coordinates

Example:

block = mc.getblock(100, 64, 200)
print(block)  # "minecraft:diamond_block"
fill()
fill(x1: int, y1: int, z1: int, x2: int, y2: int, z2: int, block_name: str) -> int

Fill a region with the specified block type.

Parameters:

  • x1, y1, z1 (int): Starting coordinates
  • x2, y2, z2 (int): Ending coordinates
  • block_name (str): Block type

Returns:

  • Number of blocks affected

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid coordinates or block type

Example:

# Fill a 10x10x10 cube with glass
count = mc.fill(0, 60, 0, 10, 70, 10, "minecraft:glass")
print(f"Filled {count} blocks")  # "Filled 1331 blocks"
getPos()
getPos(username: str) -> List[int]

Get a player's current position.

Parameters:

  • username (str): Player's Minecraft username (case-sensitive)

Returns:

  • List of [x, y, z] coordinates (integers)

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Player not found or not online

Example:

pos = mc.getPos("Steve")
x, y, z = pos
print(f"Steve is at ({x}, {y}, {z})")
teleport()
teleport(username: str, x: float, y: float, z: float, yaw: float = None, pitch: float = None) -> bool

Teleport a player to specified coordinates.

Parameters:

  • username (str): Player's Minecraft username
  • x, y, z (float): Target coordinates
  • yaw (float, optional): Rotation yaw angle
  • pitch (float, optional): Rotation pitch angle

Returns:

  • True if successful

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Player not found or teleport fails

Example:

# Teleport to coordinates
mc.teleport("Steve", 100, 64, 200)

# Teleport with rotation
mc.teleport("Steve", 100, 64, 200, yaw=90.0, pitch=0.0)
gamemode()
gamemode(username: str, mode: str) -> bool

Change a player's game mode.

Parameters:

  • username (str): Player's Minecraft username
  • mode (str): Game mode ("survival", "creative", "adventure", "spectator")

Returns:

  • True if successful

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Player not found or invalid game mode

Example:

mc.gamemode("Steve", "creative")
mc.gamemode("Alex", "survival")
mc.gamemode("Bob", "spectator")
time()
time(action: str, value: int = None) -> int

Control world time.

Parameters:

  • action (str): Action to perform ("set", "add", "query")
  • value (int, optional): Time value (0-24000) for "set" or "add" actions

Returns:

  • Current world time (0-24000)

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid action or value out of range

Example:

# Set time to day (1000)
mc.time("set", 1000)

# Add 6000 ticks
mc.time("add", 6000)

# Query current time
current_time = mc.time("query")
print(f"Current time: {current_time}")
weather()
weather(condition: str, duration: int = None) -> bool

Control world weather.

Parameters:

  • condition (str): Weather condition ("clear", "rain", "thunder")
  • duration (int, optional): Duration in seconds

Returns:

  • True if successful

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid weather condition

Example:

# Clear weather
mc.weather("clear")

# Rain for 10 minutes (600 seconds)
mc.weather("rain", duration=600)

# Thunder storm for 5 minutes
mc.weather("thunder", duration=300)
give()
give(username: str, item: str, amount: int = 1) -> bool

Give items to a player.

Parameters:

  • username (str): Player's Minecraft username
  • item (str): Item type (e.g., "minecraft:diamond" or "diamond")
  • amount (int): Quantity (1-64, default: 1)

Returns:

  • True if successful

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Player not found, invalid item, or amount out of range

Example:

# Give 10 diamonds
mc.give("Steve", "minecraft:diamond", 10)

# Give 1 diamond sword (amount defaults to 1)
mc.give("Steve", "diamond_sword")

# Give 64 stone blocks
mc.give("Alex", "stone", 64)
summon()
summon(entity_type: str, x: float, y: float, z: float) -> str

Summon an entity at specified coordinates.

Parameters:

  • entity_type (str): Entity type (e.g., "minecraft:zombie", "pig", "creeper")
  • x, y, z (float): Spawn coordinates

Returns:

  • Entity UUID as string

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid entity type or coordinates

Example:

# Summon a zombie
uuid = mc.summon("minecraft:zombie", 100, 64, 200)

# Summon a pig (namespace prefix optional)
uuid = mc.summon("pig", 150, 70, 250)

# Summon a creeper
uuid = mc.summon("creeper", 200, 64, 300)
kill()
kill(selector: str) -> int

Remove entities from the world.

Parameters:

  • selector (str): Entity selector:
    • "all" - Kill all entities
    • Entity type (e.g., "zombie", "creeper") - Kill all of that type
    • "player:username" - Kill a specific player

Returns:

  • Number of entities killed

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid selector or player not found

Example:

# Kill all entities
count = mc.kill("all")
print(f"Killed {count} entities")

# Kill all zombies
zombie_count = mc.kill("zombie")

# Kill all creepers
creeper_count = mc.kill("creeper")

# Kill a specific player
mc.kill("player:Steve")
edit()
edit(x: int, y: int, z: int, blocks: List[List[List]]) -> int

High-performance bulk block editing (like WorldEdit). Place large structures with mixed block types in a single operation.

Parameters:

  • x, y, z (int): Starting coordinates
  • blocks (List[List[List]]): 3D array of blocks [x][y][z], where each element can be:
    • str: Block name (e.g., "stone", "minecraft:glass")
    • None: Skip this position (leave unchanged)
    • dict: Complex block with state and NBT:
      {
          "block": "minecraft:chest",
          "block_state": {"facing": "north"},  # Optional
          "nbt": {"CustomName": '{"text":"Storage"}'}  # Optional
      }
      

Returns:

  • Number of blocks placed

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Invalid block data or coordinates

Example:

# Simple 2x2x2 cube
blocks = [
    [["stone", "glass"], ["stone", "glass"]],
    [["stone", "glass"], ["stone", "glass"]]
]
mc.edit(100, 64, 200, blocks)

# Mixed mode with complex blocks
blocks = [
    [[None, "stone"], ["glass", None]],
    [[{
        "block": "minecraft:chest",
        "block_state": {"facing": "north"},
        "nbt": {"CustomName": '{"text":"Loot"}'}
    }, "stone"], ["diamond_block", "gold_block"]]
]
mc.edit(100, 64, 200, blocks)

# Build a house
blocks = []
for x in range(10):
    x_layer = []
    for y in range(5):
        y_layer = [None] * 10
        x_layer.append(y_layer)
    blocks.append(x_layer)

# Floor
for x in range(10):
    for z in range(10):
        blocks[x][0][z] = "stone"

# Walls
for y in range(1, 4):
    for x in range(10):
        blocks[x][y][0] = "cobblestone"
        blocks[x][y][9] = "cobblestone"
    for z in range(10):
        blocks[0][y][z] = "cobblestone"
        blocks[9][y][z] = "cobblestone"

# Roof
for x in range(10):
    for z in range(10):
        blocks[x][4][z] = "oak_planks"

count = mc.edit(100, 64, 200, blocks)
print(f"House built: {count} blocks")

Performance Notes:

  • Use edit() for structures with multiple different block types
  • Use fill() for large areas of the same block
  • Much faster than calling setblock() repeatedly
  • Supports thousands of blocks in a single operation
clone()
clone(x1: int, y1: int, z1: int, x2: int, y2: int, z2: int, dest_x: int, dest_y: int, dest_z: int) -> int

Clone a region of blocks to a new location.

Parameters:

  • x1, y1, z1 (int): Source region start coordinates
  • x2, y2, z2 (int): Source region end coordinates
  • dest_x, dest_y, dest_z (int): Destination coordinates

Returns:

  • Number of blocks cloned

Raises:

  • ConnectionError: Failed to connect to server
  • AuthenticationError: Invalid token
  • CommandError: Region too large (max 32,768 blocks)

Example:

# Clone a 10x10x10 region
count = mc.clone(0, 64, 0, 10, 74, 10, 20, 64, 0)
print(f"Cloned {count} blocks")

# Copy a house from one location to another
mc.clone(100, 64, 100, 110, 74, 110, 200, 64, 200)

Exception Handling

MCPyLib defines custom exceptions:

from mcpylib import MCPyLib, MCPyLibError, ConnectionError, AuthenticationError, CommandError

try:
    mc = MCPyLib(token="wrong_token")
    mc.setblock(100, 64, 200, "minecraft:stone")
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except ConnectionError as e:
    print(f"Connection failed: {e}")
except CommandError as e:
    print(f"Command failed: {e}")
except MCPyLibError as e:
    print(f"General error: {e}")

Block Names

Block names can be specified with or without the "minecraft:" namespace prefix:

# Both are valid
mc.setblock(0, 64, 0, "minecraft:stone")
mc.setblock(0, 64, 0, "stone")

# Common blocks
mc.setblock(0, 64, 0, "grass_block")
mc.setblock(0, 65, 0, "oak_log")
mc.setblock(0, 66, 0, "diamond_block")
mc.setblock(0, 67, 0, "glowstone")

See the Minecraft Wiki for a complete list of block IDs.

Advanced Usage

Custom Timeout

# Set a longer timeout for slow connections
mc = MCPyLib(
    ip="192.168.1.100",
    port=65535,
    token="your_token",
    timeout=30.0  # 30 seconds
)

Building Structures

def build_cube(mc, x, y, z, size, block):
    """Build a hollow cube"""
    # Bottom and top
    mc.fill(x, y, z, x+size, y, z+size, block)
    mc.fill(x, y+size, z, x+size, y+size, z+size, block)

    # Sides
    mc.fill(x, y, z, x, y+size, z+size, block)
    mc.fill(x+size, y, z, x+size, y+size, z+size, block)
    mc.fill(x, y, z, x+size, y+size, z, block)
    mc.fill(x, y, z+size, x+size, y+size, z+size, block)

# Build a 10x10x10 glass cube
build_cube(mc, 0, 64, 0, 10, "glass")

Following Players

import time

def follow_player(mc, username, interval=1.0):
    """Track player movement"""
    try:
        while True:
            pos = mc.getPos(username)
            print(f"{username} is at {pos}")
            time.sleep(interval)
    except KeyboardInterrupt:
        print("Stopped tracking")
    except CommandError as e:
        print(f"Error: {e}")

follow_player(mc, "Steve")

Requirements

  • Python 3.11 or higher
  • No external dependencies (uses only standard library)

See Also

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcpylib-1.1.1.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpylib-1.1.1-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file mcpylib-1.1.1.tar.gz.

File metadata

  • Download URL: mcpylib-1.1.1.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for mcpylib-1.1.1.tar.gz
Algorithm Hash digest
SHA256 bab9df5679f27fc0d88546f5b2dcd45d3db6b46b807a3f021d37c4184797d274
MD5 d1844ba809813c27d6bf3b48d04bf6b0
BLAKE2b-256 8a307d620691ef109847b44a23e76402a29cb99e5e7d36112f5d789458cceee9

See more details on using hashes here.

File details

Details for the file mcpylib-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: mcpylib-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for mcpylib-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 142fc614395c65b235fd3a0730aa3e7c752e08d20210df23e978ca5154b609c1
MD5 53118edee34aa0625652020ff9105b3a
BLAKE2b-256 a23dc695465e99c55841f9e24d1968a757f757dd5594237a8bd630277a6f8c00

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page