# Proxy API Claude via session web : Intégration OpenClaw avec utilisation d'outils
Anthropic a bloqué l'utilisation de Claude dans les applications tierces comme OpenClaw. Les abonnés Pro (100 $/mois) ont reçu 100 $ de crédits d'utilisation supplémentaires, mais cela ne résout pas l'intégration d'agents. La solution ? Un serveur proxy qui imite une session navigateur Claude.ai avec une API compatible OpenAI. Cela permet d'exécuter Claude Sonnet/Opus dans OpenClaw avec un support complet des outils.
Développé en Python avec curl_cffi pour l'empreinte TLS Chrome. Les cookies et l'ID d'appareil proviennent de votre session active. Chaque requête lance une nouvelle conversation, diffusant les complétions via SSE.
Configuration de base de la session et des en-têtes
La session imite Chrome avec de vrais cookies navigateur. Testé avec le navigateur anti-détection Camoufox.
def make_session() -> cf_requests.Session:
"""Crée une nouvelle session curl_cffi avec empreinte TLS Chrome."""
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",
}
Logique des requêtes de complétion
- POST vers
/api/organizations/{org_id}/chat_conversationspour créer une conversation. - POST vers
/chat_conversations/{conv_id}/completionavectext/event-stream.
def claude_complete(
prompt: str,
internal_model: str,
) -> Generator[str, None, None]:
"""Générateur synchrone qui produit les lignes SSE de la complétion claude.ai."""
cookies = get_cookies()
org_id = cookies["lastActiveOrg"]
headers = get_headers(cookies)
session = make_session()
# 1. Créer la conversation
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"Conv créée : {conv_id} model={internal_model}")
# 2. Diffuser la complétion
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
Le serveur API utilise aiohttp avec des routes pour /v1/models, /v1/chat/completions, /health. Il s'exécute sur 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
Intégration OpenClaw
Configuration du fournisseur :
"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
}
]
}
La génération de texte fonctionne directement. L'utilisation d'outils nécessite des ajustements.
Support des outils : Injection de prompt
Le prompt système force Claude à sortir les appels d'outils au format XML :
TOOL_SYSTEM_PROMPT = """Vous avez accès à des outils. Quand vous devez appeler un outil, sortez UNIQUEMENT le bloc d'appel d'outil — sans explication, sans texte avant ou après :
<tool_call>
{{
"name": "tool_name_here", "arguments": {{"param1": "value1", "param2": "value2"}}
}}
</tool_call>
RÈGLES :
- Le JSON dans <tool_call> doit être valide — pas de virgules en fin, pas de commentaires
- Vous pouvez sortir plusieurs blocs <tool_call> en séquence
- Après réception des blocs <tool_result>, continuez votre réponse normalement
- Si vous n'appelez pas d'outil, répondez normalement sans balises <tool_call>
Outils disponibles :
{tools_json}"""
L'analyse utilise des regex avec auto-corrections pour les erreurs JSON (virgules en fin, commentaires).
Gestion finale des appels et résultats d'outils
- L'analyseur extrait les blocs
<tool_call>, corrige le JSON, convertit au format OpenAI. - Les résultats d'outils injectés comme XML
<tool_result id="...">contenu</tool_result>dans les messages utilisateur.
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]:
# Convertit les tool_calls/résultats OpenAI en XML pour Claude
# ... (logique de batching et génération XML)
Fonctionnalités clés
- Compatibilité totale : API OpenAI avec utilisation d'outils pour OpenClaw/Claude Sonnet 4.6 (contexte 200k).
- Mode furtif : curl_cffi + vrais cookies/ID appareil, TLS Chrome.
- Auto-correction : Gère les glitches JSON courants de Claude (virgules en fin, commentaires).
- Streaming : SSE depuis l'API web, nouvelle conversation par requête.
- Limites : Reste dans l'abonnement Pro, pas d'utilisation supplémentaire.
Limites et améliorations
Dépend de la stabilité de l'API web Claude.ai. Problèmes potentiels :
- Captchas sur le site.
- Expiration de sessions.
- Changements d'endpoints.
Solutions : Actualisation des cookies via automation, rotation d'ID appareil, gestion d'erreurs.
— Editorial Team
Aucun commentaire pour le moment.