Building Interoperable AI Agents: A2A Protocol Integration with KaibanJS

Community Article Published September 25, 2025

KaibanJS_A2A

Introduction

The AI landscape is rapidly evolving, with multi-agent systems becoming increasingly sophisticated. However, one of the biggest challenges in this space is achieving true interoperability between different agent frameworks and platforms. The A2A (Agent-to-Agent) Protocol addresses this challenge by providing a standardized communication layer that enables agents to communicate seamlessly regardless of their underlying technology stack.

In this article, we'll explore how to integrate the A2A Protocol with KaibanJS, a powerful multi-agent orchestration framework, to create interoperable AI systems that can communicate with any A2A-compliant agent.

Understanding the A2A Protocol

The A2A Protocol is an open standard designed to enable universal agent-to-agent communication. It provides:

  • Standardized Communication: A common language for agents to exchange messages
  • Multi-modal Support: Text, audio, and video communication capabilities
  • Real-time Streaming: Live updates and status notifications
  • Security: Built-in authentication and validation mechanisms
  • Vendor Agnostic: Works across different platforms and frameworks

KaibanJS: Multi-Agent Orchestration Made Simple

KaibanJS is a flexible multi-agent framework that simplifies the creation and management of AI agent teams. Key features include:

  • Agent Definition: Easy creation of specialized agents with specific roles and capabilities
  • Task Management: Structured task definition and execution workflows
  • Team Coordination: Seamless orchestration of multiple agents working together
  • Real-time Monitoring: Live workflow logs and status updates
  • Tool Integration: Support for external APIs and services

Architecture Overview

Our implementation demonstrates a complete A2A Protocol integration with KaibanJS, featuring:

┌─────────────────┐    A2A Protocol    ┌─────────────────┐
│   React Client  │ ◄─────────────────► │  Express Server │
│                 │                     │                 │
│ - A2A Client    │                     │ - Agent Executor│
│ - Real-time UI  │                     │ - Agent Card    │
│ - State Mgmt    │                     │ - KaibanJS Team │
└─────────────────┘                     └─────────────────┘
                                                │
                                                ▼
                                        ┌─────────────────┐
                                        │  KaibanJS Team  │
                                        │                 │
                                        │ - Scout Agent   │
                                        │ - Writer Agent  │
                                        │ - Task Flow     │
                                        └─────────────────┘

Implementation Deep Dive

1. Agent Card Definition

The Agent Card serves as the interface contract, defining what our agent can do:

export const kaibanjsAgentCard: AgentCard = {
  name: 'Kaibanjs Research Agent',
  description:
    'An AI agent that uses KaibanJS to research topics and provide comprehensive summaries using web search and content generation capabilities.',
  version: '1.0.0',
  protocolVersion: '1.0.0',
  url: process.env.BASE_URL || 'http://localhost:4000',
  preferredTransport: 'JSONRPC',
  capabilities: {
    streaming: true,
    pushNotifications: false,
    stateTransitionHistory: true
  },
  defaultInputModes: ['text/plain'],
  defaultOutputModes: ['text/plain'],
  skills: [
    {
      id: 'research',
      name: 'Research and Summarization',
      description:
        'Research topics using web search and generate comprehensive summaries',
      tags: ['research', 'summarization', 'web-search', 'ai'],
      examples: [
        'What are the latest developments in AI?',
        'Summarize the current state of renewable energy',
        'Research the history of space exploration'
      ]
    }
  ]
};

2. KaibanJS Team Configuration

Our multi-agent team consists of specialized agents working together:

// Define specialized agents
const searchAgent = new Agent({
  name: 'Scout',
  role: 'Information Gatherer',
  goal: 'Find up-to-date information about the given query.',
  background: 'Research',
  type: 'ReactChampionAgent',
  tools: [searchTool] // Tavily search integration
});

const contentCreator = new Agent({
  name: 'Writer',
  role: 'Content Creator',
  goal: 'Generate a comprehensive summary of the gathered information.',
  background: 'Journalism',
  type: 'ReactChampionAgent',
  tools: []
});

// Define task workflow
const searchTask = new Task({
  description: `Search for detailed information about: {query}. Current date: {currentDate}.`,
  expectedOutput:
    'Detailed information about the topic with key facts and relevant details.',
  agent: searchAgent
});

const summarizeTask = new Task({
  description: `Using the gathered information, create a comprehensive summary.`,
  expectedOutput:
    'A well-structured summary with key points and main findings.',
  agent: contentCreator
});

3. A2A Protocol Integration

The core integration happens in the Agent Executor, which bridges A2A Protocol messages with KaibanJS workflows:

