MQTT.Agent

Run MQTT.Agent on a local Mosquitto broker

⚠️ Future direction. This guide describes the planned standalone experience using vanilla Mosquitto with no account. The published @cloudsignal/agent v0.1.1 and @cloudsignal/mcp-over-mqtt packages currently require CloudSignal-style credentials (orgId + tokenServiceUrl); the anonymous-auth variant shown below will land in a future minor release. For working-today code against a CloudSignal-style broker, see @cloudsignal/agent and @cloudsignal/mcp-over-mqtt.

This guide walks you through standing up a complete MQTT.Agent testbed on your laptop: a local Mosquitto broker plus the two reference SDK packages (@cloudsignal/agent and @cloudsignal/mcp-over-mqtt). At the end you will have an MQTT-backed agent calling an MQTT-backed MCP tool, end to end, with no broker account or external service.

Prerequisites

  • Docker (for the Mosquitto container) - any recent version.
  • Node.js 20 or later.
  • A scratch directory to put four files in. No existing project required.
  • Familiarity with running shell commands. No prior MQTT knowledge needed.

Steps

1. Create the broker compose file

In your scratch directory, create docker-compose.yml:

services:
  mosquitto:
    image: eclipse-mosquitto:2
    ports:
      - "1883:1883"
    volumes:
      - ./mosquitto.conf:/mosquitto/config/mosquitto.conf

2. Create the broker config

Create mosquitto.conf in the same directory:

listener 1883
allow_anonymous true

This config accepts unauthenticated connections on port 1883. That is fine for a local testbed; do not use it in production.

3. Bring up the broker

docker compose up -d

Expected: the container starts and docker compose ps shows mosquitto as running. Port 1883 is now listening on localhost.

4. Install the SDK packages

npm install @cloudsignal/mcp-over-mqtt @cloudsignal/agent

Expected: both packages install. The transitive @cloudsignal/mqtt-client lands automatically.

5. Create the tool server

Create tool-server.ts:

import { MCPServer, defineTool } from '@cloudsignal/mcp-over-mqtt';
 
const echoTool = defineTool({
  name: 'echo',
  description: 'Echoes input back to the caller.',
  input_schema: {
    type: 'object',
    properties: { text: { type: 'string' } },
    required: ['text'],
  },
  handler: async ({ args }) => ({ echo: args.text }),
});
 
const server = new MCPServer({
  name: 'example-server',
  tools: [echoTool],
  broker: 'mqtt://localhost:1883',
  credentials: { anonymous: true }, // planned
});
 
await server.start();

This registers a single MCP tool called echo that returns whatever text you pass it. The defineTool helper validates the JSON Schema and binds the handler; MCPServer then registers the tool on the broker.

6. Create the agent

Create agent.ts:

import { MCPClient } from '@cloudsignal/mcp-over-mqtt';
 
const client = new MCPClient({
  clientId: 'agent-a',
  broker: 'mqtt://localhost:1883',
  credentials: { anonymous: true }, // planned
});
 
await client.start();
const result = await client.call('echo', { text: 'hello' });
console.log(result);

The client connects to the same broker, finds the echo tool, and calls it. (In a future SDK release, an Agent instance for A2A peer presence could be created alongside the MCPClient for richer behavior; today's published MCPClient handles the tool-call side cleanly on its own.)

7. Run the tool server

In one terminal:

npx tsx tool-server.ts

Expected: the process connects to the broker, publishes its tool card on a retained topic, and stays running while waiting for calls. You should see no errors. Leave this terminal open.

8. Run the agent

In a second terminal:

npx tsx agent.ts

Expected: the agent connects, finds the tool, calls it, and prints:

{ echo: 'hello' }

The agent process exits after the call completes.

Verification

You have a working MQTT.Agent stack if all of the following are true:

  • The Mosquitto container is running (docker compose ps).
  • The tool server stays connected without errors.
  • The agent prints { echo: 'hello' } and exits cleanly.

If the agent hangs or errors, check that the tool server is running and connected to the same broker URL. Both processes must use mqtt://localhost:1883.

Note: this guide is currently aspirational pending a future SDK release adding anonymous-auth support; see the callout at the top of this page.

Next steps