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

@agent-ops/grok-nats-channel

v0.8.0

Published

Synadia Agent Protocol for NATS channel for Grok. Exposes a Grok session as a discoverable, spec-compliant agent on NATS via an MCP server.

Readme

NATS Channel for Grok

Connect Grok to NATS messaging as a spec-compliant Synadia Agent Protocol for NATS agent.

The MCP server registers an agents micro service, exposes a prompt endpoint at agents.prompt.<machine>.<project>.<session>, a status endpoint at agents.status.<machine>.<project>.<session> (replies with the same payload as a heartbeat), publishes heartbeats at agents.hb.<machine>.<project>.<session> (the verb is the abbreviation hb), and bridges prompt requests into the Grok session. Harness identity (grok) lives in the service metadata (agent key), not in the subject. Replies stream back as typed JSON chunks ({"type":"response","data":"..."}) terminated by an empty headerless message - the protocol's uniform end-of-stream signal.

This is the Grok counterpart to the NATS Channel for Claude Code adapter in the Synadia Agents reference implementation.

Grok + sesh NATS

Use this adapter to make your Grok sessions first-class, discoverable agents (gr.<owner>.<name>) on any NATS mesh — including for sesh and other Synadia orchestration tools.

Typical flow with sesh:

  1. Place the adapter at ~/projects/grok-nats-channel (or your path).
  2. In a Grok TUI session: run /grok-nats-channel:launcher enable
  3. Then /grok-nats-channel:configure (pick NATS context or use demo; optionally set session name and permissions query for remote callers).
  4. Restart Grok — the MCP server starts and registers on NATS.
  5. In sesh (or nats micro ls): your gr agent appears. Route tasks to it; prompts arrive in Grok as:
    <channel source="nats" request_id="..." session="..." ts="...">
    ...
    </channel>
    Reply with the built-in reply(request_id, text, done) tool.
  6. (Future) When published under the @agent-ops npm scope as @agent-ops/grok-nats-channel, enable via bunx or Grok marketplace without a local clone.

See the Quick Setup below, the launcher + configure skills, and "Enabling in Grok" section for details. Heartbeats, discovery, attachments, and query-permission chunks are all supported per the v0.3 protocol.

Prerequisites

  • Bun - the MCP server runs on Bun. Install with curl -fsSL https://bun.sh/install | bash, and make sure bun is on your PATH.
  • NATS CLI - for managing contexts and testing.
  • A NATS server to connect to (local or remote) - the plugin defaults to demo.nats.io.

Quick Setup

1. Activate the grok-nats-channel in your Grok session.

The adapter is provided as a channel plugin for Grok. Enable it through your Grok environment's marketplace or channel launcher for the Synadia NATS Agent Protocol (the server entrypoint is server.ts / bun server.ts).

By default, the server connects to demo.nats.io (no credentials required) and registers a micro service on agents.prompt.<machine>.<project>.<session>, where <session> defaults to the working directory name.

2. (Optional) Configure the channel.

The /grok-nats-channel:configure skill manages connection, session naming, and permissions. All state lives in ~/.grok/channels/nats/config.json.

| Command | Description | | --- | --- | | /grok-nats-channel:configure | Show current config, list available contexts, and offer to switch | | /grok-nats-channel:configure list | List available NATS CLI contexts | | /grok-nats-channel:configure <context-name> | Select a NATS CLI context to connect to | | /grok-nats-channel:configure session <name> | Override the session name (the <session> token in agents.prompt.<machine>.<project>.<session>) | | /grok-nats-channel:configure session clear | Remove session name override, revert to CWD basename | | /grok-nats-channel:configure permissions terminal | Prompt for permissions in the terminal (default) | | /grok-nats-channel:configure permissions query | Relay permission prompts as protocol query chunks | | /grok-nats-channel:configure permissions clear | Reset permissions to default | | /grok-nats-channel:configure clear | Remove all configuration |

To connect to your own NATS server, use a NATS CLI context. List your contexts with nats context ls, then:

/grok-nats-channel:configure <context-name>