export class KaibanjsAgentExecutor implements AgentExecutor {
  public async execute(
    requestContext: RequestContext,
    eventBus: ExecutionEventBus
  ): Promise<void> {
    const { taskId, contextId, userMessage } = requestContext;

    // Extract query from A2A message
    const query = userMessage.parts
      .filter((part: Part) => part.kind === 'text')
      .map((part: Part) => (part as any).text)
      .join(' ');

    // Create KaibanJS team
    const team = createKaibanjsTeam(query);
    const useTeamStore = team.useStore();

    // Subscribe to workflow logs for real-time streaming
    const unsubscribe = useTeamStore.subscribe(state => {
      const { workflowLogs } = state;

      workflowLogs.forEach(log => {
        if (log) {
          // Stream workflow updates via A2A Protocol
          eventBus.publish({
            kind: 'artifact-update',
            taskId,
            contextId,
            artifact: {
              artifactId: `log-${Date.now()}`,
              parts: [{ kind: 'text', text: log.logDescription }],
              metadata: {
                timestamp: new Date().toISOString(),
                logType: log.logType,
                logMessage: `Agent Status: ${log.agentStatus}`
              }
            }
          });
        }
      });
    });

    // Execute the team workflow
    await team.start();

    // Send final result
    const finalState = useTeamStore.getState();
    const finalResult = finalState.workflowResult;

    if (finalResult) {
      eventBus.publish({
        kind: 'artifact-update',
        taskId,
        contextId,
        artifact: {
          artifactId: `result-${taskId}`,
          parts: [{ kind: 'text', text: JSON.stringify(finalResult, null, 2) }],
          metadata: {
            timestamp: new Date().toISOString(),
            type: 'final-result'
          }
        }
      });
    }

    // Complete the task
    eventBus.publish({
      kind: 'status-update',
      taskId,
      contextId,
      status: { state: 'completed', timestamp: new Date().toISOString() },
      final: true
    });
  }
}

4. Real-time Client Integration

The React client demonstrates how to consume A2A Protocol streams:

// A2A Client connection and message streaming
const stream = client.sendMessageStream({
  message: {
    messageId: uuidv4(),
    role: 'user',
    parts: [{ kind: 'text', text: query }],
    kind: 'message'
  }
});

for await (const event of stream) {
  if (event.kind === 'status-update') {
    // Handle status updates
    get().addLog('status', `Status: ${event.status.state}`);
  } else if (event.kind === 'artifact-update') {
    // Handle real-time workflow logs
    const textParts = event.artifact.parts.filter(part => part.kind === 'text');
    const content = textParts.map(part => (part as any).text).join('\n');
    get().addLog('artifact', content, event.artifact.metadata);
  }
}

Key Integration Points

1. Message Flow

  • Input: User queries arrive via A2A Protocol messages
  • Processing: KaibanJS team processes the query through specialized agents
  • Streaming: Workflow logs are streamed back via A2A artifact updates
  • Output: Final results are delivered through A2A Protocol artifacts

2. Real-time Communication

The integration enables real-time streaming of agent reasoning and workflow progress:

// Workflow log streaming
workflowLogs.forEach(log => {
  eventBus.publish({
    kind: 'artifact-update',
    taskId,
    contextId,
    artifact: {
      artifactId: `log-${Date.now()}`,
      parts: [{ kind: 'text', text: log.logDescription }],
      metadata: {
        logType: log.logType,
        logMessage: `Agent Status: ${log.agentStatus}`
      }
    }
  });
});

3. Error Handling

Robust error handling ensures graceful failure and proper A2A Protocol compliance:

catch (error) {
  // Send error as artifact
  eventBus.publish({
    kind: 'artifact-update',
    taskId,
    contextId,
    artifact: {
      artifactId: `error-${taskId}`,
      parts: [{ kind: 'text', text: `Error: ${error.message}` }],
      metadata: { timestamp: new Date().toISOString(), type: 'error' }
    }
  });

  // Mark task as failed
  eventBus.publish({
    kind: 'status-update',
    taskId,
    contextId,
    status: { state: 'failed', timestamp: new Date().toISOString() },
    final: true
  });
}

Benefits of This Integration

1. Universal Interoperability

  • Your KaibanJS agents can now communicate with any A2A-compliant agent
  • No vendor lock-in or custom integration work required
  • Future-proof architecture that adapts to new agent frameworks

2. Enhanced User Experience

  • Real-time streaming of agent reasoning and workflow progress
  • Transparent visibility into multi-agent collaboration
  • Standardized communication patterns

3. Scalable Architecture

  • Easy to add new agents and capabilities
  • Modular design allows for independent scaling
  • Standard protocols ensure consistent behavior

Getting Started

Prerequisites

  • Node.js 18+
  • API keys for OpenAI and Tavily
  • Basic understanding of TypeScript and React

Quick Setup

# Clone the repository
git clone https://github.com/kaiban-ai/a2a-protocol-kaibanjs-demo

# Install dependencies
npm run install:all

# Configure environment variables
cp server/env.example server/.env
# Add your API keys to server/.env

# Start the development servers
npm run dev

Try the Demo

  1. Open http://localhost:5173 in your browser
  2. Click "Connect to Server" to establish A2A connection
  3. Enter a research query (e.g., "What are the latest developments in AI?")
  4. Watch real-time logs as agents collaborate
  5. View the final research results

Live Demo

Experience the integration in action: A2A Protocol Integration Demo

Demo Video

Watch the A2A Protocol integration with KaibanJS in action - See real-time agent collaboration and streaming workflow logs

Conclusion

The integration of A2A Protocol with KaibanJS demonstrates how standardized protocols can unlock the full potential of multi-agent systems. By implementing this architecture, you can:

  • Build truly interoperable AI agent networks
  • Provide transparent, real-time visibility into agent workflows
  • Create scalable, maintainable multi-agent applications
  • Future-proof your AI systems against vendor lock-in

This approach represents the future of AI agent communication - one where different frameworks and platforms can work together seamlessly, creating more powerful and flexible AI systems.

Resources


This article demonstrates the practical implementation of A2A Protocol integration with KaibanJS. The code examples and architecture patterns shown here can be adapted for your own multi-agent applications.

Community

Sign up or log in to comment