# A2A JS SDK Complete Tutorial: Quick Start Guide **Published by:** [czmilo](https://paragraph.com/@zhangcheng/) **Published on:** 2025-06-09 **URL:** https://paragraph.com/@zhangcheng/a2a-js-sdk-complete-tutorial-quick-start-guide ## Content Table of ContentsWhat is A2A JS SDK?A2A JS Installation & SetupA2A JS Core ConceptsCreating Your First A2A JS AgentA2A JS Server DevelopmentA2A JS Client UsageA2A JS Advanced FeaturesA2A JS Best PracticesA2A JS TroubleshootingWhat is A2A JS SDK?A2A JS SDK is a powerful library designed specifically for JavaScript/TypeScript developers to build intelligent agent applications that comply with the Agent2Agent (A2A) Protocol. This A2A JS framework enables developers to easily create intelligent agent systems that can communicate and collaborate with each other.Core Advantages of A2A JS🚀 Easy to Use: A2A JS provides intuitive APIs that allow developers to get started quickly🔄 Real-time Communication: Supports streaming processing and Server-Sent Events (SSE)🛡️ Type Safety: Built on TypeScript, providing complete type support🌐 Cross-platform: A2A JS can run in both Node.js and browser environments📡 Standard Protocol: Fully implements A2A protocol specificationsA2A JS Installation & SetupInstalling A2A JS SDKInstall A2A JS SDK using npm:npm install a2a-sdk Or using yarn:yarn add a2a-sdk Verifying A2A JS InstallationCreate a simple test file to verify that A2A JS is correctly installed:import { A2AClient, AgentCard } from "a2a-sdk"; console.log("A2A JS SDK installed successfully!"); A2A JS Core ConceptsBefore starting to use A2A JS, it's important to understand the following core concepts:1. Agent CardEach agent in A2A JS requires an Agent Card that describes the agent's capabilities and interfaces:import { AgentCard } from "a2a-sdk"; const agentCard: AgentCard = { name: 'My A2A JS Agent', description: 'Intelligent agent built with A2A JS SDK', url: 'http://localhost:3000/', provider: { organization: 'A2A JS Developers', url: 'https://example.com' }, version: '1.0.0', capabilities: { streaming: true, pushNotifications: false, stateTransitionHistory: true, }, skills: [{ id: 'general_chat', name: 'General Chat', description: 'General conversation using A2A JS', tags: ['chat', 'a2a-js'], examples: ['Hello', 'Help me answer questions'] }] }; 2. Agent ExecutorThe core execution logic of A2A JS is implemented through AgentExecutor:import { AgentExecutor, RequestContext, IExecutionEventBus } from "a2a-sdk"; class MyA2AJSExecutor implements AgentExecutor { async execute( requestContext: RequestContext, eventBus: IExecutionEventBus ): Promise<void> { // Your A2A JS agent logic console.log("A2A JS agent is processing request..."); } async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> { console.log(`A2A JS canceling task: ${taskId}`); } } Creating Your First A2A JS AgentLet's create a complete agent example using A2A JS SDK:Step 1: Define A2A JS Agent Cardimport { AgentCard } from "a2a-sdk"; const myAgentCard: AgentCard = { name: 'Hello World A2A JS Agent', description: 'My first A2A JS agent for learning A2A JS SDK', url: 'http://localhost:3000/', provider: { organization: 'A2A JS Tutorial', url: 'https://example.com' }, version: '1.0.0', capabilities: { streaming: true, pushNotifications: false, stateTransitionHistory: true, }, defaultInputModes: ['text/plain'], defaultOutputModes: ['text/plain'], skills: [{ id: 'hello_world', name: 'Hello World', description: 'A2A JS example skill: respond to greetings', tags: ['hello', 'greeting', 'a2a-js'], examples: [ 'Hello', 'Hi there', 'Tell me about A2A JS' ], inputModes: ['text/plain'], outputModes: ['text/plain'] }], supportsAuthenticatedExtendedCard: false, }; Step 2: Implement A2A JS Executorimport { AgentExecutor, RequestContext, IExecutionEventBus, Task, TaskState, TaskStatusUpdateEvent } from "a2a-sdk"; import { v4 as uuidv4 } from "uuid"; class HelloWorldA2AJSExecutor implements AgentExecutor { private cancelledTasks = new Set<string>(); async cancelTask(taskId: string, eventBus: IExecutionEventBus): Promise<void> { this.cancelledTasks.add(taskId); console.log(`A2A JS executor canceling task: ${taskId}`); } async execute( requestContext: RequestContext, eventBus: IExecutionEventBus ): Promise<void> { const userMessage = requestContext.userMessage; const existingTask = requestContext.task; const taskId = existingTask?.id || uuidv4(); const contextId = userMessage.contextId || existingTask?.contextId || uuidv4(); console.log(`A2A JS agent processing message: ${userMessage.parts[0]?.text}`); // Create new task if (!existingTask) { const initialTask: Task = { kind: 'task', id: taskId, contextId: contextId, status: { state: TaskState.Submitted, timestamp: new Date().toISOString(), }, history: [userMessage], metadata: userMessage.metadata, artifacts: [], }; eventBus.publish(initialTask); } // Publish working status const workingUpdate: TaskStatusUpdateEvent = { kind: 'status-update', taskId: taskId, contextId: contextId, status: { state: TaskState.Working, message: { kind: 'message', role: 'agent', messageId: uuidv4(), parts: [{ kind: 'text', text: 'A2A JS agent is thinking...' }], taskId: taskId, contextId: contextId, }, timestamp: new Date().toISOString(), }, final: false, }; eventBus.publish(workingUpdate); // Simulate processing time await new Promise(resolve => setTimeout(resolve, 1000)); // Check cancellation status if (this.cancelledTasks.has(taskId)) { const cancelledUpdate: TaskStatusUpdateEvent = { kind: 'status-update', taskId: taskId, contextId: contextId, status: { state: TaskState.Canceled, timestamp: new Date().toISOString(), }, final: true, }; eventBus.publish(cancelledUpdate); return; } // Generate response const userText = userMessage.parts[0]?.text || ''; let responseText = ''; if (userText.toLowerCase().includes('hello') || userText.toLowerCase().includes('hi')) { responseText = `Hello! Welcome to A2A JS SDK! I'm an intelligent agent built with A2A JS.`; } else if (userText.toLowerCase().includes('a2a js')) { responseText = `A2A JS SDK is a powerful JavaScript library for building intelligent agent applications!`; } else { responseText = `I'm an A2A JS agent and I received your message: "${userText}". Thank you for using A2A JS SDK!`; } // Publish final result const finalUpdate: TaskStatusUpdateEvent = { kind: 'status-update', taskId: taskId, contextId: contextId, status: { state: TaskState.Completed, message: { kind: 'message', role: 'agent', messageId: uuidv4(), parts: [{ kind: 'text', text: responseText }], taskId: taskId, contextId: contextId, }, timestamp: new Date().toISOString(), }, final: true, }; eventBus.publish(finalUpdate); } } Step 3: Start A2A JS Serverimport express from 'express'; import { A2AExpressApp, DefaultRequestHandler, InMemoryTaskStore } from "a2a-sdk"; const taskStore = new InMemoryTaskStore(); const agentExecutor = new HelloWorldA2AJSExecutor(); const requestHandler = new DefaultRequestHandler( myAgentCard, taskStore, agentExecutor ); const appBuilder = new A2AExpressApp(requestHandler); const expressApp = appBuilder.setupRoutes(express(), ''); const PORT = process.env.PORT || 3000; expressApp.listen(PORT, () => { console.log(`A2A JS agent server started at http://localhost:${PORT}`); console.log(`A2A JS agent card: http://localhost:${PORT}/.well-known/agent.json`); console.log('Press Ctrl+C to stop A2A JS server'); }); A2A JS Server DevelopmentTask StorageA2A JS provides in-memory task storage, and you can also implement custom storage:import { TaskStore, Task } from "a2a-sdk"; class CustomA2AJSTaskStore implements TaskStore { private tasks = new Map<string, Task>(); async getTask(taskId: string): Promise<Task | undefined> { console.log(`A2A JS getting task: ${taskId}`); return this.tasks.get(taskId); } async setTask(task: Task): Promise<void> { console.log(`A2A JS saving task: ${task.id}`); this.tasks.set(task.id, task); } async deleteTask(taskId: string): Promise<void> { console.log(`A2A JS deleting task: ${taskId}`); this.tasks.delete(taskId); } } Middleware SupportA2A JS is based on Express.js and supports all standard middleware:import cors from 'cors'; import express from 'express'; const app = express(); // A2A JS server middleware configuration app.use(cors()); app.use(express.json()); // Custom A2A JS logging middleware app.use((req, res, next) => { console.log(`A2A JS request: ${req.method} ${req.path}`); next(); }); A2A JS Client UsageBasic Client Operationsimport { A2AClient, MessageSendParams } from "a2a-sdk"; import { v4 as uuidv4 } from "uuid"; const client = new A2AClient("http://localhost:3000"); async function testA2AJSClient() { console.log("Testing A2A JS client..."); const messageParams: MessageSendParams = { message: { messageId: uuidv4(), role: "user", parts: [{ kind: "text", text: "Hello, A2A JS!" }], kind: "message" }, configuration: { blocking: true, acceptedOutputModes: ['text/plain'] } }; try { const response = await client.sendMessage(messageParams); if (response.error) { console.error("A2A JS client error:", response.error); return; } console.log("A2A JS response:", response.result); } catch (error) { console.error("A2A JS communication error:", error); } } testA2AJSClient(); A2A JS StreamingA2A JS supports real-time streaming communication:import { A2AClient, TaskStatusUpdateEvent } from "a2a-sdk"; async function streamA2AJSResponse() { const client = new A2AClient("http://localhost:3000"); console.log("Starting A2A JS streaming..."); const streamParams = { message: { messageId: uuidv4(), role: "user", parts: [{ kind: "text", text: "Stream conversation using A2A JS" }], kind: "message" } }; try { const stream = client.sendMessageStream(streamParams); for await (const event of stream) { if (event.kind === 'task') { console.log(`A2A JS task created: ${event.id}`); } else if (event.kind === 'status-update') { const statusEvent = event as TaskStatusUpdateEvent; console.log(`A2A JS status update: ${statusEvent.status.state}`); if (statusEvent.status.message?.parts[0]?.text) { console.log(`A2A JS message: ${statusEvent.status.message.parts[0].text}`); } if (statusEvent.final) { console.log("A2A JS streaming completed"); break; } } } } catch (error) { console.error("A2A JS streaming error:", error); } } A2A JS Advanced FeaturesArtifact HandlingA2A JS supports creation and management of artifacts:import { TaskArtifactUpdateEvent } from "a2a-sdk"; // Publishing artifacts in AgentExecutor const artifactUpdate: TaskArtifactUpdateEvent = { kind: 'artifact-update', taskId: taskId, contextId: contextId, artifact: { artifactId: "a2a-js-example", name: "A2A JS Example File", parts: [{ text: `# A2A JS Generated Content\n\nThis is an example file generated using A2A JS SDK.` }], }, append: false, lastChunk: true, }; eventBus.publish(artifactUpdate); Security ConfigurationConfigure security options for A2A JS agents:const secureAgentCard: AgentCard = { name: 'Secure A2A JS Agent', description: 'Secure A2A JS agent', // ... other configurations securitySchemes: { apiKey: { type: 'apiKey', name: 'X-API-Key', in: 'header' } }, security: [{ apiKey: [] }] }; A2A JS Best Practices1. Error HandlingImplement comprehensive error handling in A2A JS applications:class RobustA2AJSExecutor implements AgentExecutor { async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) { try { // A2A JS execution logic await this.processRequest(requestContext, eventBus); } catch (error) { console.error("A2A JS execution error:", error); // Publish error status const errorUpdate: TaskStatusUpdateEvent = { kind: 'status-update', taskId: requestContext.task?.id || uuidv4(), contextId: requestContext.userMessage.contextId || uuidv4(), status: { state: TaskState.Failed, message: { kind: 'message', role: 'agent', messageId: uuidv4(), parts: [{ kind: 'text', text: 'An error occurred during A2A JS processing, please try again later.' }], }, timestamp: new Date().toISOString(), }, final: true, }; eventBus.publish(errorUpdate); } } } 2. Performance OptimizationOptimize your A2A JS application performance:// Optimize A2A JS client with connection pooling const client = new A2AClient("http://localhost:3000", { keepAlive: true, timeout: 30000 }); // A2A JS agent response caching class CachedA2AJSExecutor implements AgentExecutor { private cache = new Map<string, string>(); async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) { const userText = requestContext.userMessage.parts[0]?.text || ''; const cacheKey = `a2a-js-${userText}`; // Check A2A JS cache if (this.cache.has(cacheKey)) { console.log("A2A JS using cached response"); // Return cached response } // Process new request and cache result } } 3. LoggingAdd detailed logging to A2A JS applications:import { createLogger, format, transports } from 'winston'; const a2aJSLogger = createLogger({ level: 'info', format: format.combine( format.timestamp(), format.printf(({ timestamp, level, message }) => { return `[A2A JS] ${timestamp} ${level}: ${message}`; }) ), transports: [ new transports.Console(), new transports.File({ filename: 'a2a-js.log' }) ] }); // Use in A2A JS code a2aJSLogger.info('A2A JS agent started successfully'); a2aJSLogger.error('A2A JS processing error', { error: errorDetails }); A2A JS TroubleshootingCommon Issue Resolution1. A2A JS Connection Issues// Check A2A JS server connection async function checkA2AJSConnection() { try { const client = new A2AClient("http://localhost:3000"); const response = await fetch("http://localhost:3000/.well-known/agent.json"); if (response.ok) { console.log("A2A JS server connection normal"); } else { console.error("A2A JS server response abnormal:", response.status); } } catch (error) { console.error("A2A JS connection failed:", error); } } You can also try the following methods:A2A Protocol ValidatorGuide: How to Validate Your Agent Card2. A2A JS Type ErrorsEnsure correct A2A JS type imports:// Correct A2A JS type imports import { AgentCard, AgentExecutor, A2AClient, Task, TaskState, Message, MessageSendParams } from "a2a-sdk"; 3. A2A JS Performance Debugging// A2A JS performance monitoring class PerformanceA2AJSExecutor implements AgentExecutor { async execute(requestContext: RequestContext, eventBus: IExecutionEventBus) { const startTime = Date.now(); console.log(`A2A JS started processing: ${startTime}`); try { // Your A2A JS logic await this.processRequest(requestContext, eventBus); } finally { const endTime = Date.now(); console.log(`A2A JS processing completed, duration: ${endTime - startTime}ms`); } } } SummaryA2A JS SDK is a powerful tool for building intelligent agent applications. Through this tutorial, you have learned:Core concepts and architecture of A2A JSHow to create and configure A2A JS agentsA2A JS server and client developmentAdvanced features and best practices of A2A JSTroubleshooting methods for A2A JS applicationsNow you can start building your own A2A JS applications! Remember, A2A JS SDK provides rich functionality to help you create powerful, scalable intelligent agent systems. For more A2A JS resources and examples, please visit:A2A JS GitHub RepositoryA2A JS Sample ProjectsA2A Protocol DocumentationStart your A2A JS development journey! 🚀 https://a2aprotocol.ai/blog/a2a-javascript-sdk ) ## Publication Information - [czmilo](https://paragraph.com/@zhangcheng/): Publication homepage - [All Posts](https://paragraph.com/@zhangcheng/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@zhangcheng): Subscribe to updates