Zum Hauptinhalt springen

opencode mit mittwald AI Hosting

opencode‍ ist ein CLI-Coding-Agent, der OpenAI-kompatible Provider über den Adapter @ai-sdk/openai-compatible unterstützt, mittwald AI Hosting braucht also keine Sonderbehandlung.

Installation​

opencode 2.x und 1.x liegen in unterschiedlichen npm-Paketen:

# opencode 2.x
npm install -g @opencode/cli

# opencode 1.x
npm install -g opencode-ai

Beide Versionen bringen denselben Befehl opencode mit und lassen sich deshalb nicht nebeneinander installieren. Entferne eine 1.x-Installation, bevor du 2.x installierst.

Installation prüfen:

opencode --version

opencode auf mittwald AI Hosting zeigen lassen​

opencode liest die Konfiguration aus einem der beiden Orte:

  • Global: ~/.config/opencode/opencode.json
  • Pro Projekt: opencode.json im Projekt-Root
{
"$schema": "https://opencode.ai/config.json",
"model": "mittwald/Qwen3.8-27B-NVFP4",
"provider": {
"mittwald": {
"npm": "@ai-sdk/openai-compatible",
"name": "mittwald AI Hosting",
"options": {
"baseURL": "https://llm.aihosting.mittwald.de/v1",
"apiKey": "sk-..."
},
"models": {
"Qwen3.8-27B-NVFP4": {
"name": "Qwen3.8-27B-NVFP4",
"reasoning": true,
"tool_call": true,
"limit": { "context": 256000, "output": 32768 }
},
"Qwen3.6-35B-A3B-FP8": {
"name": "Qwen3.6-35B-A3B-FP8",
"reasoning": true,
"tool_call": true,
"limit": { "context": 256000, "output": 32768 }
},
"gpt-oss-120b": {
"name": "gpt-oss-120b",
"reasoning": true,
"tool_call": true,
"limit": { "context": 131072, "output": 32768 }
},
"GLM-OCR": {
"name": "GLM-OCR",
"tool_call": false,
"limit": { "context": 131072, "output": 4096 }
}
}
}
}
}

Ersetze sk-... durch deinen AI-Hosting-API-Key. Den legst du im Bereich AI-Hosting deines mStudio-Projekts an — siehe API-Key einrichten‍. Ein mStudio-API-Token aus den Profileinstellungen ist ein anderes Zugangsmittel und funktioniert hier nicht.

Verbindung prüfen​

opencode run --auto "Create a file called hello.txt containing the word hello, then read it back."

Erwartet: opencode schreibt die Datei, liest sie zurück und gibt den Inhalt aus. Führe das in einem Scratch-Verzeichnis aus – der Agent schreibt Dateien dort, wo du ihn startest. Eine reine Frage würde auch bei fehlendem tool_call gelingen, deshalb prüft der Test über eine Dateischreibung.

Ohne --auto musst du den Dateischreibzugriff erst genehmigen, bevor er passiert. --auto genehmigt automatisch Berechtigungen, die nicht explizit verweigert sind. In opencode 2.x läuft --standalone gegen einen privaten Server statt gegen den gemeinsamen Hintergrunddienst. Das hilft, wenn opencode run keine Ausgabe liefert, siehe Troubleshooting‍. opencode 1.x hat weder den Hintergrunddienst noch das Flag --standalone.

Nutzung​

# Explain unfamiliar code
opencode run "explain how session handling works in this project"

# Make a change
opencode run "add email validation to the registration form"

# Optimise
opencode run "optimize the database queries in user_service.py"

MCP-Server​

MCP-Server werden im Top-Level-Objekt mcp deklariert. Jeder Eintrag hat eine von zwei Formen:

  • "type": "local" – command ist ein Array: das ausführbare Programm gefolgt von seinen Argumenten. Mit dem optionalen environment setzt du Umgebungsvariablen für den Server.
  • "type": "remote" – url zeigt auf einen MCP-Endpoint.
{
"mcp": {
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp",
"enabled": true
},
"fetch": {
"type": "local",
"command": ["uvx", "mcp-server-fetch"],
"enabled": true
},
"playwright": {
"type": "local",
"command": ["npx", "-y", "@playwright/mcp"],
"enabled": true
},
"sequential-thinking": {
"type": "local",
"command": [
"npx",
"-y",
"@modelcontextprotocol/server-sequential-thinking"
],
"enabled": true
},
"directus": {
"type": "local",
"command": ["npx", "-y", "@directus/content-mcp"],
"environment": {
"DIRECTUS_URL": "https://your-directus-instance.com",
"DIRECTUS_TOKEN": "your-directus-token"
},
"enabled": true
},
"opensearch": {
"type": "local",
"command": ["uvx", "opensearch-mcp-server-py"],
"environment": {
"OPENSEARCH_URL": "https://localhost:9200",
"OPENSEARCH_USERNAME": "your-opensearch-username",
"OPENSEARCH_PASSWORD": "your-opensearch-password"
},
"enabled": true
},
"typo3": {
"type": "local",
"command": [
"mw",
"app",
"exec",
"--quiet",
"--installation-id=a-XXXXX",
"vendor/bin/typo3",
"mcp:server"
],
"enabled": true
},
"mittwald": {
"type": "remote",
"url": "https://mcp.mittwald.de/mcp",
"enabled": true
}
}
}