This writes the selected context to ~/.grok/channels/nats/config.json. The server reads connection details (URL, credentials) from ~/.config/nats/context/<name>.json.

3. How NATS prompts appear to Grok (the <channel> notification)

When a prompt arrives over NATS, Grok receives it wrapped in a host-specific channel notification:

<channel source="nats" request_id="..." session="..." ts="...">
[optional attachments header + file paths]
The user's prompt text here...
</channel>
  • source="nats" identifies the origin.
  • request_id is the opaque ID you must pass to the reply tool.
  • session is the resolved 5th subject token (<name>).
  • Attachments (if any) are staged to absolute paths on disk and listed at the top of the block so the model can Read them.

4. Reply using the reply tool

To send a response back to the NATS caller, use the built-in reply tool:

  • Pass the request_id from the <channel> block.
  • text: the content to deliver (as a {"type":"response","data":...} chunk).
  • done: set false for intermediate/streaming replies; true (default) emits the empty-body terminator that signals completion per the protocol.

Example (conceptual):

reply(request_id="abc123", text="Working on it...", done=false)
reply(request_id="abc123", text="Here is the final answer.", done=true)

The server handles chunking for large payloads, status acks, and cleanup.

5. Send a prompt (from a client).

With the @synadia-ai/agents TypeScript SDK:

import { connect } from "@nats-io/transport-node";
import { Agents } from "@synadia-ai/agents";

const nc = await connect({ servers: "nats://localhost:4222" });
const agents = new Agents({ nc });
const [agent] = await agents.discover();
for await (const msg of await agent!.prompt("hello Grok")) {
  if (msg.type === "response") process.stdout.write(msg.text);
}
await agents.close();
await nc.close();

Or directly via the NATS CLI (plain-text shorthand per spec §5.1):

nats req agents.prompt.<machine>.<project>.<session> "Hello Grok" \
  --replies=0 --reply-timeout=30s --timeout=90s

Grok's response streams back as typed JSON chunks on the reply subject; an empty headerless message signals completion.

Protocol compliance

This adapter implements the Synadia Agent Protocol for NATS v0.3 end-to-end, and additively advertises the in-development sesh v0.4 capability via $SRV.INFO metadata so the sesh shim can route v0.4 traffic (v2 envelopes, AgentCard L3 lookup) to this agent without disturbing the v0.3 wire.

v0.4 surface (slice 6 of the v0.4 rollout — see docs/plans/2026-05-24-v0.4-sdk-and-adapters.md):

  • Service metadata adds sesh.protocol_version: "0.4" and sesh.v04_capabilities: "messages,artifacts,cards". The v0.3 protocol_version: "0.3" key stays — third-party SDK probes continue to see a v0.3-conformant agent.
  • Prompt endpoint at agents.prompt.<machine>.<project>.<session> (queue group agents-prompt). Decodes the Message envelope and bridges into the MCP notification pipeline; replies stream back as agents.task.stream.* events on the consumer side.
  • AgentCard L3 registration at agents.card.<machine>.<session>.<name> — returns a partial card with one representative skill (grok.code). The shim signs and serves the merged L1+L2+L3 card over HTTPS.

Streaming Artifacts / Messages KV writes are deferred to a follow-up — the v2 handler currently bridges into the same MCP pipeline as v0.3 and replies on msg.reply with v0.3-format chunks. The shim re-projects those chunks into v2 agents.task.stream.* events on the consumer side.

