Zurück zur Startseite

Proxy Claude API für OpenClaw: Code und Tool-Nutzung

Proxy-Server stellt Zugriff auf Claude in openclaw nach Anthropic-Blockade wieder her. Browser-Emulation mit curl_cffi, Unterstützung für Tool-Nutzung über XML-Prompts und JSON Auto-Fix. Voller Code, Konfiguration und Integration für Entwickler.

Claude in OpenClaw wiederherstellen: Proxy mit Tool-Nutzung
Advertisement 728x90

Claude-API-Proxy über Web-Session: OpenClaw-Integration mit Tool-Use

Anthropic hat die Nutzung von Claude in Drittanbieter-Apps wie OpenClaw blockiert. Pro-Abonnenten (100 $/Monat) erhalten 100 $ Zusatzguthaben, doch das löst das Agenten-Integration-Problem nicht. Die Lösung? Ein Proxy-Server, der eine Claude.ai-Browser-Session simuliert und eine OpenAI-kompatible API bietet. So läuft Claude Sonnet/Opus in OpenClaw mit vollem Tool-Use-Support.

Entwickelt in Python mit curl_cffi für Chrome-TLS-Fingerprinting. Cookies und Device-ID stammen aus deiner aktiven Session. Jede Anfrage startet ein neues Gespräch und streamt Vervollständigungen via SSE.

Grundlegende Session- und Header-Konfiguration

Die Session tarnt sich als Chrome mit echten Browser-Cookies. Getestet mit dem Anti-Detection-Browser Camoufox.

Google AdInline article slot
def make_session() -> cf_requests.Session:
    """Erstellt eine neue curl_cffi-Session mit Chrome-TLS-Fingerprint."""
    cookies = get_cookies()
    session = cf_requests.Session(impersonate=IMPERSONATE)
    session.cookies.update(cookies)
    return session

def get_headers(cookies: dict) -> dict:
    return {
        "User-Agent": (
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
            "(KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
        ),
        "Origin": "https://claude.ai",
        "Referer": "https://claude.ai/new",
        "anthropic-device-id": cookies.get("anthropic-device-id", ""),
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
    }

Logik für Completion-Anfragen

  • POST an /api/organizations/{org_id}/chat_conversations, um ein Gespräch zu erstellen.
  • POST an /chat_conversations/{conv_id}/completion mit text/event-stream.
def claude_complete(
    prompt: str,
    internal_model: str,
) -> Generator[str, None, None]:
    """Synchroner Generator, der SSE-Zeilen von claude.ai-Completion liefert."""
    cookies = get_cookies()
    org_id = cookies["lastActiveOrg"]
    headers = get_headers(cookies)

    session = make_session()

    # 1. Gespräch erstellen
    r = session.post(
        f"https://claude.ai/api/organizations/{org_id}/chat_conversations",
        json={"uuid": None, "name": ""},
        headers=headers,
        timeout=15,
    )
    r.raise_for_status()
    conv_id = r.json()["uuid"]
    log.info(f"Gespräch erstellt: {conv_id} model={internal_model}")

    # 2. Completion streamen
    payload = {
        "prompt": prompt,
        "model": internal_model,
        "timezone": "Europe/Moscow",
        "attachments": [],
        "files": [],
    }
    r2 = session.post(
        f"https://claude.ai/api/organizations/{org_id}/chat_conversations/{conv_id}/completion",
        json=payload,
        headers={**headers, "Accept": "text/event-stream"},
        stream=True,
        timeout=60,
    )
    r2.raise_for_status()
    for line in r2.iter_lines():
        yield line

Der API-Server nutzt aiohttp mit Routen für /v1/models, /v1/chat/completions, /health. Läuft auf 127.0.0.1:8787.

def make_app() -> web.Application:
    app = web.Application()
    app.router.add_get("/v1/models", handle_models)
    app.router.add_get("/health", handle_health)
    app.router.add_post("/v1/chat/completions", handle_chat_completions)
    return app

