# https://github.com/qualixar/slm-mesh Project Manual

Generated at: 2026-06-20 04:51:35 UTC

## Table of Contents

- [Overview and System Architecture](#page-1)
- [MCP Tools, Claude Code Skills, CLI, and Python Client](#page-2)
- [Multi-Machine Setup, WebSocket Transport, and Agent Integrations](#page-3)
- [Configuration, Security, Adapters, and Operations](#page-4)

<a id='page-1'></a>

## Overview and System Architecture

### Related Pages

Related topics: [MCP Tools, Claude Code Skills, CLI, and Python Client](#page-2), [Multi-Machine Setup, WebSocket Transport, and Agent Integrations](#page-3), [Configuration, Security, Adapters, and Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/qualixar/slm-mesh/blob/main/README.md)
- [package.json](https://github.com/qualixar/slm-mesh/blob/main/package.json)
- [tsup.config.ts](https://github.com/qualixar/slm-mesh/blob/main/tsup.config.ts)
- [CHANGELOG.md](https://github.com/qualixar/slm-mesh/blob/main/CHANGELOG.md)
- [SECURITY.md](https://github.com/qualixar/slm-mesh/blob/main/SECURITY.md)
- [CONTRIBUTING.md](https://github.com/qualixar/slm-mesh/blob/main/CONTRIBUTING.md)
- [src/index.ts](https://github.com/qualixar/slm-mesh/blob/main/src/index.ts)
- [src/config.ts](https://github.com/qualixar/slm-mesh/blob/main/src/config.ts)
- [src/types.ts](https://github.com/qualixar/slm-mesh/blob/main/src/types.ts)
- [src/mcp/server.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/server.ts)
- [src/cli/cli.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/cli.ts)
- [src/cli/format.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/format.ts)
- [src/db/schema.ts](https://github.com/qualixar/slm-mesh/blob/main/src/db/schema.ts)
- [src/adapters/backend.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/backend.ts)
- [src/adapters/memory-bridge.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/memory-bridge.ts)
- [python/src/slm_mesh/client.py](https://github.com/qualixar/slm-mesh/blob/main/python/src/slm_mesh/client.py)
</details>

# Overview and System Architecture

## Purpose and Scope

SLM Mesh is a peer-to-peer communication layer for AI coding agents. It enables multiple AI agent sessions running on the same machine (or across machines on the same LAN) to discover each other, exchange structured messages, share state, coordinate file edits, and react to events in real time. The project is published as the `slm-mesh` npm package (v1.3.4) and is part of the Qualixar research initiative, powered by SuperLocalMemory. Source: [package.json:1-30](), [README.md:1-30]().

The system is intentionally local-first: it binds only to localhost, requires no cloud dependency, performs no telemetry, and exposes its functionality either through a CLI or as a Model Context Protocol (MCP) server that AI agents consume natively. Source: [SECURITY.md:1-30](), [README.md:30-60]().

## High-Level Architecture

SLM Mesh is organized around three runtime components that share a common local SQLite database, plus two pluggable adapter contracts for extension.

```mermaid
flowchart LR
    subgraph AI[AI Agent Hosts]
        CC[Claude Code MCP Client]
        CU[Cursor MCP Client]
        AI2[Aider / Codex / Windsurf]
    end

    subgraph Node["Node.js process: slm-mesh"]
        MCP[MCP Server<br/>8 tools, stdio]
        CLI[CLI<br/>Commander.js]
        BR[Broker<br/>HTTP + UDS + WS + mDNS]
    end

    subgraph Local[Local Resources]
        DB[(SQLite WAL<br/>peers / messages /<br/>state / locks / events)]
        UDS[Unix Domain Socket<br/>push channel]
    end

    subgraph Net[Network]
        WS[WebSocket<br/>remote peers]
        BN[mDNS / Bonjour<br/>peer discovery]
    end

    subgraph Ext[Extensions]
        BA[BackendAdapter<br/>SQLite / Redis / ...]
        MB[MemoryBridge<br/>SuperLocalMemory]
    end

    CC --> MCP
    CU --> MCP
    AI2 --> CLI
    MCP --> BR
    CLI --> BR
    BR <--> DB
    BR <--> UDS
    BR <--> WS
    BR <--> BN
    BR -.uses.-> BA
    BR -.uses.-> MB
```

The three internal components are:

| Component | Entry Point | Role |
|-----------|-------------|------|
| Broker | `src/broker/broker.ts` (compiled via `tsup` entry `broker`) | Local HTTP + UDS + WebSocket server that owns the SQLite database, performs peer registration, and routes messages, state, locks, and events. Source: [tsup.config.ts:1-15](), [src/config.ts:1-20](). |
| MCP Server | `src/mcp/server.ts` | Stdio-based MCP server that exposes 8 tools to AI agents and forwards calls to the broker over HTTP. Source: [src/mcp/server.ts:1-40](), [README.md:30-80](). |
| CLI | `src/cli/cli.ts` | Commander.js-based user interface for `start`, `stop`, `status`, `peers`, `send`, `broadcast`, `state`, `lock`, `events`, `clean`, and `version`. Source: [src/cli/cli.ts:1-40](), [src/cli/format.ts:1-30](). |

Mode selection happens in `src/index.ts`, which inspects `process.argv` to decide whether to launch the CLI or the MCP server when the package binary is executed directly. Source: [src/index.ts:1-40]().

## Core Data Model and Communication Primitives

The shared domain model is defined in [src/types.ts:1-50](). Branded ID types (`PeerId`, `MessageId`, `EventId`) and a small set of enums (`PeerStatus`, `MessageType`, `AgentType`, `PeerScope`, `LockAction`, `StateAction`, `EventAction`) keep the protocol explicit. The persistent schema lives in [src/db/schema.ts:1-30](), which creates tables for `schema_version`, `peers`, and `messages` (with matching `CHECK` constraints on `agent_type` and `status`).

The mesh supports six communication primitives, as documented in the README feature table (Source: [README.md:10-30]()):

1. **Peer Discovery** — automatic registration and heartbeat; CLI shows `peers` with pid, agent type, git branch, and project path. Source: [src/cli/format.ts:1-20]().
2. **Direct Messaging** — structured messages with delivery/read tracking stored in the `messages` table. Source: [src/db/schema.ts:1-30]().
3. **Broadcast** — one-to-all messages with `to_peer = NULL` semantics.
4. **Shared State** — namespaced key-value entries for cross-peer scratchpads.
5. **File Coordination** — advisory file locks with auto-expiry.
6. **Event Bus** — pub/sub for `peer_joined`, `peer_left`, `state_changed`, `file_locked`, `file_unlocked`, and custom events.

Two extension contracts are defined as TypeScript interfaces: [src/adapters/backend.ts:1-50]() (storage backends such as Redis or PostgreSQL) and [src/adapters/memory-bridge.ts:1-30]() (integration with external memory systems like SuperLocalMemory).

## Process Architecture, Roles, and Lifecycle

The build produces two ESM bundles (`index` and `broker`) targeting Node.js 20, with declarations and source maps. Source: [tsup.config.ts:1-15](), [package.json:30-60]().

Since v1.3.x the broker can run in three modes, controlled by `SLM_MESH_ROLE` (Source: [CHANGELOG.md:1-40]()):

- `broker` — hub machine: spawns and owns the local broker.
- `client` — peer machine: connects to a remote broker, never spawns one.
- `auto` (default) — inferred from `SLM_MESH_HOST`: `localhost` → `broker`, remote IP → `client`.

A separate `SLM_MESH_IDLE_TIMEOUT` (default 60s) lets a hub machine stay alive between sparse peer connections by setting it to `0` to disable idle shutdown. The broker auto-starts on first use and auto-stops when no peers remain. Source: [CHANGELOG.md:1-30](), [README.md:30-50]().

Real-time push is delivered over Unix Domain Sockets (sub-100ms), with a WebSocket path for cross-machine peers. The v1.3.3 fix routes remote peers via WebSocket first and only attempts UDS for local peers, avoiding futile socket dials. Source: [CHANGELOG.md:1-10](), [src/mcp/server.ts:1-30]().

## Configuration and Security Model

Configuration is centralized in `src/config.ts` (re-exported as `createConfig`, `MeshConfig`, `VERSION`, `PRODUCT_NAME`, `BRANDING`). Source: [src/config.ts:1-20](), [src/index.ts:1-15](). The CLI injects a bearer token from `~/.slm-mesh/broker.token` into every non-exempt request, where `/health` is the only auth-exempt path. Source: [src/cli/cli.ts:1-40]().

The security posture (Source: [SECURITY.md:1-30]()) is:

- Localhost-only binding (cannot bind to `0.0.0.0`).
- Bearer token authentication on all API endpoints except `/health`.
- No shell injection: `execFileSync` is used with argument arrays.
- Input validation: UUID peer IDs, payload size limits, and rate limiting.
- File permissions of `0o600` for sensitive files and `0o700` for directories.
- Zero external network calls; no telemetry.

A thin Python client (`python/src/slm_mesh/client.py`) wraps the broker HTTP API using only the standard library, allowing non-Node agents to participate. Source: [python/src/slm_mesh/client.py:1-40]().

## Development and Quality Standards

The contributing guide mandates TypeScript strict mode, 100% line coverage, files under 800 lines, functions under 50 lines, and zero `any` types. The project runs 480 tests via Vitest, with separate `typecheck`, `build`, `test:watch`, and `test:coverage` scripts. Source: [CONTRIBUTING.md:1-30](), [package.json:15-30](). The intentional 8-tool MCP surface is a deliberate constraint to limit agent context consumption; new tools are explicitly excluded from contributions. Source: [CONTRIBUTING.md:20-30]().

## See Also

- MCP Server and Tool Surface
- Broker Internals and Routing
- Configuration and Environment Variables
- Security Model
- Python Client
- Backend Adapters
- Memory Bridge

---

<a id='page-2'></a>

## MCP Tools, Claude Code Skills, CLI, and Python Client

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [Configuration, Security, Adapters, and Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/mcp/server.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/server.ts)
- [src/mcp/peer-listener.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/peer-listener.ts)
- [src/mcp/broker-client.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/broker-client.ts)
- [src/mcp/agent-detect.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/agent-detect.ts)
- [src/cli/cli.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/cli.ts)
- [src/cli/format.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/format.ts)
- [src/index.ts](https://github.com/qualixar/slm-mesh/blob/main/src/index.ts)
- [src/types.ts](https://github.com/qualixar/slm-mesh/blob/main/src/types.ts)
- [python/src/slm_mesh/client.py](https://github.com/qualixar/slm-mesh/blob/main/python/src/slm_mesh/client.py)
- [integrations/cursor/README.md](https://github.com/qualixar/slm-mesh/blob/main/integrations/cursor/README.md)
- [python/README.md](https://github.com/qualixar/slm-mesh/blob/main/python/README.md)
- [README.md](https://github.com/qualixar/slm-mesh/blob/main/README.md)
</details>

# MCP Tools, Claude Code Skills, CLI, and Python Client

SLM Mesh exposes a single mesh networking capability through three coordinated surfaces: an **8-tool MCP surface** for AI coding agents, a **terminal CLI** for humans and scripts, and a **Python client** for Python-based workflows. On top of the MCP surface, **Claude Code Skills** (`/mesh-*` slash commands) provide one-keystroke shortcuts. All three surfaces talk to the same local broker via HTTP with bearer-token authentication. Source: [README.md](https://github.com/qualixar/slm-mesh/blob/main/README.md).

## Entry Point and Mode Detection

A single executable, `slm-mesh`, decides at runtime whether to act as a CLI or as an MCP server. Source: [src/index.ts:16-18](). The detection rule is simple: if any argv token after the script name matches a known command (`start`, `stop`, `status`, `peers`, `send`, `broadcast`, `state`, `lock`, `events`, `version`, `clean`, `help`, `--help`, `-h`, `--version`, `-V`, `--json`), CLI mode is launched via Commander; otherwise MCP server mode is launched over stdio for Claude Code, Cursor, and other MCP hosts. Source: [src/index.ts:9-39](). This dual-mode design lets one binary serve both interactive and agent-driven workflows.

## The 8 MCP Tools

When launched as an MCP server, the binary registers exactly eight tools, defined in [src/mcp/server.ts](). According to the project README, the surface is intentionally fixed because each tool consumes agent context — the contributing guide explicitly rejects "new MCP tools" as a contribution category. Source: [CONTRIBUTING.md](https://github.com/qualixar/slm-mesh/blob/main/CONTRIBUTING.md).

| Tool | Purpose |
|------|---------|
| `mesh_peers` | Discover active sessions (scoped to machine, directory, or repo) |
| `mesh_summary` | Publish a description of what this agent is working on |
| `mesh_send` | Send a message to a specific peer or broadcast (`to: "all"`) |
| `mesh_inbox` | Read messages, optionally filtering to unread only |
| `mesh_state` | Read or write shared key-value state (`get`, `set`, `list`, `delete`) |
| `mesh_lock` | Advisory file locking (`lock`, `unlock`, `query`) with auto-expire |
| `mesh_events` | Read or subscribe to `peer_joined`, `state_changed`, etc. |
| `mesh_status` | Broker health, peer count, message statistics |

MCP tool calls are translated into HTTP POSTs to the broker through [src/mcp/broker-client.ts](), which caches the bearer token read from disk and exempts only `/health` from auth. Source: [src/mcp/broker-client.ts:9-50](). A long-running [PeerListener](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/peer-listener.ts) pushes inbound messages into the agent's notification stream so the model can react promptly. Source: [src/mcp/server.ts:1-30]().

## Claude Code Skills (Slash Commands)

The v1.1.0 release introduced Claude Code Skills — slash commands that wrap the MCP tools for one-keystroke use inside Claude Code. They are documented in the community release notes and re-export the same backing operations:

- `/mesh-peers` — wraps `mesh_peers`
- `/mesh-send <message>` — wraps `mesh_send` (or broadcast)
- `/mesh-lock <file>` — wraps `mesh_lock` (lock, unlock, or query)
- `/mesh-status` — wraps `mesh_status`
- `/mesh-sync` — a composite dashboard combining `mesh_peers`, `mesh_inbox`, and `mesh_status`

These skills follow the MCP-first principle: they are thin command aliases, not new wire-protocol features. Companion integration guides ship a `.cursorrules` file for Cursor and a `.windsurfrules` file for Windsurf so non-Claude agents also learn to call the same tools proactively. Source: [integrations/cursor/README.md:1-30]().

## Command-Line Interface

The CLI is a thin operator over the same broker HTTP API. Source: [src/cli/cli.ts:1-20](). It authenticates with the bearer token from `~/.slm-mesh/broker.token`, exempting only `/health`, and renders responses as fixed-width tables via [src/cli/format.ts](). Output formatters exist for peers, messages, locks, events, and broker status, each handling empty results gracefully (`"No messages"`, `"No active locks"`). Source: [src/cli/format.ts:1-50]().

The full command set mirrors the broker endpoints — `start`, `stop`, `status`, `peers`, `send`, `broadcast`, `state`, `lock`, `events`, `version`, `clean` — and supports `--json` output for scripting. A `readPidFile`/`isProcessAlive` check ensures the CLI does not double-start the broker; port discovery is delegated to `src/broker/port.ts`. Source: [src/index.ts:9-13](), [src/cli/cli.ts:1-30]().

## Python Client

A zero-dependency Python SDK ships under `python/`, exposing the broker over stdlib `urllib`. Source: [python/README.md:1-30](). The client, defined in [python/src/slm_mesh/client.py](), mirrors the CLI surface one-to-one:

```python
from slm_mesh import SLMMeshClient

client = SLMMeshClient()  # connects to localhost:7899
print(client.health())
client.send(from_peer="agent-a", to_peer="agent-b", payload="hello")
client.state_set(key="current_file", value="main.py", peer_id="agent-a")
lock = client.lock(file_path="src/app.ts", peer_id="agent-a")
events = client.events(types=["message", "lock"], limit=10)
```

The client raises a typed `SLMMeshError(message, status_code, response)` on broker failures and reads the bearer token from `SLM_MESH_DATA_DIR/broker.token`, falling back to `~/.slm-mesh/`. Source: [python/src/slm_mesh/client.py:1-60](). It targets Python 3.10+ and ships with no third-party packages.

## Data Flow

```mermaid
flowchart LR
    A[AI Agent<br/>Claude Code / Cursor] -->|MCP stdio| B[slm-mesh MCP Server<br/>src/mcp/server.ts]
    H[Human / Script] -->|CLI| C[slm-mesh CLI<br/>src/cli/cli.ts]
    P[Python Program] -->|HTTP| D[SLMMeshClient<br/>python/src/slm_mesh/client.py]
    B -->|HTTP + Bearer| E[Broker]
    C -->|HTTP + Bearer| E
    D -->|HTTP + Bearer| E
    E -->|SQLite| F[(peers, messages,<br/>locks, events)]
```

All three surfaces converge on the same broker, which persists state via the SQLite adapter defined in [src/adapters/sqlite-backend.ts]().

## Common Failure Modes

- **Broker not running** — CLI/MCP calls fail with a connection error. Start the broker first with `npx slm-mesh start` or let the MCP server auto-spawn it via `ensureBroker`. Source: [src/mcp/server.ts:1-15]().
- **Missing bearer token** — requests to non-exempt paths are rejected; `/health` always works. Source: [src/mcp/broker-client.ts:9-15]().
- **Stale peers** — entries past the heartbeat threshold are marked `stale` or `dead` by the SQLite backend. Source: [src/adapters/sqlite-backend.ts:1-80]().

## See Also

- [Architecture](architecture.md)
- [Configuration](configuration.md)
- [Security Model](security.md)
- [Troubleshooting](troubleshooting.md)
- [Python Client Guide](python-client.md)

---

<a id='page-3'></a>

## Multi-Machine Setup, WebSocket Transport, and Agent Integrations

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [Configuration, Security, Adapters, and Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/qualixar/slm-mesh/blob/main/README.md)
- [CHANGELOG.md](https://github.com/qualixar/slm-mesh/blob/main/CHANGELOG.md)
- [src/broker/push/ws-server.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/push/ws-server.ts)
- [src/mcp/peer-listener.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/peer-listener.ts)
- [src/mcp/server.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/server.ts)
- [src/types.ts](https://github.com/qualixar/slm-mesh/blob/main/src/types.ts)
- [package.json](https://github.com/qualixar/slm-mesh/blob/main/package.json)
- [skills/mesh-send.md](https://github.com/qualixar/slm-mesh/blob/main/skills/mesh-send.md)

</details>

# Multi-Machine Setup, WebSocket Transport, and Agent Integrations

## Overview

SLM Mesh began as a single-machine peer-to-peer coordination layer for AI coding agents, with the broker using Unix Domain Sockets (UDS) for sub-100ms local push delivery. The v1.1.0 release — **"Skills, Integrations & Demo"** — extended that model across machines by introducing a WebSocket push transport, mDNS-based broker discovery, and shared-secret authentication ([CHANGELOG.md](CHANGELOG.md)).

This page documents the three pillars of that cross-machine capability: the **multi-machine topology** (broker/client role split), the **WebSocket transport** that replaces UDS for remote peers, and the **agent integrations** that wire popular MCP clients (Claude Code, Cursor, Windsurf, VS Code) and slash-command skills into the mesh.

## Multi-Machine Architecture

Each machine in the mesh plays exactly one of two roles, selected at startup. A hub machine runs the broker and listens for inbound WebSocket connections; a peer machine runs only an MCP client that dials a remote broker. The `SLM_MESH_ROLE` environment variable (added in v1.3.1) makes the role explicit (`broker`, `client`, or `auto`) ([CHANGELOG.md](CHANGELOG.md)).

The `Bonjour` library (`bonjour` ^3.5.1 in [package.json](package.json)) powers mDNS auto-discovery so that brokers advertise themselves on the LAN and remote clients find them without hard-coding IPs ([package.json](package.json)). The `AgentType` enumeration in the core type system identifies which MCP client the peer represents — values include `claude-code`, `cursor`, `aider`, `codex`, `windsurf`, `vscode`, and `unknown` ([src/types.ts](src/types.ts)).

```mermaid
flowchart LR
    subgraph M4["Hub Machine (role=broker)"]
        B[Broker HTTP + WS :7900]
        UDS1[UDS peer]
    end
    subgraph M5["Peer Machine (role=client)"]
        C1[MCP Client<br/>Cursor]
        C2[MCP Client<br/>Claude Code]
    end
    C1 -- "WS + Bearer token" --> B
    C2 -- "WS + Bearer token" --> B
    UDS1 -- "UDS push" --> B
    B -. "mDNS advertisement" .- LAN((LAN))
    LAN -. "mDNS browse" .-> C1
```

A typical two-machine setup binds the broker with `SLM_MESH_HOST=0.0.0.0` and a matching `SLM_MESH_SHARED_SECRET`, then points the client machine at the broker's IP. Both sides must agree on the secret; the WebSocket server refuses connections without a valid bearer token ([README.md](README.md)).

## WebSocket Transport

The remote push path is implemented by two cooperating components defined in the broker and MCP layers.

**Broker-side WebSocket server.** [`WsServer`](src/broker/push/ws-server.ts) is an authenticated WebSocket server that runs alongside the HTTP broker. It accepts upgrades on a configurable port (default `7900`), validates a `Bearer` token against a set of allowed tokens, and maintains a `peerId → clientId` map so that `sendToPeer(peerId, data)` can deliver notifications to a specific remote peer ([src/broker/push/ws-server.ts](src/broker/push/ws-server.ts)). The `hasRemotePeer(peerId)` predicate is the routing key: the broker uses it to decide whether to attempt a UDS push or a WebSocket push, fixing the bi-directional cross-machine routing bug fixed in v1.3.3 ([CHANGELOG.md](CHANGELOG.md)).

**Client-side push client.** Each MCP server process owns a [`WsPushClient`](src/mcp/peer-listener.ts) that dials the remote broker, performs the hello handshake, and reconnects with exponential backoff on disconnect. The same [`PeerListener`](src/mcp/peer-listener.ts) abstraction exposes both UDS (local broker) and WebSocket (remote broker) push channels through a single notification callback, so the MCP tool handlers don't need to know which transport is in use ([src/mcp/peer-listener.ts](src/mcp/peer-listener.ts)).

The two transports form a **WS-first, UDS-fallback** routing rule: local peers on the same machine are reached over UDS for minimal latency; remote peers are reached over WebSocket with shared-secret authentication ([CHANGELOG.md](CHANGELOG.md)).

## Agent Integrations

### MCP Server Configuration

The MCP server ([src/mcp/server.ts](src/mcp/server.ts)) exposes eight tools — `mesh_peers`, `mesh_send`, `mesh_lock`, `mesh_summary`, `mesh_state`, `mesh_events`, plus helpers — over the Model Context Protocol. It auto-starts the broker on first use, detects the calling agent by inspecting the process tree, and registers a [`PeerListener`](src/mcp/peer-listener.ts) so pushed notifications arrive in real time ([src/mcp/server.ts](src/mcp/server.ts)).

Setup snippets from the README cover Claude Code (`claude mcp add …`), Cursor (`.cursor/mcp.json`), and any generic MCP client that accepts a `command` + `args` pair ([README.md](README.md)). Because transport is automatic, the same MCP configuration works whether the broker is local (UDS) or on another machine (WebSocket).

### Slash-Command Skills

The v1.1.0 release added five Claude Code skills — `/mesh-peers`, `/mesh-send`, `/mesh-lock`, `/mesh-status`, `/mesh-sync` — that wrap the MCP tools in slash commands so users can coordinate without writing tool calls by hand. The `/mesh-send` skill, for example, calls `mesh_peers` to confirm listeners, then broadcasts or direct-sends via `mesh_send` and reports the returned message IDs ([skills/mesh-send.md](skills/mesh-send.md)). Cursor and Windsurf receive equivalent integration guides via `.cursorrules` and `.windsurfrules` (CHANGELOG v1.1.0).

## Configuration Reference

The cross-machine features are all environment-variable driven. The table below lists the variables documented in the README and changelog that govern transport, discovery, authentication, and role selection.

| Variable | Default | Purpose |
|----------|---------|---------|
| `SLM_MESH_HOST` | `127.0.0.1` | Broker bind address; use `0.0.0.0` for remote access. |
| `SLM_MESH_WS_PORT` | `7900` | WebSocket server port for remote peer push. |
| `SLM_MESH_SHARED_SECRET` | (auto-generated) | Bearer token required on every WS upgrade. |
| `SLM_MESH_DISCOVERY` | `true` | Enables mDNS advertise/browse on LAN. |
| `SLM_MESH_ROLE` | `auto` | Explicit `broker`, `client`, or auto-detect from `HOST`. |
| `SLM_MESH_IDLE_TIMEOUT` | `60000` | Broker idle shutdown in ms; `0` disables. |

## Common Failure Modes

- **Authentication mismatch.** If two machines have different `SLM_MESH_SHARED_SECRET` values, the WebSocket upgrade is rejected silently; symptoms are peers that appear via mDNS but never receive messages.
- **Firewall on port 7900.** mDNS discovery succeeds, but the WebSocket dial times out. Verify the port is reachable between machines ([README.md](README.md)).
- **Routing to the wrong transport.** Fixed in v1.3.3 — the broker must call `hasRemotePeer(peerId)` before attempting a UDS push, otherwise remote peers trigger futile local socket connections ([CHANGELOG.md](CHANGELOG.md)).
- **Stale peer entries.** Peers that crash without a clean disconnect remain visible until the broker's stale-cleanup sweep runs; the `SLM_MESH_IDLE_TIMEOUT` controls shutdown, while the `BackendAdapter.cleanStalePeers` sweep removes zombies ([src/adapters/backend.ts](src/adapters/backend.ts), [CHANGELOG.md](CHANGELOG.md)).

## See Also

- [Architecture Overview](architecture.md) — Broker, MCP server, and CLI component model
- [API Reference](api-reference.md) — All 8 MCP tools and 12 broker endpoints
- [Configuration](configuration.md) — Full environment variable reference
- [Security Model](security.md) — Bearer tokens, mDNS scope, threat model

---

<a id='page-4'></a>

## Configuration, Security, Adapters, and Operations

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [Multi-Machine Setup, WebSocket Transport, and Agent Integrations](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/config.ts](https://github.com/qualixar/slm-mesh/blob/main/src/config.ts)
- [src/broker/port.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/port.ts)
- [src/broker/pid.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/pid.ts)
- [src/broker/token.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/token.ts)
- [src/broker/idle.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/idle.ts)
- [src/broker/cleanup.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/cleanup.ts)
- [src/adapters/backend.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/backend.ts)
- [src/adapters/memory-bridge.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/memory-bridge.ts)
- [src/types.ts](https://github.com/qualixar/slm-mesh/blob/main/src/types.ts)
- [src/broker/broker-entry.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/broker-entry.ts)
- [src/cli/cli.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/cli.ts)
- [SECURITY.md](https://github.com/qualixar/slm-mesh/blob/main/SECURITY.md)
- [package.json](https://github.com/qualixar/slm-mesh/blob/main/package.json)
- [CHANGELOG.md](https://github.com/qualixar/slm-mesh/blob/main/CHANGELOG.md)
</details>

# Configuration, Security, Adapters, and Operations

SLM Mesh is a peer-to-peer coordination layer for AI coding agents that runs as three cooperating components: a CLI, an MCP server, and a broker daemon. This page covers the cross-cutting concerns that tie those components together: how the runtime is configured, how it stays secure on a single host, how its storage and memory layers are abstracted through adapters, and how the broker process is managed from start to clean shutdown.

## Configuration

The mesh reads its configuration from a single `createConfig()` factory exported from [src/config.ts](https://github.com/qualixar/slm-mesh/blob/main/src/config.ts). The factory is called by every component that needs runtime paths and ports (broker entry, CLI, MCP server), which guarantees that all processes agree on filesystem locations and the listening port. Defaults are environment-aware: data lives under `~/.slm-mesh/` and the HTTP broker listens on `127.0.0.1` only.

The CHANGELOG ([CHANGELOG.md](https://github.com/qualixar/slm-mesh/blob/main/CHANGELOG.md)) documents the most important environment variables introduced after 1.3.0:

| Variable | Default | Purpose |
|----------|---------|---------|
| `SLM_MESH_IDLE_TIMEOUT` | `60000` (ms) | How long the broker may sit with zero peers before shutting down. Set to `0` to disable idle shutdown entirely — useful for hub machines expecting delayed peer connections. |
| `SLM_MESH_ROLE` | `auto` | Forces the machine to behave as a `broker` (spawns local broker), `client` (connects to remote broker, never spawns), or `auto` (infers from `SLM_MESH_HOST`: localhost → broker, remote IP → client). |
| `SLM_MESH_HOST` | `127.0.0.1` | Broker host the client connects to. When set to a non-loopback address, the role is auto-set to `client`. |

A new `role` field was also added to `MeshConfig` so downstream code can branch on broker vs. client behavior without re-parsing environment variables. Source: [CHANGELOG.md:18-24]()

The CLI discovers the running broker's port through `discoverPort()` in [src/broker/port.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/port.ts) and reads the bearer token from disk via [src/broker/token.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/token.ts). The `buildAuthHeaders()` helper in [src/cli/cli.ts](https://github.com/qualixar/slm-mesh/blob/main/src/cli/cli.ts) automatically attaches `Authorization: Bearer <token>` to every request except `/health`, which is explicitly exempt for liveness probes.

## Security

SLM Mesh is explicitly designed for single-machine, single-user use, and the threat model is enforced at every layer. The full policy is described in [SECURITY.md](https://github.com/qualixar/slm-mesh/blob/main/SECURITY.md), and the key guarantees are:

- **Localhost-only binding** — the broker HTTP server cannot bind to `0.0.0.0`, preventing accidental LAN exposure.
- **Bearer token auth** — every non-health API endpoint requires a token that is generated on broker startup and persisted to a file with `0o600` permissions. Source: [src/cli/cli.ts:16-31]()
- **Input validation** — peer IDs are validated as UUIDs, payloads have size limits, and the server applies rate limiting before reaching the storage layer.
- **No shell injection** — subprocess spawning uses `execFileSync` with argument arrays, never string interpolation.
- **File permissions** — sensitive files are written `0o600`; the data directory itself is `0o700`.
- **Zero telemetry** — no outbound network calls; no usage data leaves the host.

The MCP server in [src/mcp/server.ts](https://github.com/qualixar/slm-mesh/blob/main/src/mcp/server.ts) wraps these guarantees by routing all tool calls through the authenticated broker-client, so even when a hostile agent connects via MCP it cannot bypass the token check or the localhost restriction.

## Adapters

The mesh keeps its storage and memory layers behind narrow interfaces so that future contributors can swap implementations (Redis, PostgreSQL, or custom stores) without touching the broker. Two contracts are defined:

- **`BackendAdapter`** — see [src/adapters/backend.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/backend.ts). It covers the full domain: peer registration and heartbeat updates, message send/get/delivered/read, shared state get/set/list/delete, advisory file lock acquire/release/query, and event recording. The current production adapter is SQLite, but the interface is the only thing callers depend on.
- **`MemoryBridge`** — see [src/adapters/memory-bridge.ts](https://github.com/qualixar/slm-mesh/blob/main/src/adapters/memory-bridge.ts). It is an optional integration point for the SuperLocalMemory system: hooks fire on new messages, state changes, and system events, and a `recall(query)` method returns relevant context strings. `isAvailable()` lets the broker skip the bridge entirely on hosts where the memory system is not installed.

The domain types referenced by both interfaces are centralized in [src/types.ts](https://github.com/qualixar/slm-mesh/blob/main/src/types.ts) (`Peer`, `Message`, `Lock`, `StateEntry`, `MeshEvent`), which keeps the adapter surface and the SQLite schema in [src/db/schema.ts](https://github.com/qualixar/slm-mesh/blob/main/src/db/schema.ts) in lock-step.

```mermaid
flowchart LR
  Agent[AI Agent / MCP Client] -->|MCP tool call| MCP[src/mcp/server.ts]
  CLI[src/cli/cli.ts] -->|HTTP + Bearer| Broker
  MCP -->|HTTP + Bearer| Broker[Broker daemon]
  Broker --> Backend[BackendAdapter]
  Broker --> Memory[MemoryBridge<br/>optional]
  Backend --> SQLite[(SQLite WAL)]
  Memory --> SLM[SuperLocalMemory]
```

## Operations and Lifecycle

Operational behavior is split across four small modules that keep responsibilities tight:

- **[src/broker/broker-entry.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/broker-entry.ts)** — the daemon entry point. It builds a `Broker` from `createConfig()` and calls `start()`; any unhandled error is logged and the process exits with a non-zero code so a supervisor can restart it.
- **[src/broker/pid.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/pid.ts)** — reads the PID file and checks `isProcessAlive()` to decide whether to spawn a new broker or attach to the existing one. This is the basis of the auto-lifecycle promise in the README ("broker auto-starts on first use, auto-stops when no peers remain").
- **[src/broker/idle.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/idle.ts)** — implements the `SLM_MESH_IDLE_TIMEOUT` behavior. A timer watches the peer count; once it reaches zero the broker waits the configured grace period and then shuts down. With `0` the timer is disabled, which is the recommended setting for persistent hub machines.
- **[src/broker/cleanup.ts](https://github.com/qualixar/slm-mesh/blob/main/src/broker/cleanup.ts)** — performs housekeeping: marks peers `stale` past the heartbeat threshold, removes `dead` peers, and expires advisory file locks. A v1.3.3 fix recorded in the CHANGELOG corrected a WebSocket peer routing bug where remote peers connected via WS still triggered futile UDS socket connections — the broker now checks `hasRemotePeer()` and prefers WS routing with UDS fallback. Source: [CHANGELOG.md:3-8]()

A typical operational flow therefore looks like: CLI / MCP call → `ensureBroker` checks the PID file → spawn or attach → broker authenticates the request via the token file → adapter writes through to SQLite → idle timer re-evaluates peer count → on `0` peers (and `timeout > 0`) the broker exits and the PID/token files are removed on next `clean`.

The release also ships Claude Code skill commands (`/mesh-peers`, `/mesh-send`, `/mesh-lock`, `/mesh-status`, `/mesh-sync`) and integration guides for Cursor, Windsurf, and VS Code — these are mentioned in the v1.1.0 release notes and consume the same broker API described above.

## See Also

- [Architecture and Components](architecture.md) — high-level system diagram and component responsibilities
- [MCP Tools Reference](mcp-tools.md) — the 8-tool surface exposed by `src/mcp/server.ts`
- [CLI Reference](cli-reference.md) — full command list built on `commander` in `src/cli/cli.ts`
- [Security Model](security.md) — extended threat model and architectural decisions (linked from [SECURITY.md](https://github.com/qualixar/slm-mesh/blob/main/SECURITY.md))

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: qualixar/slm-mesh

Summary: Found 7 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Configuration risk - Configuration risk requires verification.

## 1. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/qualixar/slm-mesh

## 2. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/qualixar/slm-mesh

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/qualixar/slm-mesh

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/qualixar/slm-mesh

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/qualixar/slm-mesh

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/qualixar/slm-mesh

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/qualixar/slm-mesh

<!-- canonical_name: qualixar/slm-mesh; human_manual_source: deepwiki_human_wiki -->
