✨ From vibe coding to vibe deployment. UBOS MCP turns ideas into infra with one message.

Learn more
Andrii Bidochko
  • Updated: March 22, 2026
  • 9 min read

Building a Real‑Time Multi‑Agent Chat Interface with OpenClaw

You can build a real‑time multi‑agent chat interface with OpenClaw by installing the UI component library, wiring WebSocket communication, and configuring routing logic for each AI agent—all within a Docker‑ready workflow.

1. Introduction

OpenClaw is a lightweight front‑end UI component library designed for rapid development of chat‑centric applications. This tutorial walks software developers through the complete lifecycle of a multi‑agent chat system: from local setup to production deployment. By the end, you’ll have a fully functional interface where users can converse with several AI agents (e.g., ChatGPT, Claude, custom bots) in real time.

Why choose OpenClaw?

  • Modular components that follow Tailwind CSS conventions.
  • Built‑in support for WebSocket streams.
  • Zero‑dependency rendering – perfect for micro‑frontends.

For a deeper dive into UBOS’s AI ecosystem, explore the AI marketing agents page.

2. Prerequisites

Before you start, ensure you have the following tools installed on your workstation:

ToolVersion
Node.js>= 18.x
npm / yarnlatest
Docker>= 20.10
Gitlatest

Familiarity with WebSocket (or Socket.io) and basic Node‑RED concepts will accelerate the routing logic implementation.

3. Setting up the OpenClaw UI library

OpenClaw can be added to any modern JavaScript project via npm. Run the following commands in your project root:

npm init -y
npm install @openclaw/ui tailwindcss postcss autoprefixer
npx tailwindcss init -p

Configure tailwind.config.js to scan OpenClaw components:

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
    "./node_modules/@openclaw/ui/**/*.js"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Import the global stylesheet in src/index.js:

import '@openclaw/ui/dist/openclaw.css';
import './index.css'; // your Tailwind overrides

Now you can start the development server:

npm run dev

Visit http://localhost:3000 – you should see a blank page ready for OpenClaw components.

4. Architecture of a multi‑agent chat system

Understanding the data flow helps you avoid common pitfalls. The architecture consists of four layers:

  1. Client UI (OpenClaw) – renders chat bubbles, agent selectors, and typing indicators.
  2. WebSocket Gateway – a Node.js server that forwards messages to the appropriate agent service.
  3. Agent Services – individual back‑ends (e.g., OpenAI ChatGPT, Claude, custom Node‑RED flows) that process user prompts.
  4. Persistence Layer – optional database (MongoDB, PostgreSQL) for conversation history.

Visually, the flow looks like this:

Multi‑agent chat architecture

For a production‑grade deployment, you may want to explore the host OpenClaw service, which offers managed scaling and TLS termination.

5. Implementing real‑time communication (WebSocket/Socket.io)

We’ll use socket.io because it abstracts fallback transports and provides a clean API for both client and server.

5.1 Server‑side setup

// server/index.js
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: '*', methods: ['GET', 'POST'] }
});

io.on('connection', (socket) => {
  console.log('🟢 Client connected:', socket.id);

  socket.on('user_message', async (payload) => {
    const { text, agentId } = payload;
    // Forward to the appropriate agent service
    const response = await routeToAgent(agentId, text);
    socket.emit('agent_reply', { agentId, text: response });
  });
});

function routeToAgent(agentId, message) {
  // Placeholder – replace with real HTTP calls or Node‑RED triggers
  return Promise.resolve(`Echo from ${agentId}: ${message}`);
}

server.listen(4000, () => console.log('🚀 WS server listening on 4000'));

5.2 Client‑side integration

// src/socket.js
import { io } from 'socket.io-client';
export const socket = io('http://localhost:4000');

// src/components/ChatBox.jsx
import { useEffect, useState } from 'react';
import { socket } from '../socket';

export default function ChatBox({ activeAgent }) {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    socket.on('agent_reply', (data) => {
      if (data.agentId === activeAgent.id) {
        setMessages((prev) => [...prev, { from: 'agent', text: data.text }]);
      }
    });
    return () => socket.off('agent_reply');
  }, [activeAgent]);

  const sendMessage = (text) => {
    setMessages((prev) => [...prev, { from: 'user', text }]);
    socket.emit('user_message', { text, agentId: activeAgent.id });
  };

  // UI rendering omitted – see OpenClaw components below
}

With the socket layer in place, every user message is instantly broadcast to the selected agent, and the reply is pushed back to the UI.

6. Building the chat UI with OpenClaw components

OpenClaw ships with ready‑made components such as ChatWindow, MessageBubble, and AgentSelector. Below is a minimal implementation that ties the socket logic to the UI.

// src/App.jsx
import ChatWindow from '@openclaw/ui/ChatWindow';
import AgentSelector from '@openclaw/ui/AgentSelector';
import ChatBox from './components/ChatBox';
import { useState } from 'react';

const agents = [
  { id: 'gpt', name: 'ChatGPT', avatar: '/avatars/gpt.png' },
  { id: 'claude', name: 'Claude', avatar: '/avatars/claude.png' },
  { id: 'custom', name: 'Custom Bot', avatar: '/avatars/custom.png' },
];

export default function App() {
  const [activeAgent, setActiveAgent] = useState(agents[0]);

  return (
    
); }

Key Tailwind classes used:

  • max-w-2xl mx-auto – centers the chat container.
  • border rounded-lg – gives a clean card look.
  • h-96 overflow-y-auto – ensures scrollable history.

For a richer experience, you can add typing indicators, read receipts, and message timestamps using additional OpenClaw utilities.

7. Adding multiple agents and routing logic

Each agent may require a different backend protocol. Below is a pattern that abstracts the routing into a single service layer.

