The tmc CLI - The Modding Community

Noch Nicht Veröffentlicht

tmc ist ein Kommandozeilen-Client für unsere öffentliche Content-API. Er erstellt, bearbeitet und löscht deine Assets, Mods, Server, Artikel, Communities, Sammlungen und Gruppen — und weil die API genau dafür benutzt wird, lädt er Dateien hoch und veröffentlicht Releases in einem Befehl.

Python 3.10+Keine AbhängigkeitenMIT-lizenziert

tmc ist noch nicht veröffentlicht. Es liegt nicht auf PyPI und hat kein öffentliches Repository — heute installiert man es aus einem Quellcode-Checkout, und diese Seite beschreibt, was das Werkzeug schon kann, statt einen Start anzukündigen.

install.sh
# From the source checkout — there is nothing to build
pip install .
pip install '.[fast]'   # optional: cryptography, for faster signing
tmc --version       # tmc 1.1.0

# Keys are made under Account → API Keys
tmc auth login --token tmc_xxxxxxxxxxxx
tmc auth whoami

# …or read public items with no key at all
tmc mod list --anon --app 4 -o json

Ein einziges Paket aus der Standardbibliothek — nichts zu bauen und nichts aufzulösen — und jeder Befehl, jedes Flag und jeder Exit-Code steht in der Doku.

Releases

Der Grund, Überhaupt Ein Werkzeug Zu Haben

Ein Release über die rohe API zu schneiden sind vier Requests in einer bestimmten Reihenfolge: Dateien hochladen, ihre IDs einsammeln, den bereits vorhandenen Release-Satz lesen und dann den neuen zurückschreiben, ohne die anderen zu stören. release publish ist genau diese Abfolge.

publish.sh
# Upload the files, attach them, write the release — one command
tmc release publish --mod 5 \
  --version 1.2.0 \
  --title "Bug fixes" \
  --content-file CHANGELOG.md \
  --file 'dist/*.zip' --file dist/checksums.txt

# Everything on the item, without re-sending the item
tmc release list  --mod 5
tmc release files --mod 5 --version 1.2.0

Erneut Ausführen Aktualisiert

Dieselbe --version zweimal aktualisiert dieses Release und führt die neuen Dateien in dessen Satz zusammen. Deine anderen Releases werden nie angefasst, und ein verstecktes Release bleibt versteckt.

Globs, Gebündelt

Übergib --file 'dist/*.zip' und so viele Dateien, wie du hast; das Limit von zwanzig Uploads pro Request wird für dich gehandhabt.

Große Dateien Werden Gestreamt

Ein 1-GB-Upload wird stückweise von der Platte gelesen, nicht in den Speicher. Alles über dem Größenlimit deines Schlüssels wird gemeldet, bevor es gesendet wird.
Was Es Tut

Alles, Was Die API Kann, Ausbuchstabiert

Ein Befehl pro Sache, die du im Browser tun würdest — und ein paar, die du dort nicht tun wolltest: Massenbearbeitungen, Pipelines und geskriptete Releases.

Überhaupt Keine Abhängigkeiten

Python 3.10+ und die Standardbibliothek. Leg es auf eine Build-Maschine oder einen Gameserver ohne Paketindex und es läuft. cryptography wird zum Signieren benutzt, falls es zufällig installiert ist, sonst eine mitgelieferte RFC-8032-Implementierung — in beiden Fällen dieselben Signaturen.

Beide Authentifizierungsmodi

Bearer-tmc_-Schlüssel oder Ed25519-signierte Assertions, bei denen du den privaten Schlüssel behältst und wir immer nur die öffentliche Hälfte speichern.

Eine Grammatik Für Jeden Typ

Dieselben fünf Verben — list, get, create, update, delete — auf allen vierzehn Typen, von denen zwölf einen eigenen Befehl bekommen. tmc content <typ> ist die einheitliche Form und der einzige Weg zu den eigenständigen Typen release und media.