Authentifizierung und Token-Lebenszyklus des mittwald-Servers stehen in der MCP-Integration‍. Die Server für TYPO3, Directus und OpenSearch authentifizieren sich über die oben gezeigten Umgebungsvariablen.

Plugins und Skills​

Plugins stehen im Array plugin:

{
"plugin": ["opencode-scheduler"]
}

Skills liegen unter ~/.config/opencode/skills/, ein Verzeichnis pro Skill.

Agent Packs fügen vorkonfigurierte Subagenten hinzu, jeder davon kann auf ein eigenes Modell zeigen. Lass die Subagenten auf Qwen3.6-35B-A3B-FP8 laufen und den Hauptagenten auf Qwen3.8-27B-NVFP4 mit eingeschaltetem Thinking, so wie das Modell ausgeliefert wird. Dann bleiben auch lange Sessions flott, denn Subagenten suchen und fassen vor allem zusammen.

Troubleshooting​

opencode run liefert keine Ausgabe und schreibt keine Datei​

opencode run ist nicht interaktiv, und je nach Build liefert es unter Umständen gar nichts zurück – keine Ausgabe, keine Datei, keine Fehlermeldung – statt zu melden, was schiefgelaufen ist. In opencode 2.x führt --standalone den Befehl gegen einen privaten Server statt gegen den gemeinsamen Hintergrunddienst aus – einen Versuch wert, wenn ein Lauf nichts liefert; das ist die dokumentierte Funktion des Flags, keine Garantie, dass es das Problem für jede Installation löst. Bestätigt opencode run die Verbindung weiterhin nicht, weiche auf die interaktive TUI aus (opencode ohne Subcommand ausführen) und schicke denselben Prompt dort ab.

Der Agent antwortet, bearbeitet aber nie eine Datei oder führt einen Befehl aus​

Dem Modell fehlt "tool_call": true in seinem models-Eintrag.

Der Agent wiederholt denselben Tool-Call​

Der Agent liest dieselben Dateien wieder und wieder ein und kommt nie dazu, etwas zu ändern. opencode bricht so eine Schleife nicht von sich aus ab, und jeder Durchlauf geht von deinem Token-Kontingent ab. Leg deshalb in der opencode.json fest, wie viele Schritte jeder Agent höchstens machen darf:

{
"agent": {
"build": { "steps": 30 },
"plan": { "steps": 30 }
}
}

Ist die Grenze erreicht, verlangt opencode vom Modell keinen weiteren Tool-Call mehr, sondern eine Zusammenfassung dessen, was es bisher erledigt hat.

Das Limit beendet eine Schleife, verhindert sie aber nicht. Meist entstehen solche Schleifen, wenn Thinking aus ist. Lass es bei Qwen3.8-27B-NVFP4 für Planung und Tool-Arbeit deshalb eingeschaltet, siehe Agent-Schleifen im Non-Thinking-Modus‍.

Ein MCP-Server startet nie​

Prüfe die Form des Eintrags. Ein local-Server braucht command als Array, nicht als String mit separatem args-Feld – ein String-command mit args ist das Format von Claude Desktop, und opencode ignoriert es stillschweigend statt einen Fehler zu werfen.

Startet der Server, scheitert aber an der Anmeldung, sieh dir den Schlüssel für die Variablen an. opencode erwartet environment. Einen Schlüssel env wirft es ohne Warnung weg, und der Server startet ohne seine Zugangsdaten.

npx meldet einen 404 für ein MCP-Paket​

Paketname prüfen. Der context7-Server ist als @upstash/context7-mcp veröffentlicht – das ähnlich klingende @context7/mcp-server existiert nicht auf npm.

Nächste Schritte​

Disclaimer​

Drittanbieter-Tools, MCP-Server und externe Links werden zur Vereinfachung bereitgestellt, ohne Gewährleistung oder Empfehlung. Nutze sie auf eigenes Risiko, prüfe Lizenzen und Datenschutzrichtlinien und vergib nur die nötigen Berechtigungen (Least Privilege). Sende keine sensiblen Daten an externe Services, sofern nicht nötig und erlaubt.

Auf dieser Seite