Integrating Mastra Agents with Telex via A2A Requests
These articles are AI-generated summaries. Please check the original sources for full details.
Integrating Mastra Agents with Telex via A2A Requests
This guide demonstrates how to integrate Mastra AI agents with the Telex platform using A2A (App-to-App) requests to enable real-time, structured communication between the two systems. The integration leverages JSON-RPC 2.0 for message exchange, allowing Telex to send prompts to Mastra agents and receive intelligent responses. The implementation includes local setup, custom API route creation, and deployment to Mastra Cloud.
Overview
Goal
Create a two-way communication channel where:
- Telex sends structured messages (e.g., “word to describe not feeling like socializing”)
- Mastra processes the message using an AI agent and returns a response (e.g., “Reclusive — Meaning: Avoiding the company of other people…”)
Stack Used
- Mastra: Framework for building AI agents
- Node.js + TypeScript: Backend development
- Telex: Educational platform for messaging
- Mastra Cloud: Deployment and public endpoint exposure
Key Implementation Steps
1. Setting Up Mastra Locally
-
Project Initialization
mkdir telex-mastra-agent && cd telex-mastra-agent npm init -y npm install @mastra/core @mastra/agents npm install -D typescript ts-node @types/node npx tsc --init -
Agent Definition
Createsrc/agents/word-agent.tsto define an agent that analyzes user messages:import { Agent } from "@mastra/agents"; export const wordAgent = new Agent({ name: "wordAgent", instructions: "Analyze a user's message and determine the emotional tone or meaning.", });
2. Understanding Telex A2A Request Format
Telex sends messages via JSON-RPC 2.0. Example request:
{
"jsonrpc": "2.0",
"id": "request-001",
"method": "message/send",
"params": {
"message": {
"kind": "message",
"role": "user",
"parts": [
{ "kind": "text", "text": "not feeling like socializing" }
],
"messageId": "msg-001"
},
"configuration": { "blocking": true }
}
}
Validation Requirements
jsonrpcmust be"2.0"idis required- Only
method: "message/send"is supported
3. Creating a Custom A2A Endpoint
Code Implementation
Create a2aRouter.ts to handle Telex requests and route them to Mastra agents:
import { registerApiRoute } from "@mastra/core/server";
import { randomUUID } from "crypto";
import { wordAgent } from "../src/agents/word-agent";
export const a2aAgentRoute = registerApiRoute("/a2a/agent/:agentId", {
method: "POST",
handler: async (c) => {
try {
const mastra = c.get("mastra");
const agentId = c.req.param("agentId");
const body = await c.req.json();
const { jsonrpc, id: requestId, method, params } = body || {};
// Validate JSON-RPC format
if (jsonrpc !== "2.0" || !requestId) {
return c.json({
jsonrpc: "2.0",
id: requestId || null,
error: {
code: -32600,
message: 'Invalid Request: "jsonrpc" must be "2.0" and "id" is required',
},
}, 400);
}
// Validate method
if (method !== "message/send") {
return c.json({
jsonrpc: "2.0",
id: requestId,
error: {
code: -32601,
message: `Unsupported method: "${method}". Only "message/send" is allowed.`,
},
}, 400);
}
// Extract user text
const userText = params?.message?.parts
?.find((p: any) => p.kind === "text")?.text?.trim() || "";
if (!userText) {
return c.json({
jsonrpc: "2.0",
id: requestId,
error: {
code: -32602,
message: 'Invalid params: "message.parts[0].text" is required',
},
}, 400);
}
// Resolve agent and process input
const agent = agentId === "wordAgent" ? wordAgent : mastra.getAgent(agentId);
const input = { action: userText, context: userText };
let agentText = "";
if ((agent as any).run) {
const agentResponse = await (agent as any).run(input);
agentText = agentResponse?.output?.text ?? agentResponse?.text ?? "";
} else if ((agent as any).generate) {
const agentResponse = await (agent as any).generate(userText);
agentText = agentResponse?.text ?? "";
} else {
throw new Error("Agent does not support run() or generate()");
}
// Construct Telex-style response
const result = {
id: randomUUID(),
status: {
state: "completed",
timestamp: new Date().toISOString(),
message: {
kind: "message",
role: "agent",
parts: [{ kind: "text", text: agentText }],
messageId: randomUUID(),
taskId: randomUUID(),
contextId: randomUUID(),
},
},
kind: "task",
};
return c.json({
jsonrpc: "2.0",
id: requestId,
result,
});
} catch (error) {
console.error("A2A route error:", error);
return c.json({
jsonrpc: "2.0",
id: null,
error: {
code: -32603,
message: error?.message || "Internal server error",
},
}, 500);
}
},
});
Purpose
- Validates incoming Telex requests
- Extracts user text for processing
- Routes to the correct Mastra agent
- Returns a structured Telex-compatible response
4. Linking the Route to Mastra
Update mastra/index.ts to register the custom route:
import { Mastra } from "@mastra/core/mastra";
import { a2aAgentRoute } from "./a2aRouter";
export const mastra = new Mastra({
server: {
apiRoutes: [a2aAgentRoute],
},
});
Result
The endpoint http://localhost:4111/a2a/agent/wordAgent becomes accessible for testing.
5. Deploying to Mastra Cloud
Deploy the project using:
npx mastra deploy
Post-Deployment
- A public URL like
https://white-cloud-noon.mastra.cloud/a2a/agent/wordAgentis generated - This URL is registered in Telex for A2A app configuration
Key Takeaways
- Custom Routes: Mastra allows extending its API for specialized integrations
- JSON-RPC Compliance: Telex requires strict adherence to JSON-RPC 2.0 format
- Real-Time Communication: A2A integration enables seamless interaction between conversational platforms and AI agents
Working Example
// a2aRouter.ts (simplified)
import { registerApiRoute } from "@mastra/core/server";
import { randomUUID } from "crypto";
import { wordAgent } from "../agents/word-agent";
export const a2aAgentRoute = registerApiRoute("/a2a/agent/:agentId", {
method: "POST",
handler: async (c) => {
const body = await c.req.json();
const { method, params } = body;
if (method !== "message/send") {
return c.json({ error: "Unsupported method" }, 400);
}
const userText = params.message.parts.find(p => p.kind === "text")?.text;
const agentResponse = await wordAgent.run({ action: userText, context: userText });
return c.json({
jsonrpc: "2.0",
result: {
status: {
message: {
parts: [{ kind: "text", text: agentResponse.text }],
},
},
},
});
},
});
Recommendations
- Use TypeScript: Ensures type safety for JSON-RPC and agent inputs
- Validate Inputs: Always check for required fields (e.g.,
jsonrpc,id) - Error Handling: Return detailed JSON-RPC errors for debugging
- Test with Real Scenarios: Simulate Telex messages to validate agent responses
- Avoid Hardcoding: Use environment variables for agent IDs and endpoints
Potential Pitfalls
- Incorrect JSON-RPC formatting may cause Telex to reject requests
- Failing to handle
run()andgenerate()methods in agents can break processing - Misconfigured Telex app settings may prevent message delivery
Reference
https://dev.to/modinat_adesola_0ea6e1d30/integrating-mastra-agents-with-telex-via-a2a-requests-28h8
Continue reading
Next article
Java News Roundup: OpenJDK JEPs, Spring RCs, and Tool Updates for JDK 26 and Beyond
Related Content
Web-Aware AI Smart Contracts: Bridging On-Chain and Off-Chain Worlds with GenLayer
GenLayer introduces Trustless Decision-Making via Intelligent Contracts in Python, enabling native web access and LLM integration for non-deterministic on-chain consensus.
Mastering AWS Lambda for Real-Time Pipelines: A Technical Deep Dive
Optimize AWS Lambda performance using memory-CPU scaling, VPC integration, and Kinesis stream processing with a 15-minute execution limit.
Engineering Communication: Structured Scripts for Text-Based Conflict Resolution
Optimize remote engineering collaboration using structured scripts that prevent escalation and resolve technical conflicts when face-to-face communication is unavailable.