Beziehungen Ohne Alles Neu Zu Senden

Tags, Medien, Releases, Links, Quellen und Sammlungseinträge werden für sich verwaltet, also heißt einen Screenshot hinzufügen nicht, das ganze Objekt neu zu schreiben.

Massenweise, Innerhalb Jeder Grenze

Erstelle oder bearbeite aus einer JSON-Datei beliebiger Länge. Jede Servergrenze — 25 pro Schreibvorgang, 100 pro Löschung, 200 Beziehungsmitglieder, 500 Schlüssel beim Löschen einer Beziehung, 20 Upload-Teile — wird für dich gebündelt, und ein Teilfehler nennt das Element, das fehlschlug, damit du fortsetzen statt neu anfangen kannst.

Tippfehler Lokal Abgefangen

Feldnamen werden gegen eine lokale Kopie der API-Schemata geprüft, samt Beinahe-Treffer: „mod“ hat kein Feld „tgs“. Meintest du „tags“? tmc schema mod gibt die Feldliste aus, gegen die geprüft wird.

Für Pipes Gebaut

Sieben Ausgabeformate — table, json, jsonl, csv, tsv, yaml, ids — mit --field, um nur die gewünschten Spalten zu behalten. Daten auf stdout, Fortschritt auf stderr, und tmc completion bash|zsh|fish für die Shell, in der du gerade bist.

Rate-Limits Erledigt

Bei einem 429 wird genau so lange gewartet, wie die API es verlangt, bis maximal --retry-wait-max, und dann gesagt, wie lange noch bleibt, statt einen Build hängen zu lassen. Backoff gilt nur für idempotente Methoden — ein POST wird nie stillschweigend wiederholt.
Zugangsdaten

Schlüssel, Profile Und Die Öffentliche Hälfte

Melde dich einmal an, und die Zugangsdaten landen in ~/.config/tmc/config.json mit Modus 0600 — oder übergib sie über die Umgebung, dann wird die Platte gar nicht angefasst. Ein Profil pro Site oder pro Schlüssel, und --anon für die Hälfte der API, die überhaupt keinen Schlüssel braucht.

auth.sh
# A bearer key, or an Ed25519 key you hold the private half of
tmc auth login --token tmc_xxxxxxxxxxxx
tmc auth login --jwt --key-id tmcak_xxxxxxxx --private-key ~/keys/tmc.pem

# A second key on the same site — a scoped one for scripts
tmc auth login --profile ci \
  --base-url https://moddingcommunity.com --token tmc_…
tmc auth use ci

# Which key is active, and what the server lets it do
tmc auth whoami
tmc auth doctor

# …or no key at all
tmc mod list --anon --app 4 -o json

Ein Profil Pro Site Oder Schlüssel

--profile benennt eines, tmc auth use wechselt den Standard, und jeder gespeicherte Wert hat einen Umgebungs-Zwilling — TMC_TOKEN, TMC_KEY_ID, TMC_PRIVATE_KEY_FILE, TMC_BASE_URL, TMC_PROFILE.

Frag Nach, Was Ein Schlüssel Wirklich Darf

auth whoami ermittelt die echten Rechte des Schlüssels mit drei bewusst harmlosen Sonden — einem Lesen, einem Erstellen, das nicht validieren kann, und einem Löschen einer leeren ID-Liste. Es wird nichts erstellt oder gelöscht; --read-only sendet nur das Lesen.

Ein Doktor Für Die Einrichtung

auth doctor meldet, welches Signatur-Backend im Einsatz ist, ob die Rechte deiner Konfigurationsdatei sicher sind und ob die Site überhaupt antwortet — die drei Dinge, die man vor dem Debuggen einer Pipeline wissen will.

Lesen Ganz Ohne Schlüssel

