<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: boluo</title>
    <description>The latest articles on DEV Community by boluo (@buluo).</description>
    <link>https://dev.to/buluo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4138987%2F11d42b82-4828-41a1-81f4-f7d86612f3a4.png</url>
      <title>DEV Community: boluo</title>
      <link>https://dev.to/buluo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/buluo"/>
    <language>en</language>
    <item>
      <title>🔍 4 Befehle, mit denen ich prüfe, ob mein Claude-Code-Gateway wirklich läuft</title>
      <dc:creator>boluo</dc:creator>
      <pubDate>Wed, 30 Sep 2026 06:23:12 +0000</pubDate>
      <link>https://dev.to/buluo/4-befehle-mit-denen-ich-prufe-ob-mein-claude-code-gateway-wirklich-lauft-ob0</link>
      <guid>https://dev.to/buluo/4-befehle-mit-denen-ich-prufe-ob-mein-claude-code-gateway-wirklich-lauft-ob0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI-Hinweis:&lt;/strong&gt; Beim Strukturieren und Formulieren dieses Beitrags habe ich ein Sprachmodell eingesetzt. Alle Befehle, Ausgaben und Versionsnummern habe ich auf meiner eigenen Maschine tatsächlich ausgeführt und überprüft.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code lässt sich auf ein eigenes Inference-Gateway umbiegen – es sind genau &lt;strong&gt;6 Umgebungsvariablen&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude --version&lt;/code&gt; beweist &lt;strong&gt;nur&lt;/strong&gt;, dass der Client installiert ist. Nichts weiter. 🙃&lt;/li&gt;
&lt;li&gt;Die beiden Base-URLs sind &lt;strong&gt;nicht symmetrisch&lt;/strong&gt;: &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; ohne &lt;code&gt;/v1&lt;/code&gt;, &lt;code&gt;OPENAI_BASE_URL&lt;/code&gt; mit.&lt;/li&gt;
&lt;li&gt;Das Panel in der Desktop-App ist standardmäßig &lt;strong&gt;unsichtbar&lt;/strong&gt; – es steckt hinter dem Developer Mode.&lt;/li&gt;
&lt;li&gt;Der eigentliche Test ist ein echter Request mit &lt;code&gt;max_tokens=16&lt;/code&gt;. Alles davor ist Aufwärmen.&lt;/li&gt;
&lt;li&gt;Nach der Konfiguration ein &lt;strong&gt;neues&lt;/strong&gt; Terminal-Fenster. Im alten ist „command not found" das &lt;em&gt;erwartete&lt;/em&gt; Ergebnis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemessen habe ich alles auf:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2.1.283&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v24.21.0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;Windows 10 Pro 22H2 (build 19045)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;nicht installiert&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Die letzte Zeile ist kein Tippfehler. Dazu komme ich am Ende. 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  Das Problem: „installiert" ist nicht „läuft"
&lt;/h2&gt;

&lt;p&gt;Ich wollte die Inference-Requests von Claude Code auf ein anderes Gateway umleiten. Die Konfiguration selbst war unspektakulär – ein paar Umgebungsvariablen, fertig.&lt;/p&gt;

&lt;p&gt;Gehangen hat es danach.&lt;/p&gt;

&lt;p&gt;Ich tippe &lt;code&gt;claude --version&lt;/code&gt;, bekomme eine saubere Versionsnummer zurück und denke: passt. 🎉&lt;/p&gt;

&lt;p&gt;Nur beweist das genau eine Sache – dass der Client auf der Platte liegt. Ob der Endpoint erreichbar ist, ob der Key gültig ist, ob das Modell überhaupt antwortet? Davon ist &lt;strong&gt;nichts&lt;/strong&gt; geprüft.&lt;/p&gt;

&lt;p&gt;Das ist der Punkt, an dem die meisten Anleitungen aufhören. Und genau da fangen die Probleme an.&lt;/p&gt;




&lt;h2&gt;
  
  
  0️⃣ Was hier technisch überhaupt passiert
&lt;/h2&gt;

&lt;p&gt;Falls du das zum ersten Mal machst, kurz das Mentalmodell – ohne das sind die Fehlermeldungen später nicht lesbar.&lt;/p&gt;

&lt;p&gt;Claude Code ist ein Client. Er muss zwei Dinge wissen: &lt;strong&gt;wohin&lt;/strong&gt; der Request geht und &lt;strong&gt;womit&lt;/strong&gt; er sich ausweist. Beides liest er beim Start aus dem Environment (oder, in der Desktop-App, aus den App-Settings). Dann baut er einen ganz normalen HTTPS-Request und schickt ihn los.&lt;/p&gt;

&lt;p&gt;Mehr passiert nicht. Keine Magie, kein Daemon, keine Registrierung irgendwo.&lt;/p&gt;

&lt;p&gt;Deshalb gibt es auch genau drei Stellen, an denen es schiefgehen kann:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Der Wert steht nicht da, wo der Client hinschaut.&lt;/strong&gt; → Er nimmt den Default oder gar nichts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Der Wert steht da, ist aber falsch formatiert.&lt;/strong&gt; → Der Request geht raus und läuft ins Leere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Der Wert ist korrekt, aber die Gegenseite lehnt ab.&lt;/strong&gt; → Key abgelaufen, Quota leer, Modell unbekannt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Und jetzt der Clou: Die Befehle, die alle als Erstes tippen, prüfen ausschließlich Kategorie 1 – und nicht mal die vollständig. Kategorie 2 und 3 sind für sie unsichtbar.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ Erst rausfinden, in welcher Situation du bist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ausgabe&lt;/th&gt;
&lt;th&gt;Welches Skript&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Versionsnummer kommt&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;configure&lt;/code&gt; – schreibt nur die Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command not found&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;setup&lt;/code&gt; – installiert erst die Dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gute Nachricht: die &lt;code&gt;configure&lt;/code&gt;-Variante hat einen &lt;strong&gt;Hard-Check&lt;/strong&gt; eingebaut. Sie sucht als Erstes &lt;code&gt;claude&lt;/code&gt; im PATH und bricht sofort ab, wenn sie nichts findet. Falsch gewählt = nichts kaputt, das Skript verweigert einfach den Dienst. 👍&lt;/p&gt;

&lt;p&gt;Umgekehrt gilt das nicht. &lt;code&gt;setup&lt;/code&gt; auf einer schon eingerichteten Maschine installiert die Dependencies neu. Also: diesen Schritt nicht überspringen.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Skript laufen lassen
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk17mhz3xmo1olr3jhyvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk17mhz3xmo1olr3jhyvp.png" alt="Die Installationsbefehle für beide Plattformen" width="799" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claude Code ist schon da – nur konfigurieren:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/xujfcn/crazyrouter-claude-code/main/configure.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/xujfcn/crazyrouter-claude-code/main/windows/configure.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Noch gar nichts da? Im selben Repo-Verzeichnis liegt die Full-Install-Variante – &lt;strong&gt;einfach &lt;code&gt;configure&lt;/code&gt; im Befehl durch &lt;code&gt;setup&lt;/code&gt; ersetzen&lt;/strong&gt; (&lt;code&gt;setup.sh&lt;/code&gt; bzw. &lt;code&gt;windows/setup.ps1&lt;/code&gt;). Die installiert erst Git, Node.js und Claude Code und schreibt dann die Config.&lt;/p&gt;

&lt;p&gt;Umgekehrt bitte nicht: &lt;code&gt;setup&lt;/code&gt; auf einer schon eingerichteten Maschine installiert die Dependencies neu.&lt;/p&gt;

&lt;p&gt;⚠️ Öffne die Links vorher im Browser und lies drüber. Das hat nichts damit zu tun, wer das Skript geschrieben hat – bei allem in der Form &lt;code&gt;| bash&lt;/code&gt; oder &lt;code&gt;| iex&lt;/code&gt; gehört das dazu. Die Details unten habe ich genau so aus dem Quellcode gelesen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Das Skript fragt genau drei Dinge
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Frage&lt;/th&gt;
&lt;th&gt;Pflicht&lt;/th&gt;
&lt;th&gt;Verhalten&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;td&gt;ja&lt;/td&gt;
&lt;td&gt;Die Eingabe wird &lt;strong&gt;nicht angezeigt&lt;/strong&gt;. Nach dem Einfügen bleibt der Bildschirm leer – das ist normal, nicht dreimal reinpasten 😅 Leer lassen = Fehler und Abbruch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Base URL&lt;/td&gt;
&lt;td&gt;nein&lt;/td&gt;
&lt;td&gt;Default vorhanden, entfernt einen überzähligen Slash am Ende automatisch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modell&lt;/td&gt;
&lt;td&gt;nein&lt;/td&gt;
&lt;td&gt;Default vorhanden, später jederzeit änderbar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Zwei Dinge, die man nur durchs Lesen des Quellcodes erfährt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beim Token gibt es einen &lt;strong&gt;Format-Precheck&lt;/strong&gt; (Prefix &lt;code&gt;sk-&lt;/code&gt; / &lt;code&gt;cr-&lt;/code&gt; / &lt;code&gt;rk-&lt;/code&gt;), aber ein Mismatch erzeugt nur eine Warnung und &lt;strong&gt;blockt nicht&lt;/strong&gt;. Warning gesehen? Erst weiterlesen, ob danach ein echter Fehler kommt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Die Skript-Ausgabe ist auf Englisch.&lt;/strong&gt; Ein Bildschirm voll Englisch ist also erwartbar.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Was passiert, wenn man mittendrin abbricht?
&lt;/h3&gt;

&lt;p&gt;Habe ich getestet, weil ich es wissen wollte. Ich habe das Skript nicht-interaktiv laufen lassen: Es lädt sauber runter, meldet &lt;code&gt;[OK] Claude Code detected: 2.1.283&lt;/code&gt;, kommt zum Token-Prompt – und steigt dort mit &lt;strong&gt;Exit-Code 1&lt;/strong&gt; aus, weil in einem nicht-interaktiven Subprozess nichts zu lesen ist.&lt;/p&gt;

&lt;p&gt;Danach habe ich alle sechs Variablen einzeln kontrolliert: &lt;strong&gt;keine einzige verändert.&lt;/strong&gt; 🙌&lt;/p&gt;

&lt;p&gt;Das Skript sammelt also erst alle drei Antworten und schreibt dann. Ein Abbruch hinterlässt keine halbe Config. Praktisch heißt das: Wenn etwas schiefgeht, einfach nochmal starten – kein manuelles Aufräumen nötig.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unattended auf dem Server
&lt;/h3&gt;

&lt;p&gt;Wenn du nicht interaktiv sein kannst, Token vorher ins Environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CRAZYROUTER_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"dein-token"&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/xujfcn/crazyrouter-claude-code/main/configure.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Bare-Metal-Server ohne Claude Code? Auch hier &lt;code&gt;configure&lt;/code&gt; → &lt;code&gt;setup&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Ein Detail, das dieses Skript richtig macht: &lt;code&gt;curl | bash&lt;/code&gt; läuft üblicherweise in einer &lt;strong&gt;Non-Login-Shell&lt;/strong&gt;, und die kennt die npm-Global-Pfade oft nicht. Das Skript sucht deshalb aktiv in &lt;code&gt;/usr/local/bin&lt;/code&gt;, &lt;code&gt;~/.local/bin&lt;/code&gt; und &lt;code&gt;~/.npm-global/bin&lt;/code&gt; nach &lt;code&gt;claude&lt;/code&gt;. Und selbst wenn es nichts findet, schreibt es die Config trotzdem fertig und gibt Diagnose-Output aus – statt auf halber Strecke zu sterben.&lt;/p&gt;

