Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

marionette-mc

Typed asyncio client for the Marionette Minecraft bridge. Python 3.11+, protocol 2, package 0.1.0a1 (independent of mod versions). MIT, confirmed by the project owner. This is an unpublished alpha candidate; no package upload or published-consumer acceptance is claimed.

From this checkout, install for development with python -m pip install -e ./python. After an explicitly authorized publication, consumers must pin marionette-mc==0.1.0a1 rather than silently accepting new prereleases. A local wheel installation verifies packaging only.

import asyncio
from marionette_mc import connect

async def main():
    async with connect(required_capabilities=["bridgeSafety", "playerState"]) as client:
        print(client.hello)
        await client.configure(rate_divisor=1, sections=["player"])
        print(await client.next_observation(timeout=5))
        try:
            await client.input(forward=True)
            await asyncio.sleep(0.2)
        finally:
            await client.release()

asyncio.run(main())

Run only against a disposable, rendered world with a clear walking area. Context exit closes the session even on exceptions/cancellation; controller loss triggers the mod's release-all safety. release() explicitly clears queued controller intent. Neither sending nor closing is an action acknowledgment. Keep the asyncio event loop responsive: move blocking/CPU work off the loop. The websockets library answers server pings automatically; there is no reconnect or command replay policy in this package. Native connections omit Origin and ignore environment proxies. Current local trust has no authentication.

API and outcomes

  • connect(uri=..., role="controller" | "observer", sections=..., required_capabilities=...) yields one Client after validating protocol 2 and required capability flags. client.require(...) checks additional capabilities. Missing flags are unsupported.
  • input(forward=..., back=..., left=..., right=..., jump=..., sneak=..., sprint=..., attack=..., use=..., tap=["jump", "attack", "use"], hotbar=0) applies only supplied fields. Methods check capabilities for taps/interactions and guard observer roles.
  • look(yaw=..., pitch=..., mode="instant" | "delta" | "smooth", speed=...) or look(mode="smooth", x=..., y=..., z=..., speed=...) controls the camera. Success is silent; use observations for convergence. No completion event exists.
  • configure(rate_divisor=1, sections=["player"]) selects this session's stream. sections=[] requests cadence-only frames. Omitted arguments leave settings unchanged.
  • inventory(op, menu=..., source=..., destination=..., hotbar=..., all=False, animated=False, timeout=...) supports open/inspect/move/swap/equip/drop/close. Obtain menu_ref(result["menu"]) from a recent inspect before mutations. Results describe client prediction, not authoritative server acknowledgment.
  • next_observation(timeout=...) / observations() consume latest observations. A slow consumer skips frames; observations_coalesced counts replacements.
  • next_reply(timeout=...) / replies() consume uncorrelated errors and late or unmatched inventory results. Awaited inventory errors raise ServerError with the original typed .error; uncorrelated errors remain in this reliable stream. Applications should service it alongside their observation/gameplay loop.
  • wait_closed() returns local Disconnect(code, reason, cause); Disconnected.outcome carries it when an operation/stream cannot continue. This is a Python lifecycle outcome, never a fabricated protocol event. Reliable replies already received can be drained after closure. Observations cannot be read as live state after disconnect.

TypedDict wire models (including nested player, effects, inventory menus/slots, commands and all four incoming types) live in marionette_mc.messages. Decoding checks required fields/types and retains unknown additive fields. ServerError, VersionError, CapabilityError, RoleError, CapacityError and InvalidMessage (the latter in messages) distinguish failure causes. Opening failures preserve websockets/OS exceptions; handshake timeout is TimeoutError.

Each inventory call uses a unique session ID. RequestTimeout.request_id lets a caller identify the later reply. Timeout or task cancellation does not cancel server work. Late results/errors go to next_reply(); do not blindly resend a move/drop. A disconnect leaves outstanding outcomes unknown. Re-inspect state in a separately chosen new session before deciding what to do. To stop current controller work, use release or close, understanding already-completed world changes cannot be undone. An unmatched reply is not proof that it is safe to retry.

Default bounds: 64 reliable replies, 32 pending requests, one latest observation, 128 KiB incoming frames, 16 transport frames, 32 KiB write high-water mark, 64 KiB outgoing commands, 5-second connect/hello timeout, 10-second request/write timeout and 1-second close timeout. Queue limits are configurable integers 1–1024. Reliable overflow closes with an explicit local CapacityError cause; replies beyond capacity are lost with unknown outcomes. The reader never waits for a consumer queue and therefore continues servicing WebSocket liveness. Streams have one logical consumer each; concurrent readers compete rather than receive broadcasts.

Local verification and publication candidate

From the repository root:

python3.11 -m venv .venv
.venv/bin/pip install -r python/requirements-dev.txt
.venv/bin/pip install --no-build-isolation -e ./python
.venv/bin/python -m unittest discover -s python/tests -v
(cd python && ../.venv/bin/mypy)
.venv/bin/python -m build --no-isolation python
./gradlew build

requirements-dev.txt pins build/test dependencies, including transitives. The shared tests/fixtures/protocol2.json ships in the sdist; Java's PythonCompatibilityTest parses those commands and compares its actual message builders to the same expected frames. Offline tests use real local WebSockets. The wheel contains only the client, type marker and license/metadata. The sdist also contains self-contained offline tests and fixtures. Neither includes worlds, private harnesses, consumer policy, caches, credentials or mod build output.

Before publishing: review exact distributions and SHA256 hashes, resolve release prerequisites (including the project's authentication/provisioning gate), establish PyPI project ownership/credentials, obtain explicit upload authorization, then upload only the reviewed artifacts. Registration alone is not upload permission. After publication, a clean environment must install the exact published version and pass rendered observation/movement/release smoke acceptance. Local wheel or sdist success does not satisfy that milestone or consumer integration gate.

Metadata

Release files for marionette-mc 0.1.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for marionette-mc 0.1.0a1
File Size Uploaded
marionette_mc-0.1.0a1.tar.gz 15.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for marionette-mc 0.1.0a1
File Interpreter ABI Platform
marionette_mc-0.1.0a1-py3-none-any.whl Python 3 none any Details

Total release size: 28.4 kB

Release files / marionette_mc-0.1.0a1.tar.gz

Download URL marionette_mc-0.1.0a1.tar.gz
Size 15.8 kB
Tags Source
SHA-256 checksum
How to use checksums
de7f464ebbac2676920a41a2981280671b2640badb382665c3a8f25b2410a180
BLAKE2b-256 checksum
How to use checksums
eba1727ad190954e75fcaaf5cefbcd14e21e3d0ee08aa1c9677a8a025e9ee893
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / marionette_mc-0.1.0a1-py3-none-any.whl

Download URL marionette_mc-0.1.0a1-py3-none-any.whl
Size 12.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d084f4fd104b2b200724359c9dff0bc3b6572ad6deab0c327f5760aa63c2beca
BLAKE2b-256 checksum
How to use checksums
ce24b6de82827fd260442c1a9268875371050cf69467faa243980af839103f11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.1.0a1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page