The v0.3 wire below is unchanged.

  • Registers as an agents NATS micro service (§3.1 - the bare subject-safe token).
  • Service metadata includes agent, owner, session, and protocol_version: "0.3" (§3.2).
  • prompt endpoint declares the server-negotiated max_payload (read from nc.info.max_payload at startup and formatted into the §2.1 \d+(B|KB|MB|GB) grammar — 1MB against a default nats-server, larger if the operator bumped --max_payload), attachments_ok: "true" (§2.1), and queue group "agents" (§3.3).
  • Accepts both plain-text shorthand and JSON envelopes with optional base64-encoded attachments (§5.1, §5.2, §5.3). Inbound attachments are staged to a per-request temp directory and exposed to Grok via file paths.
  • Rejects malformed envelopes, empty payloads, oversize requests, and invalid base64 with Nats-Service-Error-Code: 400 (§9).
  • Emits typed response chunks {"type":"response","data":"..."} (§6.3) terminated by an empty headerless message (§6.5). Large responses are split into multiple UTF-8-safe chunks that each fit under max_payload.
  • Publishes periodic {"type":"status","data":"ack"} keep-alives (§6.4) every 30 s while a request is open, resetting the caller's 60-second inactivity timeout.
  • Publishes heartbeats at agents.hb.<machine>.<project>.<session> every 5 s with the full §8.3 payload including instance_id (§8).
  • Relays Grok permission prompts as mid-stream query chunks (§7) when permissions.mode = query.

The caller-side SDK at the Synadia Agents repository is the canonical counterpart.

Session names

The micro service prompt subject is agents.prompt.<machine>.<project>.<session> (clean v0.4 scheme; identity lives in metadata, not the subject). Heartbeats go to agents.hb.<machine>.<project>.<session> and the status endpoint replies on agents.status.<machine>.<project>.<session>.

  • Default: sanitized basename of the working directory (e.g., my-project)
  • Canonical override: set SESH_SESSION env var — the sesh contract; populated automatically by sesh up --exec and orch-spawn SESH_* exports. Also resolved via the .sesh/sessions/<label>.json state-walk when unset.
  • Legacy override: set NATS_SESSION_NAME env var (back-compat), or use /grok-nats-channel:configure session <name>
  • Multiple sessions: if the default name is already taken by another grok instance owned by the same user, the adapter auto-appends -2, -3, etc.

Discover running sessions via the protocol's discovery subjects:

nats req '$SRV.INFO.agents' '' --replies=0 --timeout=2s
nats req '$SRV.PING.agents' '' --replies=0 --timeout=2s

Or via the NATS Micro CLI:

nats micro ls
nats micro info agents

Tools exposed to the assistant

| Tool | Purpose | | --- | --- | | reply | Send a response over NATS. Takes request_id + text. The server wraps the text in a {"type":"response","data":...} chunk. Set done=false for intermediate replies; done=true (default) emits the empty-body terminator. |

Permissions

When Grok needs permission to run a tool, the adapter can either prompt in the terminal (default) or relay the request as a protocol query chunk on the active NATS stream. This is controlled by the permissions config.

Terminal mode (default)

Permission prompts appear directly in the Grok terminal / TUI session. No extra configuration needed.

Query mode

Permission requests are emitted as {"type":"query","data":{...}} chunks on the active stream's reply subject (spec §7). The caller replies on the query's dynamic _INBOX with yes/no, and the adapter forwards the decision back to the harness.

/grok-nats-channel:configure permissions query

To switch back to terminal mode:

/grok-nats-channel:configure permissions terminal

The legacy value "nats" is still accepted as an alias for "query" so old configs keep working. The older permissions.subject override field has been removed - query chunks always use a fresh NATS inbox per request.

If Grok asks for permission while no NATS request is active (for example from direct terminal input), the adapter denies by default in query mode; use permissions terminal instead if you want interactive approval in that case.

Handling permission queries with the SDK

for await (const msg of await remote.prompt("rm -rf /tmp/stale")) {
  if (msg.type === "query") {
    await msg.reply("yes");  // or "no"
  }
  if (msg.type === "response") {
    process.stdout.write(msg.text);
  }
}

Or with the NATS CLI, by publishing to the reply_subject from the query chunk:

nats pub _INBOX.Xj7k9Q2pA "yes"

If no reply is received within 2 minutes, the permission defaults to deny.

Access control

NATS server authentication and authorization handle access control. If a user can connect and publish to agents.prompt.<machine>.<project>.<session>, they can interact with Grok. No additional pairing or allowlist is needed.

Grok authentication

