npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

paseo-x-comms-mcp

v0.3.0

Published

Cross-daemon agent conversation over Paseo Relay: an MCP server that lets agents on one paseo daemon talk to agents on another (relay offer or direct host).

Readme

paseo-x-comms

This repo closely follows the latest beta versions of paseo in order to benefit from new features in the plugin system. Expect breaking changes between versions.

paseo is an agent orchestrator: AI coding agents run on paseo daemons, each managing its own workspaces, tools, and permissions.

paseo-x-comms is an MCP server that lets agents on one paseo daemon (remote or local) talk to agents on another paseo daemon, even across hosts, through the daemon's relay (WebSocket + E2EE) or directly over TCP.

How it works

pi / opencode --MCP stdio--> paseo-x-comms (our server)
                                   │  execFile("paseo", [cmd, "--host", <target>, "--json", …])
                                   ▼
                             paseo CLI --relay (E2EE) or direct TCP--> daemon
  • The MCP server is just a client of daemons: it never runs a daemon, and it only talks to agents; each agent does its own work on its own local daemon.
  • --host is an opaque string: paseo classifies it automatically: a value containing #offer= is a relay connection (E2EE); anything else is a direct host target. Our registry maps a short name to that string.
  • Every MCP response and every tool result flows through the official SDK, so framing, JSON-RPC, schema validation, and cancellation are protocol-correct by construction.
  • The server also announces its behavioral contract to clients via the MCP instructions field (initialize result), so every model using it gets the envelope format and behavior notes below automatically.

Install

As a standalone MCP server

npm install -g @xpufx/paseo-x-comms

Requires the paseo CLI on PATH. Node ≥ 18.

As a paseo plugin (recommended)

This repo also ships a paseo plugin that embeds the MCP server and adds the x-comms UI (composer pill, agent panel, timeline rendering, and the "Inject MCP into context" system-prompt toggle). The plugin is at the repo root, so install without --path:

paseo plugin add <owner>/paseo-x-comms

paseo runs a single npm install at the repo root, which pulls both the plugin dependencies and the embedded server's dependencies (@modelcontextprotocol/sdk, zod) into one node_modules. The server is spawned from ./mcp and resolves its deps from that shared tree; no separate server install or PATH entry is required.

Quick start

  1. On the target host, get its pairing offer:

    paseo daemon pair --json
    # → { "relayEnabled": true, "url": "https://app.paseo.sh/#offer=<b64>", ... }

    (Or, if that daemon is directly reachable over TCP, e.g. LAN, Tailscale, VPN, use its address, e.g. 10.0.0.5:6767, instead of an offer.)

  2. On this host, register the peer:

    In the plugin UI (Main surface) under Add peer, paste the endpoint. It probes the host over the wire, fetches its authoritative serverId and hostname, establishes a reciprocal handshake so both peers pair automatically, and saves:

    ~/.paseo/paseo-x-comms/registry.json:

    {
      "srv_019cfa5d_...": {
        "serverId": "srv_019cfa5d_...",
        "label": "hsi",
        "hostname": "hsi-workstation",
        "endpoint": "https://app.paseo.sh/#offer=<b64>",
        "enabled": true,
        "reachable": true,
        "lastSeenAt": "2026-09-03T18:00:00.000Z",
        "error": null
      }
    }

    The registry is credentials; write it through the UI or via MCP tools, and do not paste offers into agent contexts.

  3. Discover and talk:

    x_comms_list_agents(serverId="srv_019cfa5d_...")
    x_comms_send(serverId="srv_019cfa5d_...", agentId="…", prompt="…")

Tools

Tool names are x_comms_*. When a client (pi, opencode) loads this MCP server, it may prefix tool names with its own server registration (for example paseo_2d_cross_2d_daemon_2d_comms_... in pi). Match the tool names the client actually exposes in its tool list; the documented names below are the server's own, without any client prefix.

| Tool | Purpose | |------|---------| | x_comms_list_peers | List registered peer serverIds | | x_comms_add_peer | Register a peer: pairing link or direct host | | x_comms_remove_peer | Forget a registered peer by serverId | | x_comms_list_agents | List agents on a peer (serverId) | | x_comms_inspect | Inspect an agent on a peer (serverId) | | x_comms_send | Send a message/task to an agent on a peer (gated by enabled & reachable) | | x_comms_logs | View an agent's activity/timeline on a peer (serverId) | | x_comms_wait | Block until an agent on a peer is idle; returns permission if blocked | | x_comms_list_permissions | List pending permission requests on a peer (serverId) | | x_comms_allow_permission | Allow an agent's permission request (reqId or all) | | x_comms_deny_permission | Deny an agent's permission request (reqId or all, optional message/interrupt) |