OpenClaw-Integration

Provider-Konfiguration:

"claude-web": {
    "baseUrl": "http://127.0.0.1:8787/v1",
    "apiKey": "dummy",
    "api": "openai-completions",
    "models": [
      {
        "id": "claude-sonnet-4-6-web",
        "name": "Claude Sonnet 4.6 (Web)",
        "reasoning": false,
        "input": ["text"],
        "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
        "contextWindow": 200000,
        "maxTokens": 32000
      }
    ]
}

Textgenerierung funktioniert sofort. Tool-Use erfordert Anpassungen.

Google AdInline article slot

Tool-Use-Support: Prompt-Injection

System-Prompt zwingt Claude, Tool-Aufrufe im XML-Format auszugeben:

TOOL_SYSTEM_PROMPT = """Du hast Zugriff auf Tools. Wenn du ein Tool aufrufen musst, gib NUR den Tool-Call-Block aus – keine Erklärung, kein Text davor oder danach:

<tool_call>
{{
"name": "tool_name_here", "arguments": {{"param1": "value1", "param2": "value2"}}
}}
</tool_call>

REGELN:
- Das JSON im <tool_call> muss gültig sein – keine nachgestellten Kommas, keine Kommentare
- Du kannst mehrere <tool_call>-Blöcke nacheinander ausgeben
- Nach Erhalt von <tool_result>-Blöcken fährst du normal mit deiner Antwort fort
- Wenn du kein Tool aufrufst, antworte normal ohne <tool_call>-Tags

Verfügbare Tools:
{tools_json}"""

Parsing mit Regex und Auto-Fixes für JSON-Fehler (nachgestellte Kommas, Kommentare).

Finale Tool-Calls und Ergebnisbehandlung

  • Parser extrahiert <tool_call>-Blöcke, repariert JSON, konvertiert ins OpenAI-Format.
  • Tool-Ergebnisse als XML <tool_result id="...">content</tool_result> in User-Nachrichten injiziert.
def parse_tool_calls(text: str) -> tuple[list[dict], str]:
    tool_calls = []
    for match in TOOL_CALL_RE.finditer(text):
        raw_json = match.group(1).strip()
        obj = None
        try:
            obj = json.loads(raw_json)
        except json.JSONDecodeError:
            fixed = _try_fix_json(raw_json)
            obj = json.loads(fixed)
        if obj:
            tool_calls.append({
                "id": f"call_{uuid.uuid4().hex[:12]}",
                "type": "function",
                "function": {
                    "name": obj.get("name", ""),
                    "arguments": json.dumps(obj.get("arguments", {})),
                },
            })
    remaining = TOOL_CALL_RE.sub("", text).strip()
    return tool_calls, remaining

def inject_tool_results(messages: list[dict], tools: list[dict]) -> list[dict]:
    # OpenAI tool_calls/results zu XML für Claude konvertieren
    # ... (Batch- und XML-Generierungslogik)

Wichtige Features

  • Vollständige Kompatibilität: OpenAI-API mit Tool-Use für OpenClaw/Claude Sonnet 4.6 (200k Kontext).
  • Stealth-Modus: curl_cffi + echte Cookies/Device-ID, Chrome-TLS.
  • Auto-Reparatur: Behandelt Claudes übliche JSON-Probleme (nachgestellte Kommas, Kommentare).
  • Streaming: SSE von Web-API, neues Gespräch pro Anfrage.
  • Limits: Bleibt im Pro-Abo-Rahmen, keine Extrakosten.

Einschränkungen und Verbesserungen

Abhängig von der Stabilität der Claude.ai-Web-API. Mögliche Probleme:

Google AdInline article slot
  • Captchas auf der Seite.
  • Session-Timeouts.
  • Endpoint-Änderungen.

Lösungen: Cookie-Refresh per Automation, Device-ID-Rotation, Fehlerbehandlung.

— Editorial Team

Advertisement 728x90

Weiterlesen