&lt;h3&gt;
  
  
  Noch ein Wort zum Windows-&lt;code&gt;setup&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Weil das der Teil ist, der auf älteren Maschinen entscheidet, ob es klappt: Das Skript versucht zuerst &lt;strong&gt;winget&lt;/strong&gt;. Ist kein winget da, fällt es auf Direct Download zurück (Node.js über einen fixierten LTS-Installer, Git über das offizielle Release). Und für PowerShell 5.1 aktiviert es explizit TLS 1.2 und 1.3 – ohne das scheitern die Downloads auf unpatchten Systemen mit einer Fehlermeldung, die überhaupt nicht nach TLS aussieht.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Nachsehen, was tatsächlich geschrieben wurde
&lt;/h2&gt;

&lt;p&gt;Sechs Umgebungsvariablen auf User-Ebene:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ANTHROPIC_BASE_URL     Gateway-Adresse (OHNE /v1)
ANTHROPIC_AUTH_TOKEN   Token
ANTHROPIC_MODEL        Default-Modell
CLAUDE_MODEL           Default-Modell
OPENAI_API_KEY         derselbe Token
OPENAI_BASE_URL        Gateway-Adresse (MIT /v1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Warum zwei Sets? Claude Code liest die Anthropic-Konvention, viele OpenAI-kompatible Tools die andere. Ein Token deckt beide Seiten ab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Und hier kommt die Falle&lt;/strong&gt;, die mich am meisten gekostet hat: die beiden Adressen sind nicht symmetrisch. Bei &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; gehört nur die Root-Domain rein – der Client baut &lt;code&gt;/v1/messages&lt;/code&gt; selbst dran. Wer das &lt;code&gt;/v1&lt;/code&gt; manuell ergänzt, landet bei &lt;code&gt;/v1/v1/messages&lt;/code&gt; – und das ist falsch. Ein Gateway, das strikt nach Pfad routet, antwortet darauf mit 404. Darauf verlassen kann man sich aber nicht: mein eigenes habe ich nachgemessen, es liefert auf diesen Pfad weiterhin 200. Der zweite Fall ist der unangenehmere, weil auf dem Bildschirm gar kein Fehler auftaucht.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OPENAI_BASE_URL&lt;/code&gt; braucht das &lt;code&gt;/v1&lt;/code&gt; dagegen &lt;strong&gt;zwingend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Das Perfide daran: In diese Falle tappen ausgerechnet die ordentlichen Leute. Zwei Felder zeigen auf denselben Server, also bringt man sie in dieselbe Form. Der Instinkt ist völlig richtig – der Fall ist nur asymmetrisch. Es gibt keinen Linter dafür, weil syntaktisch beide Werte einwandfrei sind. Ergebnis: Claude Code läuft, die anderen Tools kommen nicht durch – meist mit 404, aber was genau zurückkommt, hängt vom Gateway ab. Oder umgekehrt. 🤦&lt;/p&gt;

&lt;h3&gt;
  
  
  Wo die Werte landen
&lt;/h3&gt;

&lt;p&gt;Unter Windows direkt als User-Umgebungsvariablen. Unter macOS/Linux in einer env-Datei im Home-Verzeichnis plus eine Load-Zeile in der Shell-Startdatei.&lt;/p&gt;

&lt;p&gt;Nettes Detail: die Startdatei wird nach der &lt;strong&gt;echten Login-Shell&lt;/strong&gt; ausgewählt, nicht danach, welche Datei existiert. Auf Servern liegt gerne mal eine ungenutzte &lt;code&gt;.bashrc&lt;/code&gt; rum, während der Login tatsächlich über zsh läuft – wer dort reinschreibt, schreibt ins Nichts. &lt;code&gt;echo $SHELL&lt;/code&gt;, bevor du irgendwas anfasst.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternative: pro Projekt
&lt;/h3&gt;

&lt;p&gt;Wer das System-Environment nicht anfassen will, legt eine &lt;code&gt;.claude/settings.json&lt;/code&gt; ins Projekt-Root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_BASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.crazyrouter.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk-dein-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_MODEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-opus-4-8"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gilt nur für dieses Projekt – super, wenn verschiedene Repos über verschiedene Gateways laufen sollen. Aber: Das ist genauso Klartext wie die Umgebungsvariablen, nur deutlich leichter versehentlich zu committen. Wenn du diesen Weg gehst, &lt;strong&gt;sofort&lt;/strong&gt; in die &lt;code&gt;.gitignore&lt;/code&gt;. 🔐&lt;/p&gt;

&lt;h3&gt;
  
  
  Die drei Wege im Vergleich
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Skript&lt;/th&gt;
&lt;th&gt;Desktop-GUI&lt;/th&gt;
&lt;th&gt;&lt;code&gt;settings.json&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;ganze Maschine&lt;/td&gt;
&lt;td&gt;nur Desktop-App&lt;/td&gt;
&lt;td&gt;nur dieses Projekt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL-Normalisierung&lt;/td&gt;
&lt;td&gt;ja (Trailing Slash weg)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;nein&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;nein&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gut für&lt;/td&gt;
&lt;td&gt;neue Maschine, Server, Wiederholbarkeit&lt;/td&gt;
&lt;td&gt;Einzelplatz, gelegentlich ändern&lt;/td&gt;
&lt;td&gt;mehrere Gateways parallel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commit-Risiko&lt;/td&gt;
&lt;td&gt;niedrig&lt;/td&gt;
&lt;td&gt;niedrig&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;hoch&lt;/strong&gt; ⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  4️⃣ Desktop-App: das versteckte Panel
&lt;/h2&gt;

&lt;p&gt;Mit der Desktop-App brauchst du die Umgebungsvariablen nicht anzufassen. Aber &lt;strong&gt;das Panel ist standardmäßig nicht sichtbar&lt;/strong&gt;. Es hängt unter dem Developer Mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Help → Troubleshooting → Enable Developer Mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Danach startet die App einmal neu, und erst dann erscheint im Menü oben links ein Eintrag &lt;code&gt;Developer&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9p2qmvto68j6v842y8oc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9p2qmvto68j6v842y8oc.jpg" alt="Der Developer-Eintrag nach Aktivierung des Developer Mode" width="236" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Darunter dann &lt;code&gt;Configure third-party inference&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fddn17pedsnagjv7pb46f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fddn17pedsnagjv7pb46f.jpg" alt="Der Einstieg zur Third-Party-Inference-Konfiguration" width="691" height="714"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Links &lt;code&gt;Connection&lt;/code&gt; wählen. So sieht es bei mir konfiguriert aus:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwv6vn5kglra0qti658hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwv6vn5kglra0qti658hp.png" alt="Das Gateway-Konfigurationspanel" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ Fairness-Hinweis: Auf meiner Maschine war der Developer Mode von vorher schon aktiv. Dass das Panel ohne ihn &lt;strong&gt;nicht&lt;/strong&gt; sichtbar ist, habe ich aus der offiziellen Doku – selbst nachgestellt habe ich es nicht. Den Menüpfad gebe ich als dokumentiert weiter, nicht als reproduziert.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Feld für Feld:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Credential kind&lt;/strong&gt; → &lt;code&gt;Static API key&lt;/code&gt;. Bedeutet: Credential-Quelle festnageln. Danach wird &lt;strong&gt;nicht mehr&lt;/strong&gt; auf Login-Status oder Umgebungsvariablen zurückgefallen. Für das Debugging ist das wertvoll, weil es das Szenario „ich dachte, ich gehe über mein Gateway, in Wahrheit bin ich auf den Default zurückgefallen" komplett ausschließt. Kehrseite: Wenn Requests trotz Konfiguration weiter zur alten Adresse gehen – hier zuerst schauen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway base URL&lt;/strong&gt; → Das GUI &lt;strong&gt;räumt das Format nicht auf&lt;/strong&gt;, anders als das Skript. Kein Slash am Ende, kein selbst ergänztes &lt;code&gt;/v1&lt;/code&gt;, keine Query-Parameter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway API key&lt;/strong&gt; → Nach dem Einfügen aufs Auge-Icon klicken und drüberschauen. Aus dem Browser kopierte Keys schleppen gerne ein unsichtbares Leerzeichen mit, und der Fehler sieht danach genau wie „Key ungültig" aus.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway auth scheme&lt;/strong&gt; → &lt;code&gt;bearer&lt;/code&gt; oder &lt;code&gt;x-api-key&lt;/code&gt;. Bestimmt, ob als &lt;code&gt;Authorization: Bearer xxx&lt;/code&gt; oder als &lt;code&gt;x-api-key: xxx&lt;/code&gt; gesendet wird.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artifact preview iframe origin&lt;/strong&gt; → leer lassen, wenn du keinen speziellen Bedarf hast.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reihenfolge der Buttons beachten: &lt;strong&gt;zuerst oben rechts &lt;code&gt;Test connection&lt;/code&gt;, und erst wenn das durch ist, unten rechts &lt;code&gt;Apply Changes&lt;/code&gt;.&lt;/strong&gt; Der Test läuft auch auf noch nicht angewendeten Werten durch – „getestet und Fenster zu" ist also eine zuverlässige Methode, nichts zu speichern. 💾&lt;/p&gt;

&lt;p&gt;Noch eine Debug-Richtung: links gibt es außerdem &lt;code&gt;Sandbox &amp;amp; workspace&lt;/code&gt; und &lt;code&gt;Egress&lt;/code&gt;. Die Desktop-App sandboxt Tool-Traffic. Wenn alle Felder stimmen und &lt;code&gt;Test connection&lt;/code&gt; trotzdem scheitert, lohnt ein Blick in die Liste der erlaubten Egress-Hosts. Bei mir ist das nie aufgetreten (die aktuelle Config geht direkt durch) – ich notiere es nur als Richtung, nicht als reproduzierten Fall.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Die vier Befehle 🎯
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg1976a73z0r78l2yvf7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg1976a73z0r78l2yvf7s.png" alt="Die Ausgabe der vier Prüfbefehle" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eins – ist der Client da?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beweist: Im PATH liegt eine ausführbare Datei. Das ist der komplette Geltungsbereich. Bei mir: &lt;code&gt;2.1.283&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zwei – ist die Runtime da?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beweist: Node.js ist installiert. Auch schon alles. Bei mir: &lt;code&gt;v24.21.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drei – ist die Config wirklich geschrieben?&lt;/strong&gt; Nicht „ich habe sie eingegeben", sondern „ich habe sie zurückgelesen".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;env&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'ANTHROPIC|OPENAI'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="s1"&gt;'ANTHROPIC_BASE_URL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'ANTHROPIC_AUTH_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'ANTHROPIC_MODEL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'CLAUDE_MODEL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'OPENAI_API_KEY'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'OPENAI_BASE_URL'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{0,-22} {1}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'User'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zwei Dinge prüfen: alle sechs vorhanden, und &lt;code&gt;/v1&lt;/code&gt; nur bei &lt;code&gt;OPENAI_BASE_URL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vier – Endpoint, Key und Modell gleichzeitig&lt;/strong&gt; ⬅️ der eigentliche Test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.crazyrouter.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"anthropic-version: 2023-06-01"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "claude-opus-4-8",
    "max_tokens": 16,
    "messages": [{"role": "user", "content": "reply with: pong"}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;max_tokens: 16&lt;/code&gt; ist Absicht: Der Inhalt der Antwort ist irrelevant, relevant ist nur, dass es eine gibt. Eine erfolgreiche Antwort etabliert drei Fakten gleichzeitig – Endpoint erreichbar, Key akzeptiert, Modell antwortet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warum die ersten drei genau dort blind sind, wo es zählt
&lt;/h3&gt;

&lt;p&gt;Alle drei inspizieren den Zustand deiner lokalen Maschine. Keiner von ihnen redet mit dem Gateway.&lt;/p&gt;

&lt;p&gt;Diese Failure Modes sind für sie also &lt;strong&gt;komplett unsichtbar&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔑 Key abgelaufen&lt;/li&gt;
&lt;li&gt;📉 Quota leer&lt;/li&gt;
&lt;li&gt;🏷️ Modell-ID wird vom Gateway nicht erkannt&lt;/li&gt;
&lt;li&gt;🌐 Proxy oder VPN routet die Domain woandershin&lt;/li&gt;
&lt;li&gt;🚧 Gateway-Domain nicht in der Egress-Whitelist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alles davon geht durch Befehl 1–3 ohne eine einzige Warnung und fällt erst bei Nummer 4 um.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dass die ersten drei durchgehen und der vierte scheitert, ist also nicht der Randfall – es ist die Normalform dieses Fehlers.&lt;/strong&gt; Drei Viertel der üblichen Prüfung sind strukturell unfähig, das zu finden, was am wahrscheinlichsten kaputt ist. Wenn du nur einen Befehl machst: mach den vierten.&lt;/p&gt;

&lt;p&gt;Zum Auth-Header noch: ich habe mit &lt;strong&gt;beiden&lt;/strong&gt; Varianten je einen echten Request geschickt. Auf diesem Gateway antworten &lt;code&gt;bearer&lt;/code&gt; &lt;strong&gt;und&lt;/strong&gt; &lt;code&gt;x-api-key&lt;/code&gt; mit 200. Das ist aber keine allgemeine Regel – die meisten Gateways akzeptieren nur eines, und die Fehlermeldung bei der falschen Wahl ist von „Key kaputt" praktisch nicht zu unterscheiden. Doku des Anbieters lesen.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Fehlermeldungen, die ich gesehen habe (und was sie wirklich bedeuten)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;„command not found" direkt nach erfolgreicher Konfiguration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Umgebungsvariablen greifen nur für &lt;strong&gt;neu gestartete&lt;/strong&gt; Prozesse. Im alten Fenster zu prüfen scheitert immer, und das ist das erwartete Ergebnis, keine Fehlkonfiguration. Fenster komplett schließen; ein neuer Tab reicht unter Windows nicht. Die erste Next-Step-Zeile des Skripts ist übrigens genau &lt;code&gt;Open a NEW PowerShell window&lt;/code&gt; – geht in der englischen Ausgabe nur leicht unter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;„no token provided" – obwohl der Token gesetzt ist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Das hat mich am meisten Zeit gekostet, und ich war schon dabei, einen neuen Key auszustellen. Der Key war völlig in Ordnung. Die Prüfung lief in einem Subprozess, und in dessen Environment war &lt;code&gt;$env:ANTHROPIC_AUTH_TOKEN&lt;/code&gt; einfach leer.&lt;/p&gt;

&lt;p&gt;Aus Serversicht sind die zwei Fälle nicht unterscheidbar: Es kam ein Request ohne Key an. Woher soll der Server wissen, ob du keinen hast oder ob er unterwegs verloren ging? Die Meldung war präzise &lt;strong&gt;und&lt;/strong&gt; schlimmer als nutzlos, weil sie mit voller Überzeugung auf die falsche Hypothese zeigte.&lt;/p&gt;

&lt;p&gt;In PowerShell lieber explizit aus der User-Scope lesen statt auf &lt;code&gt;$env:&lt;/code&gt; zu vertrauen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ANTHROPIC_AUTH_TOKEN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'User'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;404, obwohl die URL richtig aussieht&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/v1&lt;/code&gt; doppelt. Siehe oben. Das ist die häufigste Ausprägung der Asymmetrie.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validierungsfehler bei der Endpoint-Adresse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aus einem Share-Link kopiert? Dann hängt am Ende vermutlich ein &lt;code&gt;?utm_source=...&lt;/code&gt;. Im Browser egal, als API-Endpoint bestenfalls ignoriert, schlimmstenfalls Validierungsfehler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git-Installation scheitert – alles hinwerfen?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nein. Auf dieser Maschine ist &lt;strong&gt;Git überhaupt nicht installiert&lt;/strong&gt;, trotzdem läuft &lt;code&gt;claude&lt;/code&gt; und trotzdem geht Befehl vier durch. &lt;strong&gt;Git ist keine Runtime-Dependency von Claude Code.&lt;/strong&gt; Das Full-Setup-Skript installiert es für die Arbeit danach, nicht als Voraussetzung.&lt;/p&gt;

&lt;p&gt;Und weil das die zweite Stelle war, an der ich mir selbst reingefallen bin: Ich hatte „kein Git" kurzzeitig als Ursache meines Problems abgehakt und angefangen, von dieser Annahme aus zu debuggen. Genau derselbe Fehler wie mit der Versionsnummer – ich habe einen Zustand erschlossen, den ich nicht beobachtet hatte, und bin dann selbstsicher weitergelaufen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Die drei Dinge, die ich mir gemerkt habe:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; ohne &lt;code&gt;/v1&lt;/code&gt;, &lt;code&gt;OPENAI_BASE_URL&lt;/code&gt; mit. Vereinheitlichen ist falsch – und gibt nicht zwangsläufig einen 404.&lt;/li&gt;
&lt;li&gt;Nach der Konfiguration ein &lt;strong&gt;neues&lt;/strong&gt; Terminal-Fenster.&lt;/li&gt;
&lt;li&gt;Endpoint-Adressen müssen sauber sein – keine Query-Parameter aus kopierten Links.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Und das übergeordnete:&lt;/strong&gt; Die Disziplin liegt nicht in den Checks, sondern in der Bereitschaft, laut zu sagen, was ein Signal eigentlich beweist. Nicht worauf es hindeutet, sondern was es etabliert. Eine Versionsnummer etabliert, dass eine Datei auf der Platte liegt. Ein grünes Dashboard etabliert, dass ein Check gelaufen ist und unter einem Threshold blieb. Grüne Tests etablieren, dass die Assertions erfüllt sind, die &lt;strong&gt;du&lt;/strong&gt; geschrieben hast.&lt;/p&gt;

&lt;p&gt;Keins davon heißt „läuft". Alle sind deutlich billiger zu bekommen als „läuft" – deshalb sammeln sie sich an, und deshalb lassen wir sie das Ergebnis ersetzen.&lt;/p&gt;

&lt;p&gt;Und zur Sicherheit: Token nicht ins Git committen, nicht in Screenshots reinrutschen lassen, beim Maschinenwechsel den alten Key widerrufen. Klingt banal – mir ist aber genau während dieses Debuggings aufgefallen, wie oft mein Key einfach im Klartext auf meinem eigenen Bildschirm lag. 🔐&lt;/p&gt;




&lt;h2&gt;
  
  
  Und bei euch? 💬
&lt;/h2&gt;

&lt;p&gt;Mich interessiert vor allem eines: &lt;strong&gt;welcher der vier Befehle ist bei euch zuletzt gescheitert?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ich habe den Verdacht, dass Nummer vier bei fast allen der Stolperstein ist – aber aus unterschiedlichen Gründen. Falsches Auth-Scheme? Proxy dazwischen? Modell-ID, die das Gateway nicht kennt? Schreibt es in die Kommentare, ich ergänze gern eine Fehlerliste.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>cli</category>
      <category>devops</category>
    </item>
    <item>
      <title>Codex CLI unter Windows</title>
      <dc:creator>boluo</dc:creator>
      <pubDate>Tue, 29 Sep 2026 08:15:16 +0000</pubDate>
      <link>https://dev.to/buluo/codex-cli-unter-windows-5a0a</link>
      <guid>https://dev.to/buluo/codex-cli-unter-windows-5a0a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fpmqp3erqg75qwc0v35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fpmqp3erqg75qwc0v35.png" alt="Installation, Anmeldung und Überprüfung eines Codex-Projekts" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;„Die Installation ist fertig“ ist eine schlechte Abnahmebedingung für einen Coding-Agenten. Sie sagt nichts darüber aus, ob der richtige Dienst angesprochen wird oder ob das Ergebnis im Projekt landet. Für diese Anleitung beginnen wir deshalb mit einer kleinen Spezifikation: Eine lokale HTML-Seite soll einen Zähler anzeigen, ihn erhöhen und wieder auf null setzen können.&lt;/p&gt;

&lt;p&gt;Wir richten dafür Codex CLI unter Windows ein und verbinden den Client über einen eigenen Provider mit Crazyrouter. Die Verbindung bleibt Teil der technischen Aufgabe: Schlüsselquelle, Modell-ID und Responses-Endpunkt werden ausdrücklich geprüft. Preisversprechen, Empfehlungen für unbekannte Konten oder behauptete erfolgreiche Modellaufrufe ersetzen diese Prüfung nicht.&lt;/p&gt;

&lt;p&gt;Der Text ist auf Deutsch; die Protokollfelder und Befehle bleiben in ihrer tatsächlichen Schreibweise. Du kannst den gesamten Ablauf ohne Framework nachvollziehen. Eine installierte CLI brauchst du nicht erneut einzurichten, nur um jeden Absatz der Anleitung abzuarbeiten.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Erst festlegen, woran die Aufgabe scheitern könnte
&lt;/h2&gt;

&lt;p&gt;Bevor ein Agent etwas baut, sollte klar sein, was du selbst überprüfen kannst. Für unseren Zähler gelten drei sichtbare Anforderungen: Beim Öffnen steht dort null; ein Klick erhöht den Wert um eins; Zurücksetzen stellt unabhängig vom bisherigen Wert null her. Speichern zwischen Browserbesuchen gehört ausdrücklich nicht zum Auftrag.&lt;/p&gt;

&lt;p&gt;Diese Begrenzung macht einen Unterschied. Würden wir gleichzeitig Speicherung, Anmeldung und Synchronisation verlangen, könnte ein Fehler an vielen zusätzlichen Stellen entstehen. Ein einzelnes HTML-Dokument reicht dagegen aus, um Dateizugriff, generierten Code und Browserinteraktion zu untersuchen.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prüfung&lt;/th&gt;
&lt;th&gt;Beobachtung, die wir benötigen&lt;/th&gt;
&lt;th&gt;Was dadurch noch offenbleibt&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Programmstart&lt;/td&gt;
&lt;td&gt;Version und Hilfe erscheinen&lt;/td&gt;
&lt;td&gt;Zugang zum Modell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API-Probe&lt;/td&gt;
&lt;td&gt;Ein kurzer Text wird tatsächlich geliefert&lt;/td&gt;
&lt;td&gt;Vollständiges Agentenverhalten&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI-Dialog&lt;/td&gt;
&lt;td&gt;Antwort über den vorgesehenen Provider&lt;/td&gt;
&lt;td&gt;Schreibberechtigung&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datei&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;index.html&lt;/code&gt; liegt im Übungsordner&lt;/td&gt;
&lt;td&gt;Korrekte Bedienung&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interaktion&lt;/td&gt;
&lt;td&gt;Erhöhen und Zurücksetzen funktionieren&lt;/td&gt;
&lt;td&gt;Eignung für andere Projekte&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Die Tabelle enthält Sollbedingungen, keine vorab ausgefüllten Testergebnisse. Ohne eigene gültige Zugangsdaten lässt sich der entfernte Teil nicht als bestanden markieren. Auch ein lokal simulierter HTTP-Responder könnte lediglich die Form eines Skripts prüfen, nicht dein Konto authentifizieren.&lt;/p&gt;

&lt;p&gt;Lege dir eine kurze Notiz mit Version, Modell-ID und beobachtetem Ergebnis an. Damit kannst du nach einer Änderung dieselbe Aufgabe wiederholen. Die API-Key-Zeichenfolge gehört nicht in diese Notiz.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Den Windows-Unterbau vorbereiten
&lt;/h2&gt;

&lt;p&gt;Wenn du noch nie mit PowerShell gearbeitet hast, führe diesen Abschnitt vollständig durch. Er erklärt auch Eingabeaufforderung und Zeilenumbrüche. Wenn die Werkzeuge bereits vorhanden sind, reichen die beschriebenen Versions- und Pfadprüfungen.&lt;/p&gt;

&lt;h3&gt;
  
  
  PowerShell öffnen und Befehle richtig einfügen
&lt;/h3&gt;

&lt;p&gt;Suche im Windows-Startmenü nach PowerShell und öffne zunächst ein normales Fenster. Im Windows Terminal kannst du ein PowerShell-Profil auswählen. Ein Administratorfenster ist keine allgemeine Voraussetzung für jede Zeile dieser Anleitung; zusätzliche Rechte werden erst behandelt, wenn ein bestimmter Einrichtungsschritt sie verlangt.&lt;/p&gt;

&lt;p&gt;Die Zeile mit &lt;code&gt;PS&lt;/code&gt; und dem aktuellen Pfad ist die Eingabeaufforderung. Sie gehört nicht zum Befehl. Kopiere ausschließlich den Inhalt eines Codeblocks und drücke Enter.&lt;/p&gt;

&lt;p&gt;Beginne mit einer Zeile, warte auf das Ergebnis und fahre dann fort. Wenn zwei Installationsbefehle ohne Zeilenumbruch aneinandergeraten, entsteht daraus kein gültiger längerer Befehl. Bei mehrzeiligen Blöcken mit Klammern muss dagegen der vollständige Block zusammenbleiben.&lt;/p&gt;

&lt;p&gt;Zum Einfügen funktioniert häufig &lt;code&gt;Strg + V&lt;/code&gt;, alternativ die rechte Maustaste oder &lt;code&gt;Strg + Umschalt + V&lt;/code&gt;. Erscheint statt des normalen Prompts ein &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, erwartet PowerShell möglicherweise das Ende einer Zeichenkette oder eines Ausdrucks. Mit &lt;code&gt;Strg + C&lt;/code&gt; kannst du diese unvollständige Eingabe abbrechen und sauber neu beginnen.&lt;/p&gt;

&lt;p&gt;Die Endung &lt;code&gt;.cmd&lt;/code&gt; verwenden wir bewusst. npm installiert unter Windows verschiedene Starter. PowerShell kann sonst einen Starter mit &lt;code&gt;.ps1&lt;/code&gt; auswählen, dessen Ausführung durch eine Richtlinie blockiert wird. Mit &lt;code&gt;npm.cmd&lt;/code&gt; und &lt;code&gt;codex.cmd&lt;/code&gt; benennen wir ausdrücklich die Windows-Befehlsdatei. Dafür muss nicht pauschal die Skriptrichtlinie gelockert werden.&lt;/p&gt;

&lt;p&gt;Eine weitere Grenze wirst du später sehen: In PowerShell stehen Systembefehle, im geöffneten Codex-Dialog stehen deine Aufgaben in natürlicher Sprache. Vor jeder Eingabe lohnt sich ein kurzer Blick darauf, welches der beiden Programme gerade auf Text wartet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js installieren und die Umgebung kontrollieren
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Bereits vorhandene Installation erkennen
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Führe die beiden Zeilen einzeln aus. Wenn Node und npm jeweils eine Versionsnummer liefern, kannst du direkt zum nächsten Abschnitt wechseln. Es ist nicht nötig, eine zweite Kopie zu installieren, nur weil ein Screenshot eine andere Nummer zeigt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6ng89h2v3pjar71tfuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6ng89h2v3pjar71tfuj.png" alt="PowerShell findet den Befehl node noch nicht" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Die Oberfläche im Bild ist chinesisch. Relevant ist die fehlgeschlagene Programmsuche, noch nicht die spätere API-Verbindung.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wird &lt;code&gt;node&lt;/code&gt; nicht erkannt, ist entweder Node.js noch nicht vorhanden oder das Fenster kennt den neuen Suchpfad noch nicht. An dieser Stelle helfen Änderungen an Modellnamen und API-Schlüsseln nicht, denn die Anfrage erreicht noch keinen Anbieter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Den passenden Windows-Download auswählen
&lt;/h4&gt;

&lt;p&gt;Öffne die &lt;a href="https://nodejs.org/en/download?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=codex_crazyrouter&amp;amp;utm_content=devto_de_20260929__node" rel="noopener noreferrer"&gt;Node.js-Downloadseite&lt;/a&gt;. Wähle LTS, Windows und die passende Architektur. Ob dein Rechner x64 oder ARM64 verwendet, lässt sich in den Windows-Systeminformationen beziehungsweise unter „Info“ nachsehen.&lt;/p&gt;

&lt;p&gt;Gesucht ist ein Installationspaket mit der Endung &lt;code&gt;.msi&lt;/code&gt;. Befehle für Docker beschreiben eine andere Betriebsart und gehören nicht zu diesem Windows-Ablauf. Du musst weder einen Container starten noch dafür erst eine zusätzliche Entwicklungsumgebung aufbauen.&lt;/p&gt;

&lt;p&gt;Lass im Installationsassistenten npm und die Einbindung in PATH aktiviert. Die zusätzlichen Werkzeuge zum Kompilieren nativer Module sind für diese Einführung nicht erforderlich. Lies die angebotenen Komponenten, statt vorsorglich jede optionale Entwicklungsumgebung mitzuinstallieren.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ein neues Fenster ist Teil der Prüfung
&lt;/h4&gt;

&lt;p&gt;Schließe nach der Installation das bisherige Terminal und öffne es neu. Bei einem Terminal innerhalb eines Editors kann ein Neustart des Editors nötig sein, weil dessen Prozesse die alte Umgebung weitergeben.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nslkh5dbfk1j2883rtb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nslkh5dbfk1j2883rtb.png" alt="Node.js liefert eine Versionsnummer zurück" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Die abgebildete Nummer ist ein Beispiel. npm muss zusätzlich geprüft werden.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wiederhole die Versionsabfragen. Bleibt die Programmsuche erfolglos, kontrolliere den tatsächlichen Installationsordner und PATH. Ändere dabei nicht gleichzeitig Netzwerk, Schlüssel und Provider, sonst lässt sich eine Verbesserung später keinem einzelnen Schritt zuordnen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Codex installieren und den Starter finden
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;openai/codex&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;codex.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;codex.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--help&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Warte, bis die npm-Installation beendet ist, bevor du die beiden Prüfkommandos ausführst. &lt;code&gt;-g&lt;/code&gt; richtet das Paket als globales npm-Werkzeug ein. Es bedeutet nicht, dass der gesamte spätere Arbeitsablauf mit Administratorrechten laufen soll. &lt;code&gt;latest&lt;/code&gt; bezeichnet ein Veröffentlichungslabel und keine dauerhaft feste Versionsnummer.&lt;/p&gt;

&lt;p&gt;Eine Ausgabe mit &lt;code&gt;codex-cli&lt;/code&gt; bestätigt, dass sich der Starter ausführen lässt. Die Hilfe zeigt außerdem, welche Unterbefehle die installierte Ausgabe kennt. Keine dieser beiden Abfragen testet bereits eine Modellantwort.&lt;/p&gt;

&lt;p&gt;Hinweise mit &lt;code&gt;notice&lt;/code&gt; oder &lt;code&gt;WARN&lt;/code&gt; sollten gelesen werden, sind aber nicht automatisch ein Abbruch. Für eine Diagnose sind der eigentliche Fehlertext und die anschließende Funktionsprüfung aussagekräftiger als die bloße Farbe oder Sprache der Ausgabe.&lt;/p&gt;

&lt;p&gt;Wenn Windows den Starter nach der Installation weiterhin nicht findet, öffne ein frisches Fenster und prüfe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;codex.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ErrorAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SilentlyContinue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der npm-Präfix zeigt den globalen Werkzeugordner. Öffne ihn im Explorer und suche &lt;code&gt;codex.cmd&lt;/code&gt;. Existiert die Datei, aber die erste Abfrage findet nichts, kontrolliere den Benutzer-Path. Fehlt auch die Datei, lies die Installationsergebnisse erneut.&lt;/p&gt;

&lt;p&gt;Ergänzt wird der Ordner, nicht der vollständige Dateiname. Bestehende Path-Einträge bleiben erhalten. Nach einer Änderung ist wiederum ein neuer Terminalprozess nötig. Bei mehreren Installationsmethoden kann später &lt;code&gt;Get-Command codex* -All&lt;/code&gt; helfen, versehentlich verwendete ältere Starter zu erkennen.&lt;/p&gt;

&lt;p&gt;Danach sollte Windows die CLI starten können. Noch wurde kein Zähler gebaut und keine bestimmte API-Berechtigung nachgewiesen. Halte diese lokale Prüfung im Protokoll getrennt von den nächsten Schritten.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Einen eindeutigen Arbeitsbereich für das Experiment schaffen
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$projectDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'CodexProjects\crazyrouter-demo'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$projectDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-Null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Set-Location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$projectDir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-Location&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prüfe den ausgegebenen Pfad. Für einen Test ist der Ort ein Teil der Ausgangsbedingungen: Eine Datei in einem anderen Ordner zählt nicht automatisch als Ergebnis dieser Aufgabe. Der Verzeichnisname richtet übrigens keinen Provider ein; er dient nur deiner Organisation.&lt;/p&gt;

&lt;p&gt;Existiert die Übungsmappe bereits, sieh zuerst nach ihren Dateien. &lt;code&gt;-Force&lt;/code&gt; in diesem Block löscht ihren Inhalt nicht. Wenn dort eine ältere &lt;code&gt;index.html&lt;/code&gt; liegt, entscheide bewusst, ob sie ersetzt werden darf. Sonst könntest du nach einer gescheiterten Neuerstellung versehentlich eine alte funktionierende Seite prüfen.&lt;/p&gt;

&lt;p&gt;Lass das PowerShell-Fenster offen. &lt;code&gt;$projectDir&lt;/code&gt; und die folgenden Testvariablen gelten für diese Sitzung. Ein neuer Tab erhält nicht automatisch die temporären Werte aus einem anderen Tab. Bei einem Neustart führst du die benötigten Vorbereitungsblöcke erneut aus.&lt;/p&gt;

&lt;p&gt;Du musst Codex nicht in diesen Ordner installieren. Die globale npm-Installation stellt das Werkzeug bereit; der aktuelle Ordner bestimmt das Projekt. Diese Unterscheidung bleibt auch später bei mehreren Projekten nützlich.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Die Testdaten aus dem eigenen Konto beziehen
&lt;/h2&gt;

&lt;p&gt;Der API-Key und der Modellbezeichner sind Eingaben, keine Konstanten aus einem Screenshot. Erzeuge einen eigenen Token im Crazyrouter-Konto und kontrolliere dessen Rechte. Die &lt;a href="https://docs.crazyrouter.com/en/quickstart?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=codex_crazyrouter&amp;amp;utm_content=devto_acceptance_20260929__provider" rel="noopener noreferrer"&gt;Dokumentation zum Einstieg&lt;/a&gt; beschreibt den Zugang zur Tokenverwaltung.&lt;/p&gt;

&lt;p&gt;Eine ChatGPT-Anmeldung ist kein Ersatz für diesen Token. Ebenso gehört ein offizieller OpenAI-Key zu einem anderen Kontozugang. Für unseren Provider müssen Aussteller, Zieladresse und Authentifizierungsverfahren zusammenpassen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$crazySecret&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Read-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Crazyrouter API Key'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-AsSecureString&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CRAZYROUTER_API_KEY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Net.NetworkCredential&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crazySecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Password&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazySecret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Remove-Variable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crazySecret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CRAZYROUTER_API_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die verdeckte Eingabe verhindert, dass der rohe Wert als Bestandteil eines eingegebenen Shellbefehls erscheint. Die abschließende boolesche Abfrage meldet nur, ob der Prozess einen Wert enthält. Sie kann auch bei einer falschen Zeichenfolge &lt;code&gt;True&lt;/code&gt; liefern.&lt;/p&gt;

&lt;p&gt;Der Schlüssel wird hier nicht dauerhaft in den Benutzereinstellungen gespeichert. Das ist für diesen Versuch beabsichtigt: Wir wissen genau, aus welcher vorbereiteten Sitzung Codex gestartet werden soll. Umgebungsvariablen sind deshalb trotzdem kein universeller Geheimnisspeicher; veröffentliche ihren Inhalt nicht.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$crazyBase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://api.crazyrouter.com/v1'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazyHeaders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CRAZYROUTER_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazyModels&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$crazyBase&lt;/span&gt;&lt;span class="s2"&gt;/models"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crazyHeaders&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazyModels&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ExpandProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$crazyModel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Read-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Model ID'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Übernimm bei &lt;code&gt;Model ID&lt;/code&gt; die genaue Kennung eines für Codex und Responses geeigneten Modells, das dein Konto nutzen darf. Ein Eintrag im Modellkatalog belegt zunächst nur die Sichtbarkeit. Die Probe im nächsten Teil muss zeigen, ob eine konkrete Generierung funktioniert.&lt;/p&gt;

&lt;p&gt;Besonders bei gemischten Katalogen lohnt sich dieser Zwischenschritt: Ein Bild- oder Audiomodell ist nicht allein wegen seines Vorkommens in der Liste für einen Coding-Agenten geeignet. Ein vertrauter Produktname wiederum muss nicht der exakte API-Identifier sein.&lt;/p&gt;

&lt;p&gt;Wenn du nach der Abfrage den Key austauschst, führe auch die Zuweisung des Headers erneut aus. &lt;code&gt;$crazyHeaders&lt;/code&gt; enthält den Wert vom Zeitpunkt seiner Erstellung. Es ist keine dauerhafte Verknüpfung, die bei jeder Änderung der Umgebungsvariable automatisch neu berechnet wird.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Die Verbindung als überprüfbare Konfiguration speichern
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$codexConfigDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CODEX_HOME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CODEX_HOME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.codex'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-Null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$codexConfigFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'config.toml'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$backupFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'yyyyMMdd-HHmmss'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.bak'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Copy-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Destination&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$backupFile&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;notepad.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$codexConfigFile&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Block sucht den Benutzerkonfigurationsort über &lt;code&gt;CODEX_HOME&lt;/code&gt; beziehungsweise den üblichen Home-Pfad. Vorhandene Inhalte bekommen eine Sicherung mit Zeitstempel. Bearbeite die betreffenden Einträge und erhalte andere Einstellungen; ein vollständiger Austausch deiner Konfiguration ist nicht nötig.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MODEL_ID_FROM_YOUR_ACCOUNT"&lt;/span&gt;
&lt;span class="py"&gt;model_provider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"crazyrouter"&lt;/span&gt;

&lt;span class="nn"&gt;[model_providers.crazyrouter]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Crazyrouter"&lt;/span&gt;
&lt;span class="py"&gt;base_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://api.crazyrouter.com/v1"&lt;/span&gt;
&lt;span class="py"&gt;env_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CRAZYROUTER_API_KEY"&lt;/span&gt;
&lt;span class="py"&gt;wire_api&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"responses"&lt;/span&gt;
&lt;span class="py"&gt;requires_openai_auth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ersetze &lt;code&gt;MODEL_ID_FROM_YOUR_ACCOUNT&lt;/code&gt; durch den eben ausgewählten Identifier. Die Eingabe in &lt;code&gt;$crazyModel&lt;/code&gt; schreibt ihn nicht von selbst in diese Datei. Für den Vergleich von direkter Anfrage und CLI müssen beide Stellen übereinstimmen.&lt;/p&gt;

&lt;p&gt;Ich würde diese Datei bei einer technischen Durchsicht mit vier Fragen lesen: Welche Tabelle wird ausgewählt? Welche Adresse steht darin? Woher kommt das Geheimnis? Welches Protokoll erwartet der Client? Die Antwort darf nicht aus dem hübschen Anzeigenamen abgeleitet werden, sondern aus den tatsächlichen Feldern.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kontrollpunkt&lt;/th&gt;
&lt;th&gt;Erwartete Beziehung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;model_provider&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entspricht dem Namen hinter &lt;code&gt;model_providers.&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base_url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API-Basis mit einmaligem &lt;code&gt;/v1&lt;/code&gt;, ohne Artikelparameter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env_key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exakter Variablenname aus dem PowerShell-Block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wire_api&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;responses&lt;/code&gt; für den hier beschriebenen Weg&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requires_openai_auth&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;false&lt;/code&gt; für den dienstspezifischen Variablenzugang&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Bei &lt;code&gt;requires_openai_auth = true&lt;/code&gt; verwendet Codex OpenAI-Authentifizierung und ignoriert &lt;code&gt;env_key&lt;/code&gt;. Das wäre eine andere Strategie. Übernimm diesen Wert daher nicht zusätzlich aus einem Beispiel für eine offizielle Anmeldung.&lt;/p&gt;

&lt;p&gt;Die ersten beiden Schlüssel gehören auf die oberste TOML-Ebene, vor Tabellenüberschriften. Doppelte Schlüssel oder wiederholte Provider-Tabellen sind kein Verfahren zum Überschreiben. Aktualisiere vorhandene Einträge und kontrolliere, dass der Editor wirklich &lt;code&gt;config.toml&lt;/code&gt; gespeichert hat, nicht &lt;code&gt;config.toml.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Provider- und Authentifizierungseinstellungen gehören hier in die Benutzerkonfiguration. Eine gleichnamige Datei im Übungsprojekt ist kein beliebiger Ersatz. Nach dem Speichern wird eine alte Sitzung beendet und neu gestartet, damit der Test nicht noch den alten Zustand verwendet.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Einen kleinen API-Smoke-Test ausführen
&lt;/h2&gt;

&lt;p&gt;Dieser Aufruf verwendet echte Kontoressourcen und kann nach den Bedingungen des Dienstes Nutzung verursachen. Er setzt die zuvor erstellten Variablen voraus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$crazyPayload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crazyModel&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Reply with OK.'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertTo-Json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Depth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;6&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$crazyResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$crazyBase&lt;/span&gt;&lt;span class="s2"&gt;/responses"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crazyHeaders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ContentType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'application/json'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crazyPayload&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazyResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crazyResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertTo-Json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Depth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der Test ist bewusst unspektakulär. Die Antwort muss keine komplizierte Lösung enthalten; wir wollen die Verbindung mit einer kleinen Eingabe beobachten. Notiere die tatsächliche Antwort-ID, den Status, einen möglichen Fehler und die vorhandene Textausgabe.&lt;/p&gt;

&lt;p&gt;Ein fehlerfreier HTTP-Transport allein erfüllt die Abnahmebedingung nicht. Wenn der zurückgegebene Inhalt eine fehlgeschlagene Verarbeitung beschreibt, bleibt der Test fehlgeschlagen. Bei einer abweichenden Antwortstruktur wird zuerst die aktuelle Dokumentation mit dem realen Körper verglichen.&lt;/p&gt;

&lt;p&gt;Diese Probe verwendet &lt;code&gt;stream = false&lt;/code&gt;. Sie ist deshalb kein vollständiger Test für das Streaming und die Werkzeuge der CLI. Aus Chat-Completions-Kompatibilität lässt sich ebenfalls nicht automatisch die gesamte benötigte Responses-Funktionalität ableiten.&lt;/p&gt;

&lt;p&gt;Wenn die Anfrage scheitert, halte die restlichen Bedingungen konstant. Ein anderer Key, eine andere Basisadresse und ein anderes Modell im selben Versuch machen den Vergleich wertlos. Beginne beim Fehlertext: 401 deutet auf die Authentifizierungsebene, 403 verlangt eine Prüfung des Ablehnungsgrunds, 404 auf Pfad oder Auswahl, 429 auf die erläuterten Limits. Keiner dieser Codes ersetzt das Lesen der Antwort.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Den Agenten starten und seine Schreibrechte einordnen
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-Location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$projectDir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;codex.cmd&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Frage zunächst: „Was ist eine HTML-Datei? Antworte in einem Satz und verwende keine Dateien oder Befehle.“ Kontrolliere außerdem, ob die Sitzung den gewünschten Provider und das Modell anzeigt. Die direkte Anfrage verwendet Skriptvariablen; die CLI verwendet ihre geladene Konfiguration. Das sind zwei verschiedene Zugriffswege, die übereinstimmen müssen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5nfpnj9cavjdmqc2wsga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5nfpnj9cavjdmqc2wsga.png" alt="Abfrage zur Windows-Sandbox bei Codex" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Die Oberfläche ist chinesisch. Lies die entsprechende Beschreibung deiner Version; Modellanzeige und Schaltflächenpositionen sind keine Empfehlung für eine bestimmte Auswahl.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bei einer Vertrauensabfrage gehört der angezeigte Pfad zur Prüfung. Wenn dort ein anderer Ordner steht, beende die Sitzung und korrigiere die Startposition. Ein Vertrauensklick auf das gesamte Benutzerprofil wäre keine genaue Umsetzung unseres begrenzten Auftrags.&lt;/p&gt;

&lt;p&gt;Für den Zähler brauchen wir genau eine lokale Datei. Eine vorgeschlagene Installation zusätzlicher Pakete sollte deshalb erklärt werden, bevor sie ausgeführt wird. Du kannst den Agenten nach betroffenen Dateien und dem Zweck eines Befehls fragen. Rechte pauschal zu erweitern ist keine Voraussetzung dieses Beispiels.&lt;/p&gt;

&lt;p&gt;Die Windows-Sandbox kann eigene Einrichtungsschritte benötigen. Beachte deren Beschreibung und die Vorgaben verwalteter Geräte. Wenn die Modellantwort ankommt, aber das Speichern verweigert wird, untersuche diese lokale Grenze. Ein neu ausgestellter API-Key ändert keine Dateiberechtigung.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Den Zähler mit konkreten Abnahmekriterien bauen lassen
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Erstelle im aktuellen Übungsordner ausschließlich index.html.
Die deutsche Seite trägt die Überschrift „Mein erster Zähler“.
Beim Laden steht der sichtbare Wert auf 0.
Ein Button „Erhöhen“ addiert pro Klick genau 1.
Ein Button „Zurücksetzen“ setzt jeden erreichten Wert auf 0.
Nutze echte HTML-Buttons, die auch mit der Tastatur bedient werden können.
Kein Speichern über Seitenaufrufe hinweg, keine externen Ressourcen oder Pakete.
CSS und JavaScript stehen in derselben Datei. Keine zusätzlichen Netzwerkaufrufe.
Melde den tatsächlich gespeicherten Pfad und nenne die manuell prüfbaren Funktionen.
Wenn Schreiben nicht möglich ist, beschreibe den Grund statt eine fertige Datei zu behaupten.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hier steckt bereits eine einfache Prüfliste im Auftrag. „Pro Klick genau eins“ verhindert eine unklare Erwartung an den Zähler. „Kein Speichern“ erklärt, warum nach einem Neuladen wieder null erscheinen soll. Ohne diesen Satz könnte ein persistenter Zähler eine plausible, aber andere Umsetzung sein.&lt;/p&gt;

&lt;p&gt;Du musst dafür noch keine Testbibliothek installieren. Bei einer kleinen Ein-Datei-Aufgabe lässt sich das Verhalten unmittelbar prüfen. Wir testen auch nicht die Geschwindigkeit verschiedener Modelle, sondern ob der definierte Auftrag erfüllt wird.&lt;/p&gt;

&lt;p&gt;Lies die Schreibanfrage und bestätige nur den passenden Zielpfad. War dort schon eine Datei vorhanden, achte auf die geplante Änderung. Nach Abschluss verlässt du den Dialog mit &lt;code&gt;/quit&lt;/code&gt; oder der angebotenen Beenden-Funktion und kehrst zum Shellprompt zurück.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\index.html&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Start-Process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\index.html&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die zweite Zeile wird erst nach einer Existenzprüfung mit &lt;code&gt;True&lt;/code&gt; ausgeführt. Ein Quelltextblock im Gespräch zählt nicht als gespeichertes Artefakt. Eine alte Datei aus einem früheren Durchlauf darf ebenfalls nicht unbemerkt das Ergebnis ersetzen.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Nicht nur den ersten Klick ausprobieren
&lt;/h2&gt;

&lt;p&gt;Eine kleine Funktion kann beim ersten Versuch richtig wirken und bei einer Wiederholung falsch reagieren. Nutze deshalb eine kurze, feste Reihenfolge:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aktion&lt;/th&gt;
&lt;th&gt;Erwartete Anzeige&lt;/th&gt;
&lt;th&gt;Warum diese Aktion dazugehört&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Seite öffnen&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Anfangszustand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zweimal erhöhen&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Mehrere Ereignisse, nicht nur ein erster Klick&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zurücksetzen&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Rückweg aus einem veränderten Zustand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nochmals zurücksetzen&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Wiederholtes Zurücksetzen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Einmal erhöhen&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Weiterarbeiten nach dem Reset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Seite neu laden&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Vereinbarter Verzicht auf Persistenz&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ergänze eine Tastaturprüfung: Tab sollte die echten Buttons erreichen, und die übliche Aktivierung sollte dieselbe Aktion auslösen. Behaupte damit keine vollständige Barrierefreiheitsprüfung; es ist eine konkrete Anforderung dieses kleinen Beispiels.&lt;/p&gt;

&lt;p&gt;Bei einem Fehler beschreibst du die Folge der Aktionen und den abweichenden Wert. „Nach zweimaligem Erhöhen steht 4 statt 2“ ist für eine Korrektur brauchbarer als „Die Seite ist falsch“. Bitte um Änderung nur an der vorhandenen Datei und wiederhole danach dieselbe Reihenfolge.&lt;/p&gt;

&lt;p&gt;Kontrolliere bei jeder Wiederholung die Adresse im Browser. Wenn zwei Dateien gleich heißen, könnte eine geöffnete alte Kopie den Eindruck erzeugen, die Korrektur sei wirkungslos. Auch die Seite selbst muss nach dem Speichern neu geladen werden.&lt;/p&gt;

&lt;p&gt;Die Abnahme endet bei unserem vereinbarten Funktionsumfang. Ein funktionierender Zähler beweist weder sichere Verarbeitung beliebiger Projekte noch Zuverlässigkeit für jede spätere Aufgabe. Das ist kein Mangel der Probe, sondern ihr klar definierter Geltungsbereich.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Fragen, die beim Wiederholen des Versuchs auftreten
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Warum ist der Schlüssel im neuen Terminal nicht vorhanden?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;CRAZYROUTER_API_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Die ursprüngliche Eingabe galt für einen Prozess. Bereite den Wert im Fenster vor, aus dem du Codex startest. Die TOML-Datei nennt die Variable, stellt aber keinen geheimen Inhalt her.&lt;/p&gt;

&lt;h3&gt;
  
  
  Muss ich bei einem npm-Timeout den API-Anbieter wechseln?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nein, der Paketdownload ist ein anderer Netzwerkweg. Prüfe Registry und Fehlermeldung. Behalte beabsichtigte Firmenkonfigurationen bei und löse Zertifikatsprobleme nicht durch pauschales Abschalten der Prüfung.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warum wird ein PowerShell-Skript blockiert?
&lt;/h3&gt;

&lt;p&gt;Kontrolliere, ob du den beschriebenen &lt;code&gt;.cmd&lt;/code&gt;-Starter aufrufst. Eine Skriptrichtlinie ist eine gesonderte Frage, gerade auf verwalteten Geräten. Für diesen Ablauf muss nicht vorsorglich jede Skriptausführung freigegeben werden.&lt;/p&gt;

&lt;h3&gt;
  
  
  Der Modellkatalog funktioniert; warum scheitert die Generierung?
&lt;/h3&gt;

&lt;p&gt;Die Operationen prüfen unterschiedliche Fähigkeiten. Lies den konkreten Generierungsfehler, prüfe Modellrechte und Responses-Verhalten. Der Katalog ist kein Ersatz für einen erfolgreichen Aufruf.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warum verwendet Codex anscheinend die alte Auswahl?
&lt;/h3&gt;

&lt;p&gt;Vergleiche Benutzerkonfigurationspfad, &lt;code&gt;CODEX_HOME&lt;/code&gt;, oberste TOML-Schlüssel und Sitzung. Danach neu starten. Die Modellvariable des Tests und die Datei werden nicht automatisch synchronisiert.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wie prüfe ich eine Aktualisierung der CLI?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;openai/codex&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;codex.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-Command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;codex&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-All&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vergleiche Version und gefundene Starter. Anschließend genügt für die erste Kontrolle wieder dieselbe kleine Aufgabe; installiere das Werkzeug nicht vor jedem Projektstart neu.&lt;/p&gt;

&lt;h3&gt;
  
  
  Funktioniert eine kopierte CMD-Zeile in PowerShell?
&lt;/h3&gt;

&lt;p&gt;Nicht zwangsläufig. Hier gilt &lt;code&gt;$env:USERPROFILE&lt;/code&gt;, nicht &lt;code&gt;%USERPROFILE%&lt;/code&gt;; für Pfade nutzen wir &lt;code&gt;Set-Location&lt;/code&gt;, nicht &lt;code&gt;cd /d&lt;/code&gt;. Die richtige Shell ist Teil der reproduzierbaren Anleitung.&lt;/p&gt;

&lt;h3&gt;
  
  
  Welche Angaben gehören zu einem Fehlerbericht?
&lt;/h3&gt;

&lt;p&gt;Version, ausgewähltes Modell, konkrete Aktion, erwartetes und beobachtetes Ergebnis sowie bereinigte Fehlermeldung. Zugangsdaten, Gerätecodes und private Projektinhalte bleiben draußen. Eine Anfrage-ID kann dem Dienst helfen, ohne dass du den Header veröffentlichst.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Einen nachvollziehbaren Abschluss festhalten
&lt;/h2&gt;

&lt;p&gt;Ein guter Abschlussbericht für dieses Experiment ist kurz: Welche lokale Version wurde verwendet, welche Konfiguration war ausgewählt und welche Prüfschritte wurden tatsächlich ausgeführt? Markiere offen gebliebene Punkte ausdrücklich als offen. Eine fehlende Berechtigung wird nicht durch eine schönere Zusammenfassung zum Erfolg.&lt;/p&gt;

&lt;p&gt;Bewahre die Konfigurationssicherung auf. Bei einem Rückwechsel beendest du die Sitzung und stellst die betroffenen Felder wieder her, statt sämtliche Authentifizierungsdaten oder den kompletten Codex-Ordner zu löschen. Für ein neues Modell oder eine neue Basisadresse wiederholst du API-Probe und CLI-Aufgabe mit übereinstimmenden Werten.&lt;/p&gt;

&lt;p&gt;Damit bleibt dieser Beitrag auch als Diskussionsgrundlage brauchbar: Nicht die allgemeine Aussage „lief bei mir“ ist interessant, sondern eine nachvollziehbare Bedingung und ihr Ergebnis. Wenn du im Kommentar einen zusätzlichen Prüfpunkt vorschlägst, beschreibe, welchen Fehler er sichtbar machen würde. Behaupte keine Messwerte, die im eigenen Versuch nicht erhoben wurden.&lt;/p&gt;

&lt;p&gt;Die Verbindung zu Crazyrouter ist hier Bestandteil eines überprüfbaren Entwicklungsablaufs. Das wiederverwendbare Ergebnis besteht aus einer verständlichen Provider-Konfiguration und einer kleinen Aufgabe, deren Erfolg du selbst beurteilen kannst.&lt;/p&gt;

&lt;p&gt;Versionsbezogene Optionen findest du in der &lt;a href="https://learn.chatgpt.com/docs/codex/cli?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=codex_crazyrouter&amp;amp;utm_content=devto_acceptance_20260929__docs" rel="noopener noreferrer"&gt;Codex-Dokumentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Redaktioneller Hinweis: Dieser Text wurde mit KI-Unterstützung ausgearbeitet und lokalisiert. Konfigurationsbeispiele und Sollwerte ersetzen keine Prüfung mit dem eigenen Dienstkonto.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codex</category>
      <category>windows</category>
      <category>powershell</category>
      <category>api</category>
    </item>
    <item>
      <title>Claude Code mit CC Switch umstellen und Verbindungsfehler eingrenzen</title>
      <dc:creator>boluo</dc:creator>
      <pubDate>Tue, 29 Sep 2026 08:04:25 +0000</pubDate>
      <link>https://dev.to/buluo/claude-code-mit-cc-switch-umstellen-und-verbindungsfehler-eingrenzen-4fg7</link>
      <guid>https://dev.to/buluo/claude-code-mit-cc-switch-umstellen-und-verbindungsfehler-eingrenzen-4fg7</guid>
      <description>&lt;p&gt;Ein gespeicherter Anbieter ist nicht unbedingt der Anbieter, den der nächste Claude-Code-Prozess tatsächlich verwendet. Dieser Unterschied ist entscheidend, wenn nach einem Wechsel des API-Endpunkts ein Fehler mit dem Statuscode 401, 403 oder 404 auftritt.&lt;/p&gt;

&lt;p&gt;Diese Anleitung verwendet CC Switch unter Windows und einen Anthropic-kompatiblen Endpunkt von Crazyrouter. Das Vorgehen lässt sich auf ähnliche Konfigurationen übertragen: zuerst den Client prüfen, dann Zugangsdaten und Basis-URL eintragen, den Anbieter aktivieren und schließlich eine kurze Anfrage mit dem Protokoll des Dienstes abgleichen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zuerst den Client prüfen
&lt;/h2&gt;

&lt;p&gt;Führe vor der Konfiguration eines Anbieters folgenden Befehl in PowerShell aus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Falls PowerShell &lt;code&gt;claude&lt;/code&gt; nicht findet, prüfe zuerst die Installation von Claude Code und die PATH-Umgebungsvariable. CC Switch verwaltet Verbindungseinstellungen, installiert aber nicht die CLI. Du kannst CC Switch über die &lt;a href="https://github.com/farion1231/cc-switch/releases" rel="noopener noreferrer"&gt;Release-Seite des Projekts&lt;/a&gt; herunterladen.&lt;/p&gt;

&lt;p&gt;Die für diesen Artikel geprüfte Umgebung bestand aus Windows 10 22H2 und Claude Code 2.1.283. Die Bezeichnungen in der Oberfläche können bei anderen Versionen von CC Switch abweichen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Einen Claude-Anbieter hinzufügen
&lt;/h2&gt;

&lt;p&gt;Öffne den Reiter &lt;strong&gt;Claude&lt;/strong&gt; und klicke in der Anbieterliste auf die Schaltfläche zum Hinzufügen. Der bisherige Anbieter kann neben dem neuen bestehen bleiben.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faib2utyeex5pr4qlknt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faib2utyeex5pr4qlknt7.png" alt="Einen Anbieter im Claude-Reiter hinzufügen" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suche in den Vorlagen nach &lt;code&gt;crazy&lt;/code&gt; und wähle CrazyRouter aus. Eine Vorlage spart Eingaben, ersetzt aber nicht die Prüfung der Werte. Falls sie in deiner Version fehlt, lege einen benutzerdefinierten Anbieter an.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbpidtu7ltw3yujtbt0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbpidtu7ltw3yujtbt0z.png" alt="Die Anbietervorlage suchen" width="798" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trage einen API-Schlüssel aus deinem eigenen Konto in das Feld &lt;strong&gt;API Key&lt;/strong&gt; ein. Achte auf versehentlich kopierte Leerzeichen am Anfang oder Ende. Der Schlüssel darf niemals in einem veröffentlichten Screenshot erscheinen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwjawyatzbtmtlcly8t9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwjawyatzbtmtlcly8t9z.png" alt="Das Feld für den API-Schlüssel" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trage für den hier verwendeten regionalen Endpunkt ausschließlich diese Basis-URL als Anfrageadresse ein:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://cn.crazyrouter.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternativ steht &lt;code&gt;https://api.crazyrouter.com&lt;/code&gt; zur Verfügung. Wähle den für dein Netzwerk passenden Endpunkt. Hänge an die Basis-URL für Claude weder &lt;code&gt;/v1&lt;/code&gt; noch &lt;code&gt;/v1/messages&lt;/code&gt; an: Der Client setzt den Anthropic-Anfragepfad selbst zusammen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwffon2ymkx9rwaegj4ny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwffon2ymkx9rwaegj4ny.png" alt="Das Feld für die Anfrageadresse" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rufe im Formular die aktuelle Modellliste ab und wähle ein Modell, auf das dein Schlüssel zugreifen darf. Die entsprechende Schaltfläche heißt je nach Oberflächensprache beispielsweise &lt;strong&gt;Get model list&lt;/strong&gt;. Ein Modellname aus einem fremden Screenshot belegt keine Zugriffsberechtigung für dein Konto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speichern und tatsächliche Verwendung unterscheiden
&lt;/h2&gt;

&lt;p&gt;Speichere den Anbieter und wähle anschließend seine Karte in der Liste aus. Beende bestehende Claude-Code-Sitzungen und öffne ein neues PowerShell-Fenster. Sende eine kurze Anfrage ohne Projektkontext:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Antworte nur mit OK."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-turns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--tools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Der geprüfte Rechner gab mit gültigen Zugangsdaten und der oben genannten regionalen Basis-URL &lt;code&gt;OK&lt;/code&gt; zurück. Damit war ein CLI-Aufruf erfolgreich. Das beweist jedoch &lt;strong&gt;nicht allein&lt;/strong&gt;, dass die CC-Switch-Karte die Verbindung bestimmt hat: Eine geerbte Umgebungsvariable könnte die erwartete Konfiguration weiterhin überschreiben. Vergleiche deshalb den Zeitpunkt der Anfrage mit dem Anfrageprotokoll im Konto des Dienstes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Zuerst prüfen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;claude&lt;/code&gt; wird nicht gefunden&lt;/td&gt;
&lt;td&gt;Installation und PATH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;td&gt;Gültigkeit des Schlüssels und mitkopierte Leerzeichen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403 oder &lt;code&gt;model not allowed&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Berechtigung für das ausgewählte Modell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Basis-URL, zusätzlich eingetragener Pfad und API-Format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Erfolgreiche Antwort ohne passenden Protokolleintrag&lt;/td&gt;
&lt;td&gt;Ausgewählte Karte und geerbte Umgebungsvariablen&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Diese Tabelle beschreibt eine sinnvolle Reihenfolge zur Fehlersuche. Ein Statuscode lässt sich nicht eindeutig einer einzigen Ursache zuordnen. Ändere jeweils nur ein Feld und wiederhole dieselbe kurze Anfrage.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hinweis und Offenlegung: Crazyrouter dient in diesem Artikel als Produktbeispiel für die Konfiguration. Der Artikel ist kein unabhängiger Preis- oder Leistungsvergleich. Verfügbare Modelle und Gebühren können sich ändern; maßgeblich sind die aktuellen Angaben im Dashboard des Dienstes. Veröffentliche deinen API-Schlüssel nicht.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>windows</category>
      <category>api</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Wie ich den 403-Fehler bei der Claude-Code-Installation unter Windows behoben habe (und es mit Crazyrouter verbunden habe)</title>
      <dc:creator>boluo</dc:creator>
      <pubDate>Mon, 28 Sep 2026 09:23:27 +0000</pubDate>
      <link>https://dev.to/buluo/wie-ich-den-403-fehler-bei-der-claude-code-installation-unter-windows-behoben-habe-und-es-mit-5eoj</link>
      <guid>https://dev.to/buluo/wie-ich-den-403-fehler-bei-der-claude-code-installation-unter-windows-behoben-habe-und-es-mit-5eoj</guid>
      <description>&lt;h1&gt;
  
  
  Wie ich den 403-Fehler bei der Claude-Code-Installation unter Windows behoben habe (und es mit Crazyrouter verbunden habe)
&lt;/h1&gt;

&lt;p&gt;Der frustrierendste Fehler beim Einrichten von Claude Code unter Windows war keine fehlende Abhängigkeit — es war ein &lt;code&gt;403&lt;/code&gt;, der erst auftauchte, als scheinbar alles lief.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;claude --version&lt;/code&gt; gab eine saubere Versionsnummer aus. Die Binärdatei war installiert. Dann startete ich das Programm und bekam &lt;code&gt;Failed to connect to api.anthropic.com: Status 403&lt;/code&gt;. Ich habe npm dreimal neu installiert und Proxy-Einstellungen durchprobiert, bevor ich merkte, dass der eigentliche Fehler eine falsch benannte Umgebungsvariable war. Hier ist die vollständige Analyse und mein exaktes Prüfprotokoll. Alles lief auf Windows 10 mit PowerShell; alle Befehle lassen sich direkt kopieren und ausführen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der 403-Screenshot, mit dem alles begann
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi5lpsn5pwesqe3oepn4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi5lpsn5pwesqe3oepn4h.png" alt="Die Versionsnummer wird korrekt ausgegeben, beim Start kommt aber trotzdem ein 403 von api.anthropic.com" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Das Bild hält die wichtigste Lektion fest: &lt;strong&gt;Eine erfolgreiche Installation und ein erfolgreicher Aufruf sind zwei verschiedene Prüfpunkte.&lt;/strong&gt; Die Versionsnummer beweist nur den ersten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teil 1: Claude Code installieren
&lt;/h2&gt;

&lt;p&gt;PowerShell öffnen (achte auf die Eingabeaufforderung &lt;code&gt;PS C:\Users\deinname&amp;gt;&lt;/code&gt;). Installationsbefehle gehören nicht in den Claude-Code-Chat, sondern ins Terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native Installation (bevorzugt, kein Node.js nötig):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://claude.ai/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Danach das Terminal neu öffnen und &lt;code&gt;claude --version&lt;/code&gt; ausführen. Eine Versionsnummer bedeutet, dass der lokale Befehl funktioniert. Wenn der Skript-Download fehlschlägt oder die Ausgabe voller HTML- und &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;-Tags ist: aufhören — dann hast du nicht das echte Skript bekommen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2t9jiiqzm2gkcgje543a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2t9jiiqzm2gkcgje543a.png" alt="Das offizielle Installationsskript lieferte eine HTML-Seite zurück; iex führte die Webseite als Befehle aus und spuckte JavaScript-Syntaxfehler aus" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wenn PowerShell sich über &lt;code&gt;var&lt;/code&gt; oder &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; beschwert, parst es gerade eine Webseite und nicht deinen Befehl.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm als Ausweichlösung (benötigt Node.js 22+):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;npm.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;anthropic-ai/claude-code&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;claude.cmd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ich nutze &lt;code&gt;npm.cmd&lt;/code&gt;, damit PowerShell nicht &lt;code&gt;npm.ps1&lt;/code&gt; nimmt und an der Execution Policy hängen bleibt. Eine häufige Falle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahnewbt553mm6225zefx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahnewbt553mm6225zefx.png" alt="Zwei npm-Befehle wurden zusammengeklebt, wodurch der nicht existierende Paketname claude-codenpm entstand" width="799" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Der Fehler zeigte &lt;code&gt;@anthropic-ai/claude-codenpm&lt;/code&gt; — ein verirrtes &lt;code&gt;npm&lt;/code&gt;, das am Paketnamen klebte, weil zwei Befehle in einer Zeile verschmolzen waren. Das korrekte Paket heißt immer &lt;code&gt;@anthropic-ai/claude-code&lt;/code&gt;. Zeile leeren und einmal sauber ausführen.&lt;/p&gt;

&lt;p&gt;Git ist zum Starten nicht nötig; installiere &lt;a href="https://git-scm.com/install/windows" rel="noopener noreferrer"&gt;Git für Windows&lt;/a&gt; nur, wenn du Repositories oder Git Bash brauchst.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teil 2: Die Gateway-API anbinden
&lt;/h2&gt;

&lt;p&gt;Ohne einen nutzbaren Modelldienst kannst du keine einzige Frage stellen. Ich habe den Ostasien-Endpunkt verwendet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://cn.crazyrouter.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Zweck&lt;/th&gt;
&lt;th&gt;Adresse&lt;/th&gt;
&lt;th&gt;Wo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Konto / Konsole&lt;/td&gt;
&lt;td&gt;&lt;code&gt;crazyrouter.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Browser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code Base URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://cn.crazyrouter.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modelle auflisten&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://cn.crazyrouter.com/v1/models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prüfung&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Messages-Endpunkt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://cn.crazyrouter.com/v1/messages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Wichtig: die Wurzeladresse eintragen, nicht &lt;code&gt;/v1/messages&lt;/code&gt;.&lt;/strong&gt; Das ist genau das Gegenteil von OpenAI-kompatiblen Clients. Wer den OpenAI-Stil übernimmt, bekommt einen 404 oder landet bei &lt;code&gt;/v1/v1/messages&lt;/code&gt;. UTM-Parameter haben in der API-Konfiguration nichts zu suchen.&lt;/p&gt;

&lt;p&gt;Lege in der Konsole einen eigenen API-Key an (nenn ihn &lt;code&gt;claude-code-windows&lt;/code&gt;, prüfe Ablaufdatum und Kontingent) und öffne dann die Benutzerkonfiguration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%USERPROFILE%\.claude\settings.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verzeichnis anlegen und eine vorhandene Datei sichern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="s2"&gt;\.claude"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-Null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.claude\settings.json'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;Copy-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Destination&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="s2"&gt;.backup-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'yyyyMMdd-HHmmss'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;notepad.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="s2"&gt;\.claude\settings.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Das JSON im Editor schreiben (niemals in PowerShell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_BASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cn.crazyrouter.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_CRAZYROUTER_API_KEY"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ersetze den Platzhalter durch deinen Key. Verwende englische doppelte Anführungszeichen, kein Komma am Ende, und füge dich in ein bereits vorhandenes &lt;code&gt;env&lt;/code&gt; ein, statt ein zweites anzulegen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Die eine Änderung, die meinen 403 beendet hat
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Für einen Anthropic-kompatiblen Endpunkt von Drittanbietern nutzt du &lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt;, nicht &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;.&lt;/strong&gt; Die beiden senden unterschiedliche Header:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Gesendeter Header&lt;/th&gt;
&lt;th&gt;Gedacht für&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x-api-key: &amp;lt;key&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;offizielle Anthropic-API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;eigene / kompatible Gateways&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Setzt du &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;, geht der Client vom offiziellen Kanal aus — &lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt; kann das nicht überschreiben, die Anfragen laufen weiter gegen &lt;code&gt;api.anthropic.com&lt;/code&gt;, und du bekommst den 403. Setze nicht „zur Sicherheit“ beide; das erzwingt nur bei jedem Start eine Rückfrage.&lt;/p&gt;

&lt;p&gt;Prüfe, ob die Konfiguration überhaupt parst (das &lt;strong&gt;validiert den Key nicht&lt;/strong&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.claude\settings.json'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$ccSettings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Raw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$settingsPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertFrom-Json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pscustomobject&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nx"&gt;BaseURL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ccSettings&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nx"&gt;HasAuthToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ccSettings&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modelle mit dem eigenen Key auflisten:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$crBase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;$ccSettings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TrimEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$crHeaders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Authorization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nv"&gt;$ccSettings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ANTHROPIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$crBase&lt;/span&gt;&lt;span class="s2"&gt;/v1/models"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$crHeaders&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TimeoutSec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ein sichtbares Modell ist kein Beweis, dass es über das Messages-Protokoll auch generieren kann — deshalb stellen wir trotzdem eine echte Frage. Kopiere die exakt zurückgegebene ID und ergänze sie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_BASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cn.crazyrouter.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_CRAZYROUTER_API_KEY"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_MODEL_ID"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Speichern und Claude Code neu starten (ebenso das Terminal, wenn du Umgebungsvariablen geändert hast).&lt;/p&gt;

&lt;h2&gt;
  
  
  Teil 3: Die erste Frage — was „verbunden“ wirklich heißt
&lt;/h2&gt;

&lt;p&gt;Nutze ein Wegwerf-Verzeichnis, kein echtes Projekt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$demoDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;USERPROFILE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'claude-code-first-run'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$demoDir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-Null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Set-Location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LiteralPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$demoDir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Im Chatfenster eingeben:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reply with exactly OK. Do not read files. Do not run commands.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Erwartet wird ein vollständiges &lt;code&gt;OK&lt;/code&gt;. Öffne dann das Nutzungsprotokoll der Konsole und verifiziere, dass Zeit, Modell, Status und Verbrauch des Aufrufs übereinstimmen. Ein funktionierender Befehl plus lesbare Konfiguration plus vollständige Antwort plus passender Eintrag im Backend — das ist eine verifizierte Integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teil 4: Den 403 lesen
&lt;/h2&gt;

&lt;p&gt;Mein Fehler war &lt;code&gt;Failed to connect to api.anthropic.com: Status 403&lt;/code&gt;. Drei Ebenen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;403&lt;/code&gt;&lt;/strong&gt; heißt: Die Anfrage wurde gesendet und beantwortet — der Server hat sie abgelehnt. Ein Netzwerkausfall zeigt einen Timeout, keinen Statuscode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Der Host ist &lt;code&gt;api.anthropic.com&lt;/code&gt;&lt;/strong&gt; — das ist das wertvolle Detail. Du hast das Gateway konfiguriert, trotzdem geht die Anfrage an die offizielle Domain, der Client hat deine Konfiguration also nie verwendet.&lt;/li&gt;
&lt;li&gt;Zusammen mit „Versionsnummer wurde sauber ausgegeben“ heißt das: Das Problem liegt beim Routing und bei den Zugangsdaten, nicht bei der Installation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also: erst klären, wohin die Anfrage ging, dann diskutieren, warum sie abgelehnt wurde. Zeigt die Anfrage noch woanders hin, prüfe in dieser Reihenfolge: Konfiguration im richtigen Windows-Benutzerverzeichnis, &lt;code&gt;settings.json&lt;/code&gt; parst mit korrekter Base URL, &lt;code&gt;CLAUDE_CONFIG_DIR&lt;/code&gt; unverändert, Neustart erfolgt, keine projektlokale &lt;code&gt;.claude/settings.local.json&lt;/code&gt; überschreibt etwas, und kein Startargument, keine Umgebungsvariable und kein Login-Status hat den Auth-Pfad verändert. Kommt der 403 direkt vom Gateway, lies den Response-Body, prüfe Key-Gültigkeit, Kontingent und Logs — und notiere dir die Request-ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teil 5: Mein tatsächliches Prüfprotokoll
&lt;/h2&gt;

&lt;p&gt;Erfasst am 2026-09-28:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prüfung&lt;/th&gt;
&lt;th&gt;Ergebnis&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OS / Terminal&lt;/td&gt;
&lt;td&gt;Windows 10 / Windows PowerShell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js / npm&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;v22.22.2&lt;/code&gt; / &lt;code&gt;10.9.7&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2.1.281&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Base URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://cn.crazyrouter.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Konfiguration&lt;/td&gt;
&lt;td&gt;parst; &lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt; gesetzt; kein &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; beigemischt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 200, 161 Modell-IDs, gewähltes Modell enthalten&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /v1/messages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 200, Body &lt;code&gt;OK&lt;/code&gt;, &lt;code&gt;stop_reason&lt;/code&gt; &lt;code&gt;end_turn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response-ID&lt;/td&gt;
&lt;td&gt;&lt;code&gt;msg_011CfVJqbN2DVuqoYqgLcdNE&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens&lt;/td&gt;
&lt;td&gt;Input 18, Output 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Round-Trip (direkt)&lt;/td&gt;
&lt;td&gt;11569 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client-Aufruf&lt;/td&gt;
&lt;td&gt;Exit 0, &lt;code&gt;is_error=false&lt;/code&gt;, &lt;code&gt;subtype=success&lt;/code&gt;, &lt;code&gt;OK&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client-Dauer&lt;/td&gt;
&lt;td&gt;5103 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session-ID&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a7a76f08-fa36-4a36-8787-3f2b24dad626&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Der Minimaltest verwendete diesen Body (die Modell-ID war zum Abfragezeitpunkt gültig und kann bei dir abweichen):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-fable-5-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reply with exactly OK."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Das beweist, dass eine minimale Anfrage erfolgreich war — nicht die langfristige Stabilität und auch nicht, dass jedes Modell funktioniert. Modell-IDs und Preise ändern sich; verlass dich auf dein eigenes &lt;code&gt;/v1/models&lt;/code&gt; und deine Konsole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;Zerlege die Einrichtung in Prüfpunkte: Version wird ausgegeben → Key liegt vor → JSON parst → kompatibles Modell → vollständige Antwort → Log stimmt überein. Scheitert einer der früheren Punkte, repariere genau diesen Schritt. Installiere npm nicht wegen eines 403 neu, gib dem Key nicht die Schuld an einem &lt;code&gt;ConnectionRefused&lt;/code&gt;, und nenne „der Bildschirm ist aufgegangen“ nicht Erfolg.&lt;/p&gt;

&lt;p&gt;Was war die seltsamste Falle, in die du beim Anbinden von Claude Code (oder irgendeinem KI-Coding-Tool) unter Windows getappt bist? Schreib deine Leidensgeschichte in die Kommentare — ich vergleiche gern Notizen und erspare vielleicht der nächsten Person ein paar Neuinstallationen.&lt;/p&gt;

&lt;p&gt;Tags: claude, windows, api, tutorial&lt;/p&gt;

&lt;h2&gt;
  
  
  Referenzen
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/setup" rel="noopener noreferrer"&gt;Offizielle Setup-Dokumentation zu Claude Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/settings" rel="noopener noreferrer"&gt;Claude-Code-Einstellungen und Priorität&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.crazyrouter.com" rel="noopener noreferrer"&gt;Crazyrouter-Dokumentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;Node.js herunterladen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/install/windows" rel="noopener noreferrer"&gt;Git für Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://crazyrouter.com/register" rel="noopener noreferrer"&gt;Crazyrouter-Konsole — API-Key erstellen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Haftungsausschluss: Dieser Artikel ist ein persönlicher Erfahrungsbericht und keine offizielle Dokumentation. Dienste von Drittanbietern, Modellnamen, Preise und verfügbare Modelle können sich jederzeit ändern — prüfe sie immer auf den offiziellen Seiten und in deiner eigenen Konsole. API-Endpunkte und Konfigurationspfade solltest du der offiziellen Dokumentation entnehmen, die du zum jeweiligen Zeitpunkt heranziehst. Dieser Artikel enthält keine Affiliate-, Provisions- oder Sponsoring-Inhalte.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