Message envelope

send prepends a structured sender-meta envelope, one line, JSON:

[x-comms] {"xComms":{"version":4,"type":"x-comms.incoming_message","sender":{"agentId":"...","agentName":"...","host":"...","serverId":"srv_...","cwd":"..."},"target":{"serverId":"srv_...","agentId":"..."},"sentAt":"..."}}
  • sender: agentId, agentName, host, serverId, cwd: who is talking and from where. Sources: agentId/cwd from the environment (PASEO_AGENT_ID / PASEO_AGENT_CWD), host/serverId from paseo daemon status --json, agentName from paseo inspect <agentId> --json.
  • target: peer serverId + recipient agentId.
  • sentAt: ISO timestamp.
  • The prompt text itself stays prose: the meta is for machines, the prompt is for humans.

Recipients may parse the envelope and reply to sender.agentId on the sender's daemon (sender.serverId). The envelope is versioned (version: 4), so the format can evolve without breaking older readers.

For best results, run the same version on each daemon: the envelope format, tool names, and parameters evolve between releases, so a mismatched pair still works, but the older side answers in its older format.

Behavior notes

  • Send is preemptive. A message to a busy agent replaces its current run (paseo's replaceRunning: true in startAgentRun, see packages/server/src/server/agent/agent-prompt.ts) on both sides. If a target may be busy, wait until it is idle before messaging it, or expect the preemption.
  • Permission loop. An agent may block on a permission prompt; send returns permission, wait surfaces it, list_permissions shows details, and allow_permission/deny_permission answer. The loop: sendwait → on permission: list_permissions + allow/deny → wait … → idle.

Host forms

The registry value is passed to paseo as an opaque --host string; paseo classifies it:

  • https://app.paseo.sh/#offer=<b64> : relay connection (E2EE)
  • host:port, tcp://host:port?ssl=true&password=secret, unix:///path, IPC paths, bare port: direct connection to a reachable daemon

Only these canonical forms are accepted. Anything else (e.g. a raw base64 payload) is passed through untouched and paseo fails visibly on it. (Note: paseo's own --host help text lists only host:port and tcp://…; bare ports and unix:// also work but are not documented in the CLI help.)

Security

The registry (default ~/.paseo/paseo-x-comms/registry.json) holds live pairing offers (serverId, daemon public keys, relay endpoints): it is credentials. Never publish it. Configure it as a plain JSON file yourself (see the example); do not paste offers into agent contexts and do not share the file.

Configuration

| Env var | Default | Purpose | |---------|---------|---------| | PASEO_X_COMMS_REMOTES | ~/.paseo/paseo-x-comms/registry.json | registry file path | | PASEO_X_COMMS_PASEO | paseo | paseo binary | | PASEO_X_COMMS_TIMEOUT_MS | 120000 | per paseo call timeout |

Registering with clients

Example configs live in this repo: mcp-config.example.json (pi-style registration) and paseo-x-comms.example.json (registry format: never commit your real registry).

pi (~/.config/mcp/mcp.json): the stdio form supports env (pi needs MCP enabled for this to be picked up):

{
  "mcpServers": {
    "paseo-x-comms": {
      "command": "node",
      "args": ["/path/to/paseo-x-comms.mjs"],
      "type": "stdio",
      "env": { "PASEO_X_COMMS_REMOTES": "/path/to/paseo-x-comms.json" }
    }
  }
}

opencode (~/.config/opencode/opencode.jsonc): note the key is environment (per opencode's schema):

{
  "mcp": {
    "paseo-x-comms": {
      "type": "local",
      "command": ["node", "/path/to/paseo-x-comms.mjs"],
      "enabled": true,
      "environment": { "PASEO_X_COMMS_REMOTES": "/path/to/paseo-x-comms.json" }
    }
  }
}

Scope

Communication only. The toolset covers discovery (list_agents, inspect), messaging (send), listening (logs, wait), answering (allow_permission, deny_permission, list_permissions), and the daemon registry (list_daemons, add_daemon, remove_daemon). It deliberately does not operate resources on other daemons: no schedules, terminals, workspaces, or agent creation.

Development

npm install
npm test          # hermetic: fake paseo CLI + temp registry, no live daemons

License

Apache-2.0.