Skip to content

openclaw_chat returns 400 Bad Request with local Ollama/Qwen gateway #21

@ashold12

Description

@ashold12

Summary

openclaw_chat tool returns 400 Bad Request when called through the MCP bridge. The gateway is healthy, openclaw_instances and openclaw_status work correctly — only openclaw_chat fails.

Environment

Component Version
openclaw-mcp v1.3.0 (ghcr.io/freema/openclaw-mcp:latest)
OpenClaw gateway 2026.3.24 (cff6dc9)
Ollama 0.18.3
Model ollama/qwen2.5:14b (14B, 9.0 GB)
Platform macOS Darwin x86_64
Client Claude Code v2.1.85 (MCP over streamable HTTP)

Gateway config (openclaw.json)

chatCompletions endpoint is enabled:

{
  "gateway": {
    "port": 18789,
    "mode": "local",
    "bind": "loopback",
    "auth": { "mode": "token", "token": "REDACTED" },
    "http": {
      "endpoints": {
        "chatCompletions": { "enabled": true }
      }
    }
  }
}

docker-compose.yml

services:
  mcp-bridge:
    image: ghcr.io/freema/openclaw-mcp:latest
    container_name: openclaw-mcp
    environment:
      - OPENCLAW_URL=http://host.docker.internal:18789
      - OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
      - AUTH_ENABLED=true
      - MCP_CLIENT_ID=openclaw
      - MCP_CLIENT_SECRET=${MCP_CLIENT_SECRET}
      - CORS_ORIGINS=https://claude.ai
      - DEBUG=true
    extra_hosts:
      - "host.docker.internal:host-gateway"

Steps to reproduce

  1. Start OpenClaw gateway with Ollama/Qwen backend and chatCompletions.enabled: true
  2. Start MCP bridge via Docker (config above)
  3. Connect Claude Code: claude mcp add --transport http --client-id openclaw --client-secret openclaw http://localhost:3000/mcp
  4. Call openclaw_chat with any message

What happens

openclaw_chat(message: "What's your opinion on Pokemon?")
-> Error: API request failed: 400 Bad Request

openclaw_chat(instance: "default", message: "...", session_id: "test")
-> Error: API request failed: 400 Bad Request

openclaw_instances and openclaw_status work correctly — only openclaw_chat fails.

What we know

  • Gateway is healthy: /health returns {"ok":true,"status":"live"}

  • MCP bridge connects and can list instances

  • The chat completions endpoint is enabled in gateway config

  • Direct curl to the gateway works fine:

    curl -X POST \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"model":"openclaw","messages":[{"role":"user","content":"hi"}]}' \
      http://localhost:18789/v1/chat/completions
    # -> 200 OK, returns valid chat completion response
    
  • The 400 has no detail in bridge logs even with DEBUG=true

What we don't know

We cannot see the actual request the bridge sends to the gateway, so we don't know what's causing the 400. Possible causes:

  • Incorrect model name in the request body (gateway requires "openclaw" or "openclaw/agentId")
  • Different endpoint path
  • Missing or malformed headers
  • Auth token not forwarded correctly
  • Request body format mismatch

Request

  1. Could DEBUG=true log the outgoing request body and the full 400 response body? That would make this trivially diagnosable.
  2. Any known compatibility requirements between bridge v1.3.0 and specific OpenClaw gateway versions?
  3. Any additional gateway config needed beyond chatCompletions.enabled: true?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions