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

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.1.tar.gz (15.8 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.1-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: craftcord-0.1.1.tar.gz
  • Upload date:
  • Size: 15.8 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.1.tar.gz
Algorithm Hash digest
SHA256 7b1497dd182fe23e363cfea9d92904f95006edcd06a3ab13423468cb36772abc
MD5 07b98f4490cb5ab4e05bd41d0445c3e5
BLAKE2b-256 ca4feb0060cdfcc8b0db743bfb4e86830bc5eb6fd5d4599dbe8661bea941cc01

See more details on using hashes here.

Provenance

The following attestation bundles were made for craftcord-0.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: craftcord-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 15.9 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 69416cdee0275c9dda0a94f36d0701bf5eb8ea3f924bcc34ccaa58466b422729
MD5 1ba39d3e2d4457c516f683d4a0ca063c
BLAKE2b-256 81c4a4e2412a3dc627b597dddea2eb3314c09a5b7e19d070a0d497e8a62ee85e

See more details on using hashes here.

Provenance

The following attestation bundles were made for craftcord-0.1.1-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