--anon liest die öffentliche Zusammenfassung von sieben Typen ohne Authorization-Header — ein wirklich anderer Endpunkt, also verweigert es Schreibvorgänge, bevor der Request rausgeht, verwirft die Filter, die es dort nicht gibt, statt sie wie Treffer aussehen zu lassen, und stuft sich nie stillschweigend auf einen gespeicherten Schlüssel hoch. --set apiPublic=false ist der Weg, ein Objekt daraus zu entfernen.
Beziehungen

Vier Verben, Die Sagen, Was Sie Tun

Das gefährliche ist set: In dieser API bedeutet ein PUT auf eine Beziehung „das ist jetzt die vollständige Menge“, also löscht ein PUT mit einem einzigen Mitglied alles andere am Objekt. Die CLI hält die vier auseinander und warnt, bevor sie das zerstörerische sendet.

Befehl Methode Bedeutet
tmc rel add POST Diese hinzufügen, alles andere lassen
tmc rel set PUT Das ist jetzt die vollständige Menge
tmc rel rm DELETE Die genannten entfernen
tmc rel clear DELETE Alle entfernen
relations.sh
# Add two tags. The rest of the item is untouched
tmc tags add mod 5 pvp vanilla

# Upload a screenshot and attach it in one step
tmc media add mod 5 --file shot.png --title Screenshot

# Read one relation back
tmc rel get mod 5 releases

# …and the one that REPLACES the whole gallery
tmc rel set mod 5 media --from-file gallery.json
Automatisierung

Gemacht Für CI

Baue dein Projekt, schneide ein Release und lade seine Dateien bei jedem Tag hoch. Die Zugangsdaten kommen aus der Umgebung, also wird auf einem Runner nichts auf die Platte geschrieben.

release.yml
- name: Publish to TMC
  env:
    TMC_TOKEN: ${{ secrets.TMC_TOKEN }}
  run: |
    tmc release publish --mod 42 \
      --version "${GITHUB_REF_NAME#v}" \
      --content-file CHANGELOG.md \
      --file 'dist/*.zip'

# Clean pipes: data on stdout, progress on stderr
tmc mod list --mine --all -o ids | xargs -n1 tmc mod get -o json

Nichts Auf Einen Runner Geschrieben

Die Zugangsdaten kommen aus der Umgebung, also wird kein Profil angelegt und nichts überlebt den Job. Ein JWT-Schlüssel kann eine Secret-Datei bleiben, die der Runner einhängt — wir halten immer nur seine öffentliche Hälfte.

Exit-Codes Mit Bedeutung

2 Benutzung, 3 Auth, 4 nicht gefunden, 5 Validierung, 6 Rate-Limit, 7 Server, 8 Netzwerk — damit eine Pipeline „nochmal versuchen“ von „reparier deinen Schlüssel“ unterscheiden kann.

Nie Von Einem Veralteten Build Blockiert

Ein Feld, das das Werkzeug noch nicht kennt, geht mit --allow-unknown-fields trotzdem durch, und tmc raw sendet überhaupt jeden Request.

Gegen Das Echte Getestet

75 Tests fahren die tatsächliche CLI gegen ein prozessinternes Mock der API über einen echten Socket — beide Auth-Modi, das Bündeln, die Beziehungssemantik und den Retry-Pfad.

Schlüssel Findest Du Unter Konto → API-Schlüssel

Ein Schlüssel ist kostenlos, in einem Moment erstellt und trägt Lese-/Schreib-/Löschrechte, Ablaufdatum, IP-Allowlists und ein eigenes Rate-Limit — ein Schlüssel, den du einem Build-Server gibst, kann also genau eine Sache tun. Jeder Befehl, jedes Flag und jeder Exit-Code steht in der Doku.

Ein Schlüssel ist heute schon nützlich — die API läuft und die Doku ist geschrieben. tmc selbst ist weiterhin unveröffentlicht: noch kein PyPI-Paket und kein öffentliches Repository, also bleibt es bis dahin ein Quellcode-Checkout.