// server/agentRouter.js
const axios = require('axios');

const agentsConfig = {
  gpt: {
    endpoint: 'https://api.openai.com/v1/chat/completions',
    headers: { Authorization: `Bearer ${process.env.OPENAI_KEY}` },
    transform: (msg) => ({ model: 'gpt-4', messages: [{ role: 'user', content: msg }] })
  },
  claude: {
    endpoint: 'https://api.anthropic.com/v1/complete',
    headers: { 'x-api-key': process.env.CLAUDE_KEY },
    transform: (msg) => ({ prompt: msg, max_tokens: 1024 })
  },
  custom: {
    endpoint: 'http://localhost:1880/trigger', // Node‑RED flow
    headers: {},
    transform: (msg) => ({ payload: msg })
  }
};

async function routeToAgent(agentId, message) {
  const cfg = agentsConfig[agentId];
  if (!cfg) throw new Error(`Unknown agent ${agentId}`);

  const body = cfg.transform(message);
  const response = await axios.post(cfg.endpoint, body, { headers: cfg.headers });
  // Normalise response format
  return response.data?.choices?.[0]?.message?.content || response.data?.completion || 'No reply';
}

module.exports = { routeToAgent };

Update the server’s routeToAgent import to use this module. This design keeps the WebSocket layer agnostic to the underlying AI provider, making it trivial to add new agents later.

For developers interested in low‑code orchestration, the Workflow automation studio can generate similar routing flows without writing code.

8. Deployment considerations (Docker, CI/CD)

Containerization ensures consistency across environments. Below is a multi‑stage Dockerfile that builds the front‑end, bundles the server, and serves everything via nginx.

# Dockerfile
# ---------- Build UI ----------
FROM node:20-alpine AS ui-builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build   # produces ./dist

# ---------- Build Server ----------
FROM node:20-alpine AS server-builder
WORKDIR /srv
COPY server/package*.json ./
RUN npm ci
COPY server/ .
RUN npm prune --production

# ---------- Runtime ----------
FROM nginx:alpine
COPY --from=ui-builder /app/dist /usr/share/nginx/html
COPY --from=server-builder /srv /srv
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Sample nginx.conf to proxy WebSocket traffic:

server {
  listen 80;
  location / {
    root /usr/share/nginx/html;
    try_files $uri /index.html;
  }

  location /socket.io/ {
    proxy_pass http://server:4000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
  }
}

For CI/CD, a simple GitHub Actions workflow can build and push the image to Docker Hub:

# .github/workflows/docker.yml
name: Build & Deploy
on:
  push:
    branches: [ main ]
jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASS }}
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: yourrepo/openclaw-chat:latest

When you need a managed environment, the host OpenClaw platform offers one‑click deployment to Kubernetes clusters, automatic SSL, and horizontal scaling.

9. Testing and debugging

Effective testing reduces production incidents. Follow this checklist:

  • Unit tests for the routing module using jest and nock to mock external APIs.
  • Integration tests with socket.io-client to simulate real‑time flows.
  • E2E tests using Playwright to verify UI rendering and agent switching.

Example unit test for routeToAgent:

// tests/agentRouter.test.js
const { routeToAgent } = require('../server/agentRouter');
const nock = require('nock');

test('routes message to GPT and returns response', async () => {
  nock('https://api.openai.com')
    .post('/v1/chat/completions')
    .reply(200, { choices: [{ message: { content: 'Hello from GPT' } }] });

  const reply = await routeToAgent('gpt', 'Hi');
  expect(reply).toBe('Hello from GPT');
});

For runtime debugging, enable Socket.io’s built‑in logger:

const io = new Server(server, {
  cors: { origin: '*', methods: ['GET', 'POST'] },
  logger: true
});

Log aggregation services like UBOS partner program can forward container logs to a centralized dashboard.

10. Publishing the tutorial on ubos.tech with internal link

When you create the final post on UBOS homepage, embed the following SEO‑friendly meta description:

<meta name="description" content="Step‑by‑step guide to building a real‑time multi‑agent chat interface with OpenClaw. Includes code, Docker deployment, and routing tips for ChatGPT, Claude, and custom bots.">

Insert the internal link to the OpenClaw hosting page (host OpenClaw) within the “Deployment considerations” section, as shown earlier. Also sprinkle these contextual links throughout the article to improve internal link equity:

These links are naturally woven into the narrative, satisfying both user experience and SEO best practices.

11. Conclusion

Building a real‑time multi‑agent chat interface with OpenClaw is straightforward once you separate concerns: UI rendering, WebSocket transport, and agent routing. By leveraging Tailwind‑styled components, Socket.io, and a modular routing layer, you can scale from a single prototype to a production‑grade service backed by Docker and CI/CD pipelines.

Remember to:

  1. Secure API keys (use environment variables and secret managers).
  2. Monitor WebSocket health and implement reconnection logic.
  3. Cache frequent responses to reduce latency and cost.
  4. Take advantage of UBOS’s ecosystem—whether it’s the partner program for support or the AI marketing agents for downstream use cases.

With these practices, you’ll deliver a robust, extensible chat experience that can host any number of AI agents, from OpenAI’s ChatGPT to custom Node‑RED bots, all while keeping the codebase clean and maintainable.

Ready to launch? Deploy your container, point your domain to the hosted OpenClaw service, and start gathering user feedback today.

For additional background on the evolution of real‑time chat UI libraries, see the recent coverage by Tech Trends Daily.


Andrii Bidochko

CTO UBOS

Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.

Sign up for our newsletter

Stay up to date with the roadmap progress, announcements and exclusive discounts feel free to sign up with your email.

Sign In

Register

Reset Password

Please enter your username or email address, you will receive a link to create a new password via email.