Let's build an agent that connects to the mesh, registers itself, finds other agents, and handles incoming requests. The whole thing is about 30 lines of code.
Prerequisites: Node.js 18+
npm install agentmesh
This gives you everything you need — connection handling, envelope building, the works.
import { AgentMesh } from "agentmesh";
const mesh = await AgentMesh.connect("ws://your-nats-server:4443");
This creates a WebSocket connection to the mesh. Once connected, your agent has a unique ID and can start communicating.
await mesh.register({
name: "My First Agent",
description: "A friendly agent that echoes messages back",
capabilities: ["echo"],
skills: [
{
id: "echo",
name: "Echo",
description: "Returns whatever you send it",
},
],
});
Now every other agent on the mesh can find you. Your manifest is stored in the registry, and you'll show up in discovery queries.
mesh.onRequest("echo", (payload, ctx) => {
const input = payload.input as { text: string };
return { text: `Echo: ${input.text}` };
});
When another agent asks you to use your 'echo' skill, this function runs. Whatever you return becomes the response.
const result = await mesh.discover();
for (const agent of result.agents) {
console.log(`${agent.name} — ${agent.availability}`);
}
This queries the registry and returns every online agent. You can filter by capability or skill too.
const agent = result.agents[0];
const response = await mesh.request(agent.id, "echo", {
text: "Hello from my first agent!",
});
console.log(response.payload.output);
// { text: "Echo: Hello from my first agent!" }
You pick an agent, choose a skill, send input, and get output back. The mesh handles routing, tracing, and error handling.
await mesh.close();
Always close your connection when you're done.
Here's the complete agent in a single file. Copy this, swap in your server address, and run it.
import { AgentMesh } from "agentmesh";
// Connect to the mesh
const mesh = await AgentMesh.connect("ws://your-nats-server:4443");
// Register this agent
await mesh.register({
name: "My First Agent",
description: "A friendly agent that echoes messages back",
capabilities: ["echo"],
skills: [
{
id: "echo",
name: "Echo",
description: "Returns whatever you send it",
},
],
});
// Handle incoming echo requests
mesh.onRequest("echo", (payload, ctx) => {
const input = payload.input as { text: string };
return { text: `Echo: ${input.text}` };
});
// Discover other agents on the mesh
const result = await mesh.discover();
for (const agent of result.agents) {
console.log(`${agent.name} — ${agent.availability}`);
}
// Send a request to the first agent found
const target = result.agents[0];
const response = await mesh.request(target.id, "echo", {
text: "Hello from my first agent!",
});
console.log(response.payload.output);
// { text: "Echo: Hello from my first agent!" }
// Disconnect
await mesh.close();
In those ~30 lines, your agent did everything a mesh participant needs to do:
The mesh handled all the hard parts behind the scenes — message routing, envelope construction, distributed tracing, and error propagation. Your code just focused on the logic.