Grok sessions and model access are authenticated through the host Grok application and xAI infrastructure. The NATS channel adapter requires no separate API keys or credentials — it communicates with the local Grok harness exclusively via the MCP protocol.

Configuration

State lives in ~/.grok/channels/nats/:

| File | Purpose | | --- | --- | | config.json | Selected NATS context, session name override, and permission settings | | attachments/<request_id>/ | Per-request staged attachments; auto-cleaned on reply completion |

NATS CLI contexts live in ~/.config/nats/context/<name>.json.

config.json

{
  "context": "my-context",
  "sessionName": "my-session",
  "permissions": {
    "mode": "query"
  }
}

| Field | Default | Description | | --- | --- | --- | | context | (none - uses demo.nats.io) | NATS CLI context name | | sessionName | CWD basename | Override the session name | | permissions.mode | terminal | terminal or query (nats accepted as legacy alias for query) |

Environment variables

| Variable | Overrides | Default | | --- | --- | --- | | SESH_SESSION | Session name (the <session> token in agents.prompt.<machine>.<project>.<session>); canonical sesh contract — wins over NATS_SESSION_NAME. Also resolved via .sesh/sessions/<label>.json state-walk when unset. | (unset) | | NATS_SESSION_NAME | Legacy operator override for session name. | sanitized basename of $GROK_CWD or CWD | | NATS_STATE_DIR | State directory location | ~/.grok/channels/nats | | NATS_CONTEXT | NATS CLI context name (higher precedence than config file) | (none) | | NATS_URL | Raw NATS URL (fallback when no context) | (none - falls back to demo.nats.io) | | SESH_ROLE | Free-form role token (^[a-z0-9_-]+$, 1–63 chars). Identifies the function this agent plays in the swarm — e.g. implementer, verifier, spy. Surfaced as metadata.role on the NATS Micro service and as role in sesh's session manifest. | worker | | SESH_CLASS | One of active or observer. Coordination-subject routing keys on this: active agents subscribe to workers.*, observer agents subscribe to spies.*. | active |

Enabling in Grok (Grok-side Launcher)

The adapter is distributed as a Grok plugin (skills + .mcp.json + .grok-plugin manifest). This implements the Grok-side consumption (Task 6 of the implementation plan).

Quick Enable (recommended)

  1. Ensure you have the adapter repo at ~/projects/grok-nats-channel (or your preferred location).
  2. In a Grok session, run:
    /grok-nats-channel:launcher enable
    (or /grok-nats-channel:launcher enable /custom/path/to/grok-nats-channel)
  3. The launcher skill creates the symlink ~/.grok/plugins/grok-nats-channel → your path.
  4. Grok will automatically pick up the MCP server definition from .mcp.json and the /grok-nats-channel:configure + launcher commands from the skills/ directory.
  5. Run /grok-nats-channel:configure to pick your NATS context / session name / permission mode.
  6. Restart your Grok TUI/session — the MCP spawns at startup.
  7. Verify: grok mcp list shows "nats"; nats micro ls shows a gr service; NATS prompts now arrive as <channel source="nats" ...> blocks with a reply tool.

Manual / Advanced

  • Symlink the plugin yourself:
    mkdir -p ~/.grok/plugins
    ln -sfn ~/projects/grok-nats-channel ~/.grok/plugins/grok-nats-channel
  • Or register explicitly (if not using the plugin loader):
    grok mcp add nats --command bun --args server.ts --cwd ~/projects/grok-nats-channel
  • Disable:
    /grok-nats-channel:launcher disable
    rm -f ~/.grok/plugins/grok-nats-channel

Packaging note: We chose local plugin path (Option A) for v1/dev. Once published to npm under the @agent-ops scope (as @agent-ops/grok-nats-channel or equivalent), the launcher will also support bunx @agent-ops/grok-nats-channel and direct Grok marketplace installation (which will manage the plugin cache automatically). The skill names (/grok-nats-channel:*) are derived from the installed plugin directory and remain stable.

See skills/launcher/SKILL.md and skills/configure/SKILL.md for the full command surfaces.