21. ACP (Agent Communication Protocol)
The ACP (Agent Communication Protocol) support in MALDA enables MALDA agents to communicate with external ACP agents and expose MALDA agents as ACP-compliant agents. This allows for distributed agent orchestration across different systems and frameworks.
21.1 Overview
ACP is an open protocol for agent-to-agent communication that enables AI agents to collaborate across different frameworks, programming languages, and organizations. MALDA's ACP implementation provides:
- ACPClient: Connect to external ACP agents and send messages
- ACPServer: Expose MALDA agents as ACP-compliant agents via HTTP
- ACPAgentTool: Use external ACP agents as tools for MALDA agents
21.2 ACPClient Class
The ACPClient class allows MALDA agents to communicate with external ACP agents via REST API.
Constructor
var client = new ACPClient(baseUrl, apiKey?);
Parameters:
baseUrl(string): Base URL of the ACP server (e.g., "https://acp.example.com")apiKey(string, optional): API key for authentication (Bearer token)
Properties
baseUrl(string): The base URL of the ACP serverisConnected(boolean): Always returnstruefor HTTP client
Methods
discoverAgents(): Returns an array of available agents from the ACP servergetAgentManifest(agentId): Gets the manifest (metadata) for a specific agentsendMessage(agentId, message, timeoutMs?, sessionId?): Sends a message synchronously and returns the response. OptionalsessionIdkeeps history across runs (see 21.11)sendMessageAsync(agentId, message, timeoutMs?): Sends a message asynchronously and returns run IDsendMessageStream(agentId, message, timeoutMs?): Sends a message with streaming and returns accumulated responsegetRunStatus(agentId, runId): Gets the status of a running agent executioncancelRun(agentId, runId): Cancels a running agent executionresumeRun(agentId, runId, input): Resumes an awaiting agent execution with inputgetSession(sessionId): Gets session details including history
Example: Discovering and Communicating with External Agents
// Create ACP client
var client = new ACPClient("https://acp.example.com", "my-api-key");
// Discover available agents
var agents = client.discoverAgents();
print("Available agents:");
var i = 0;
while (i < length(agents)) {
var agent = agents[i];
print(agent.name + ": " + agent.description);
i = i + 1;
}
// Send message to an external ACP agent
var response = client.sendMessage("translation-agent", "Translate 'Hello' to Spanish", 5000);
print("Response: " + response);
21.3 ACPServer Class
The ACPServer class exposes MALDA agents as ACP-compliant agents via HTTP server, allowing external ACP clients to communicate with MALDA agents.
Constructor
var server = new ACPServer(port);
Parameters:
port(integer): Port number to listen on (1-65535)
Properties
port(integer): The port number the server is listening onisRunning(boolean): Whether the server is currently running
Methods
registerAgent(agentId, agentInstance, manifest?): Registers a MALDA agent as an ACP-compliant agentstart(): Starts the ACP server and begins listening for requestsstop(): Stops the ACP servergetRegisteredAgents(): Returns an array of registered agents
REST API Endpoints
The ACPServer exposes the following REST endpoints:
GET /agents: List all registered agentsGET /agents/{id}: Get agent manifestPOST /agents/{id}/runs: Send a message to an agent (create a run)
Example: Exposing MALDA Agent as ACP Agent
// Create a MALDA agent
var client = new OpenRouterClient();
var myAgent = new Agent(
"CodeHelper",
"coding assistant",
"You help with programming tasks.",
client
);
// Expose as ACP agent
var server = new ACPServer(8080);
server.registerAgent("code-helper-001", myAgent, {
"name": "CodeHelper",
"description": "A coding assistant agent",
"version": "1.0.0"
});
server.start();
print("MALDA agent exposed at http://localhost:8080/agents/code-helper-001");
// Keep server running
while (server.isRunning) {
sleep(1000);
}
21.4 ACPAgentTool Class
The ACPAgentTool class wraps an external ACP agent as a MALDA tool, allowing it to be used by MALDA agents via tool calling.
Constructor
var tool = new ACPAgentTool(acpClient, agentId, description);
Parameters:
acpClient(ACPClient): An ACPClient instance connected to the ACP serveragentId(string): The ID of the external ACP agent to use as a tooldescription(string): Description of what the tool does (used by LLM for tool selection)
Example: Using External ACP Agent as Tool
// Create ACP client
var acpClient = new ACPClient("https://acp.example.com");
// Create tool wrapper for external ACP agent
var translationTool = new ACPAgentTool(
acpClient,
"translation-agent",
"Translates text between languages"
);
// Add to MALDA agent
var client = new OpenRouterClient();
var myAgent = new Agent("Helper", "assistant", "You help users", client);
myAgent.addTool(translationTool);
// Agent can now use the external ACP agent via tool calling
var response = myAgent.think("Translate 'Hello' to Spanish");
print(response.content);
21.5 Use Cases
Distributed Agent Orchestration
Connect MALDA agents with agents running in other systems:
// Local MALDA agents
var writer = new Agent("Writer", "writer", "...", client);
var editor = new Agent("Editor", "editor", "...", client);
// External ACP agent
var acpClient = new ACPClient("https://acp.example.com");
var translator = new ACPAgentTool(acpClient, "translation-agent", "Translates text");
// Orchestrate workflow
function createMultilingualDoc(topic) {
// Step 1: Local agent writes
var doc = writer.think("Write about: " + topic);
// Step 2: External ACP agent translates (via tool)
editor.addTool(translator);
editor.getConversation().addUserMessage("Translate to Spanish: " + doc.content);
var translated = editor.getConversation().send();
return translated.content;
}
Exposing MALDA Agents to External Systems
Make MALDA agents available to other ACP-compatible systems:
var server = new ACPServer(8080);
server.registerAgent("malda-coder", codingAgent);
server.registerAgent("malda-reviewer", reviewAgent);
server.start();
// External systems can now communicate with MALDA agents via ACP protocol
21.6 ACP vs MCP
ACP and MCP serve different purposes:
- MCP (Model Context Protocol): Connects AI applications with tools and data sources. Focus: one model, many tools
- ACP (Agent Communication Protocol): Enables communication between independent AI agents. Focus: many agents, peer-to-peer communication
They can be used together: MALDA agents can use MCP tools (via MCPClient) and also communicate with other agents via ACP.
21.7 Message Format
ACP uses a message format with multiple parts, each with content and a MIME type. MALDA automatically converts:
- Outbound: MALDA strings → ACP message format (single text part)
- Inbound: ACP message format → MALDA strings (joins all text parts)
This allows MALDA agents to work seamlessly with ACP without needing to handle the message format directly.
21.8 Execution Modes
Synchronous Execution
Default mode - waits for agent to complete:
var response = client.sendMessage("agent-id", "Hello");
print(response);
Asynchronous Execution
Returns run ID immediately, poll for status:
var runId = client.sendMessageAsync("agent-id", "Hello");
var status = client.getRunStatus("agent-id", runId);
while (status.status == "in-progress" || status.status == "created") {
sleep(100);
status = client.getRunStatus("agent-id", runId);
}
print("Final status: " + status.status);
if (status.message != null) {
print("Response: " + status.message);
}
Streaming Execution
Receives incremental updates via Server-Sent Events:
var response = client.sendMessageStream("agent-id", "Hello");
print("Streamed response: " + response);
21.9 Run Cancellation
Long-running agent executions can be cancelled:
var runId = client.sendMessageAsync("agent-id", "Long running task");
// ... later ...
client.cancelRun("agent-id", runId);
21.10 Await/Resume
__ACP_AWAIT__:… is an agent convention, not a MALDA keyword. If the agent’s reply starts with that marker, the ACP server marks the run as awaiting and the client calls resumeRun with user input. Same idea: Examples/ACP/await_resume.malda. These samples need two processes (server and client).
// Agent code (uses special marker or tool)
// When agent needs input, it responds with: "__ACP_AWAIT__:Please provide your name"
// Client code
var runId = client.sendMessageAsync("agent-id", "Ask for user name");
var status = client.getRunStatus("agent-id", runId);
if (status.status == "awaiting") {
var userInput = input("Enter your name: ");
var response = client.resumeRun("agent-id", runId, userInput);
print(response);
}
21.11 Session Management
Maintain stateful conversations across multiple runs:
var sessionId = "session-" + random();
var response1 = client.sendMessage("agent-id", "My name is Alice", 30000, sessionId);
var response2 = client.sendMessage("agent-id", "What is my name?", 30000, sessionId);
var session = client.getSession(sessionId);
print("Session history: " + length(session.history) + " runs");
21.12 Error Handling
ACP operations may throw exceptions in the following cases:
- Network errors when connecting to ACP servers
- Invalid agent IDs or missing agents
- Timeout errors when waiting for agent responses
- Invalid message formats
Errors are returned as structured objects with code, message, and optional data fields. Always wrap ACP calls in try-catch blocks for production code:
try {
var response = client.sendMessage("agent-id", "Hello", 5000);
print(response);
} catch (error) {
print("Error: " + error);
}
See Also
- 18. Agent Orchestration - Creating and using MALDA agents
- 20. MCP Server - MCP protocol for tools and data sources
- 27. REST API Server - Creating REST APIs in MALDA
- Runnable sketches in
Examples/ACP/