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 an async Python SDK for talking to Minecraft Paper servers through CraftCordPlugin.

It provides a clean API for requests and live events over HTTP or WebSocket, so your app can focus on behavior instead of protocol plumbing.

Note:

What Changed

CraftCord no longer ships a built-in Discord adapter layer.

Use CraftCord as your Minecraft transport/event SDK, and wire Discord behavior directly in your own bot runtime (for example, discord.py).

This keeps the SDK simpler and avoids framework-specific abstractions.

Features

  • Async-first API
  • HTTP and WebSocket transports
  • Typed Minecraft models
  • Event dispatcher with typed events + GenericEvent fallback
  • Built-in command registry/invocation
  • Python-side plugin manager
  • Framework-agnostic integration pattern for Discord bots and other Python apps

Installation

pip install craftcord

If your application uses discord.py, install it in your app environment:

pip install discord.py

Quick Start

Environment Variables

export CRAFTCORD_HOST="127.0.0.1"
export CRAFTCORD_PORT="8080"
export CRAFTCORD_TOKEN="your-api-token"
export CRAFTCORD_TRANSPORT="ws"

Minimal Client

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() -> list[str]:
        players = await client.minecraft.players()
        return [p.username for p in players]

    await client.start()


asyncio.run(main())

Discord Integration (Direct)

CraftCord emits typed events you can handle directly and forward to Discord with your own bot.

Example: send a Discord embed when Minecraft emits server_start.

import discord
from discord.ext import commands

from craftcord import Client
from craftcord.minecraft.events import ServerStartEvent

bot = commands.Bot(command_prefix="!", intents=discord.Intents.default())
craft = Client(host="127.0.0.1", port=8080, token="secret")
DEFAULT_CHANNEL_ID = 123456789012345678


@craft.event("server_start")
async def on_server_start(event: ServerStartEvent) -> None:
    channel = bot.get_channel(DEFAULT_CHANNEL_ID)
    if channel is None:
        return

    embed = discord.Embed(
        title="Minecraft Server Started",
        description="The server is now online.",
        color=discord.Color.green(),
        timestamp=event.timestamp,
    )
    embed.add_field(name="Version", value=event.version, inline=True)
    await channel.send(embed=embed)

For a full working example, see examples/basic_bot.py.

Core API

Common Minecraft operations:

await client.minecraft.players()
await client.minecraft.server_info()
await client.minecraft.send_message("Hello from CraftCord")
await client.minecraft.execute("time set day")
await client.minecraft.kick("Steve", reason="Rule violation")
await client.minecraft.ban("Steve", reason="Griefing")

Register event handlers:

@client.on("player_join")
async def on_join(event) -> None:
    print(event.player.username)

Built-in typed event names:

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

Unknown events are delivered as GenericEvent.

Transport Choice

WebSocket transport (default):

  • Best for bots, dashboards, and real-time event streams.
export CRAFTCORD_TRANSPORT="ws"

HTTP transport:

  • Best for scripts and one-off request/response workflows.
export CRAFTCORD_TRANSPORT="http"

Network Binding and Reachability

CraftCordPlugin bind behavior is configured on the Java plugin side:

  • bindMode=local binds to 127.0.0.1
  • bindMode=global binds to 0.0.0.0
  • host= overrides bindMode

Your Python SDK host must be a reachable destination from the SDK process.

Do not use 0.0.0.0 as CRAFTCORD_HOST.

Example targets:

Troubleshooting

Connection refused or timeout checklist:

  1. Ensure CraftCordPlugin is running.
  2. Confirm token and port match plugin config.
  3. Confirm CRAFTCORD_HOST points to a reachable address.
  4. Do not use 0.0.0.0 as client host.
  5. Check firewalls, routing, and reverse proxy forwarding.

WebSocket reconnect loop checklist:

  1. Verify host, port, and token.
  2. Verify plugin is reachable from the client machine.
  3. If you only need request/response, switch to HTTP transport.

discord.py integration checklist:

  1. Enable Message Content Intent when needed.
  2. Ensure bot permissions include reading and sending messages.
  3. Verify channel ID and command prefix.

Plugin System

Load reusable Python plugins (extensions):

class GreetingPlugin:
    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(GreetingPlugin)

Protocol

CraftCord uses authenticated JSON-RPC style messages over HTTP and WebSocket.

Authentication model:

  • Bearer token
  • HTTP validation endpoint
  • WebSocket authentication handshake

Endpoint paths:

  • /api/v1/auth/validate
  • /api/v1/rpc
  • /ws

Sample request payload:

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

Development

pytest
ruff check .

Repository Structure

craftcord/
├── craftcord/
├── docs/
├── examples/
└── tests/

License

MIT

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-1.0.0.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

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

craftcord-1.0.0-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for craftcord-1.0.0.tar.gz
Algorithm Hash digest
SHA256 61225f2109e265a18aa8c8c42112f46094dd1cc73d61f73b42dbd0b658a6f2b8
MD5 d19c9d0d8eda9bead76e55b574cfe54b
BLAKE2b-256 541aae8faec591f948cf94e129405850f8119adc293d1b4340da9ad1a24319b5

See more details on using hashes here.

Provenance

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

File metadata

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

File hashes

Hashes for craftcord-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 390984403d6d07c716304248e8ac5e2429ac4aa5f5f79c60618f23f961e3dc42
MD5 acb648130990c2fa1be21c39b48d579f
BLAKE2b-256 3962f52dfe2fcab52e2e0cb6f66808483405e04cace9e5836b251e7b047a02fa

See more details on using hashes here.

Provenance

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