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-ws

v1.0.4

Published

WebSocket bridge for CLI AI agents — stream Claude and Codex CLI responses over WebSocket

Readme

agent-ws

WebSocket bridge for CLI AI agents. Stream responses from Claude Code and Codex CLI over WebSocket. A dumb pipe: no prompt engineering, no credential handling, just transport.

Prerequisites

  • Node.js 20+
  • At least one supported CLI agent installed:
    • Claude Code (npm install -g @anthropic-ai/claude-code)
    • Codex (npm install -g @openai/codex)

Installation

# From npm
npm install -g agent-ws

# Or run directly
npx agent-ws

# Or clone and run locally
git clone https://github.com/Lisovate/agent-ws.git
cd agent-ws
npm install
npm run build
npm start

Quick Start

# Start the WebSocket bridge
agent-ws

# Connect via WebSocket on ws://localhost:9999

Library Usage (Node.js only)

If you want to embed the WebSocket server into your own Node.js backend (e.g. Express, Fastify, or a Next.js API route) instead of running the CLI:

import { AgentWS } from "agent-ws";

const agent = new AgentWS({
  port: 9999,
  host: "localhost",
  agentName: "my-app",       // Customise the agent identity in connected messages
  sessionDir: "my-sessions", // Customise the temp directory name for sessions
});

await agent.start();

Note: This is server-side only. Browser/React clients should connect to the running agent-ws server as a WebSocket client (see Protocol).

CLI Options

-p, --port <port>            WebSocket server port (default: 9999)
-H, --host <host>            WebSocket server host (default: localhost)
-c, --claude-path <path>     Path to Claude CLI (default: claude)
    --codex-path <path>      Path to Codex CLI (default: codex)
-t, --timeout <seconds>      Process timeout in seconds (default: 300)
    --log-level <level>      Log level: debug, info, warn, error (default: info)
    --origins <origins>      Comma-separated allowed origins
-V, --version                Output version number
-h, --help                   Display help

Architecture

┌───────────────┐     WebSocket      ┌─────────────┐      stdio       ┌─────────────┐
│  Your App     │ <=================> │  agent-ws   │ <===============> │ Claude Code │
│  (any client) │   localhost:9999   │  (Node.js)  │      stdio       │  / Codex    │
└───────────────┘                    └─────────────┘                   └─────────────┘

Any WebSocket client can connect — browser frontends, backend services, scripts, other CLI tools. Each connection gets its own CLI process. The agent:

  1. Accepts WebSocket connections on localhost
  2. Receives prompt messages from your client
  3. Spawns the appropriate CLI agent (Claude Code or Codex)
  4. Streams output back in real-time
  5. Manages process lifecycle (timeout, cancellation, cleanup)

Supported Agents

| Agent | Provider field | CLI | |-------|---------------|-----| | Claude Code | "claude" (default) | claude --print --verbose --output-format stream-json | | Codex | "codex" | codex --json |

Protocol

Client → Agent

{ "type": "prompt", "prompt": "Build a login form", "requestId": "uuid", "model": "opus", "provider": "claude" }
{ "type": "prompt", "prompt": "...", "requestId": "uuid", "projectId": "my-app", "systemPrompt": "...", "thinkingTokens": 2048 }
{ "type": "prompt", "prompt": "Describe this image", "requestId": "uuid", "images": [{ "media_type": "image/png", "data": "<base64>" }] }
{ "type": "cancel", "requestId": "uuid" }

| Field | Required | Description | |-------|----------|-------------| | prompt | yes | The prompt text (max 512KB) | | requestId | yes | Unique request identifier | | model | no | Model name (e.g. "sonnet", "opus") | | provider | no | "claude" (default) or "codex" | | projectId | no | Scopes CLI session by directory. Enables --continue for multi-turn. Alphanumeric, hyphens, underscores, dots only. | | systemPrompt | no | Appended as system prompt (max 64KB) | | thinkingTokens | no | Max thinking tokens. 0 disables thinking. Omit to let Claude decide. | | images | no | Array of { media_type, data } objects. Up to 4 images, max 10MB base64 each. Supported types: image/png, image/jpeg, image/gif, image/webp. |

Agent → Client

{ "type": "connected", "version": "1.0", "agent": "agent-ws" }
{ "type": "chunk", "content": "Here's a login form...", "requestId": "uuid" }
{ "type": "chunk", "content": "Let me think...", "requestId": "uuid", "thinking": true }
{ "type": "complete", "requestId": "uuid" }
{ "type": "error", "message": "Process timed out", "requestId": "uuid" }

Chunks with thinking: true contain Claude's reasoning. Clients can display these as a thinking indicator or ignore them.

Security

  • Local only: Binds to localhost by default
  • Origin validation: Optional --origins flag restricts allowed origins
  • No credentials: Never stores or transmits API keys
  • Process isolation: One CLI process per connection
  • Message limits: 50MB max WebSocket payload, 512KB max prompt, 10MB per image (4 max)
  • Heartbeat: Dead connections are cleaned up every 30 seconds

Development

npm install          # Install dependencies
npm run build        # Build TypeScript
npm test             # Run tests
npm run typecheck    # Type check
npm start            # Start from built output

Project Structure

src/
├── index.ts               # Barrel export (library entry point)
├── cli.ts                 # CLI entry point (Commander)
├── agent.ts               # Orchestrator: wires server + logger
├── server/
│   ├── websocket.ts       # WebSocket server, heartbeat, per-connection state
│   └── protocol.ts        # Message types, validation
├── process/
│   ├── claude-runner.ts   # Claude Code process spawn/kill/timeout
│   ├── codex-runner.ts    # Codex process spawn/kill/timeout
│   └── output-cleaner.ts  # ANSI stripping via node:util
└── utils/
    ├── logger.ts          # Pino logger factory
    └── claude-check.ts    # Claude CLI availability check

Troubleshooting

"Claude CLI not found"

Make sure Claude Code is installed:

npm install -g @anthropic-ai/claude-code
claude --version

"Port 9999 already in use"

Another instance might be running. Kill it or use a different port:

agent-ws --port 9998

License

MIT