Skip to main content

Async Python SDK for connecting Discord bots and automation to Minecraft servers through a CraftCord plugin API.

Project description

CraftCord

CraftCord is a Python SDK for Discord bot developers who want to connect their bot to Minecraft. It is to be used with Craftcord plugin, you can find it in https://github.com/rytisltu09/CraftcordPlugin

IT IS HIGHLY RECOMMENDED THAT YOU SETUP YOUR CRAFTCORD PLUGIN FIRST BEFORE CONTINUING!

If you are new, the fastest way to understand CraftCord is:

  1. Run the example bot.
  2. Use !mc_online in Discord.
  3. See Minecraft player data in your Discord channel.

Who This Is For

CraftCord is a good fit if you want to:

  • build a Discord bot in Python
  • read Minecraft server events
  • run Minecraft actions from Discord commands
  • keep bot logic clean and reusable

What You Get

  • async Python client (Client)
  • two transport options: WebSocket or HTTP
  • typed Minecraft events and models
  • CraftCord command system (@client.command)
  • Discord adapter for discord.py (DiscordPyAdapter)
  • plugin system (client.plugins.load(...))

Beginner 5-Minute Setup

1. Install Dependencies

From your virtual environment

pip install craftcord

2. Configure Environment Variables

Set these before running examples/basic_bot.py:

  • DISCORD_TOKEN (required)
  • CRAFTCORD_HOST (default: 127.0.0.1)
  • CRAFTCORD_PORT (default: 8080)
  • CRAFTCORD_TOKEN (default: secret)
  • CRAFTCORD_TRANSPORT (ws or http, default: ws)
  • CRAFTCORD_DEFAULT_CHANNEL (optional Discord channel id)

Example:

export DISCORD_TOKEN="your-discord-bot-token"
export CRAFTCORD_HOST="127.0.0.1"
export CRAFTCORD_PORT="8080"
export CRAFTCORD_TOKEN="secret"
export CRAFTCORD_TRANSPORT="ws"

3. Start The Bot

python examples/basic_bot.py

4. Test It In Discord

In a channel where your bot can read and send messages, run:

!mc_online

If everything is connected, the bot responds with online player names.

How Commands Work (Simple Mental Model)

  • @bot.command is Discord-facing.
  • @client.command is CraftCord-facing shared logic.

Typical flow:

  1. User types a Discord command like !mc_online.
  2. Discord handler calls await client.invoke_command("online").
  3. CraftCord command runs and returns data.
  4. Discord handler sends the result back to chat.

This is why you avoid duplicating business logic.

Minimal Example

import asyncio

from craftcord import Client


async def main() -> None:
    client = Client(host="127.0.0.1", port=8080, token="secret")

    @client.command("online")
    async def online_players() -> list[str]:
        players = await client.minecraft.players()
        return [player.username for player in players]

    await client.start()


asyncio.run(main())

Minecraft Features Available

From client.minecraft:

  • players() / get_players()
  • server_info() / get_server_info()
  • send_message(message, target=None)
  • execute(command)
  • kick(username, reason=None)
  • ban(username, reason=None)

Events You Can Listen To

Typed built-in events include:

  • player_join
  • player_leave
  • player_chat
  • player_death
  • server_start
  • server_stop

Unknown event names arrive as GenericEvent.

Transport Choice

  • Use ws for real-time events and long-running bot sessions.
  • Use http for simple request/response integrations.

Set with:

export CRAFTCORD_TRANSPORT="ws"

or

export CRAFTCORD_TRANSPORT="http"

Troubleshooting

Bot starts but keeps retrying WebSocket

Cause: CraftCord API endpoint is not reachable.

Check:

  1. Is your Java-side CraftCord plugin/API running?
  2. Do CRAFTCORD_HOST, CRAFTCORD_PORT, and CRAFTCORD_TOKEN match?
  3. If your server only supports HTTP, set CRAFTCORD_TRANSPORT=http.

Discord command does not trigger

Check:

  1. Message Content Intent is enabled in Discord Developer Portal.
  2. Bot has permission to read and send in that channel.
  3. You are using the right prefix (!) and command (!mc_online).

Import or dataclass errors on Python 3.14

Use the latest code in this repository. Recent updates include Python 3.14 compatibility fixes for event dataclasses.

Plugin System

Extensions are classes with setup(client) and optional teardown(client).

class GreetingExtension:
    async def setup(self, client) -> None:
        @client.on("player_join")
        async def greet(event) -> None:
            await client.minecraft.send_message(f"Welcome {event.player.username}!")


await client.plugins.load(GreetingExtension())

Protocol Contract (For Java Plugin Authors)

Expected API behavior:

  • Bearer token auth for HTTP and WebSocket
  • WebSocket action: auth.validate
  • HTTP endpoint: GET /api/v1/auth/validate
  • HTTP endpoint: POST /api/v1/rpc
  • WebSocket event envelope support

Request envelope:

{
  "type": "request",
  "id": "uuid",
  "action": "minecraft.get_players",
  "payload": {}
}

Response envelope:

{
  "type": "response",
  "id": "uuid",
  "status": "ok",
  "data": {}
}

Event envelope:

{
  "type": "event",
  "event": "player_join",
  "data": {
    "player": {
      "uuid": "3b5e4f2d-8e34-4ad1-848f-b9d66fd07a4f",
      "username": "Alex",
      "health": 20.0,
      "world": "world",
      "location": {"x": 0.0, "y": 64.0, "z": 0.0}
    }
  }
}

Development

Run tests:

pytest

Run lint:

ruff check .

Repository Layout

craftcord/
docs/
examples/
tests/

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

craftcord-0.1.2.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

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

craftcord-0.1.2-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file craftcord-0.1.2.tar.gz.

File metadata

  • Download URL: craftcord-0.1.2.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for craftcord-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d03e33cec43187e5b1ce280301208286b34d0045a128e7412a9bf04198ed6122
MD5 d87b82f87eeb8db8005ed8feef613a6f
BLAKE2b-256 f7822175437b741b56924f26b8aeece44a709bef5759e1abf11b9d97c3eecb05

See more details on using hashes here.

Provenance

The following attestation bundles were made for craftcord-0.1.2.tar.gz:

Publisher: ci.yml on rytisltu09/Craftcord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file craftcord-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: craftcord-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for craftcord-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6cf9fb7bec0a3ca071d078b9d485e2fc363459ce57dcef749ab38f1dab8e81da
MD5 9349a9671f59d924ad204d66223daeb6
BLAKE2b-256 3aceb4479955727c42666d31543da5e2a8e3829e7dfc07241cf3bb96b08f7bd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for craftcord-0.1.2-py3-none-any.whl:

Publisher: ci.yml on rytisltu09/Craftcord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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