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

@cubicler/cubicagentkit

v2.6.3

Published

Node.js library for creating AI agents that integrate with Cubicler

Readme

CubicAgentKit

npm version [!## 🎯 Recent Updates

v2.6.0 - Major Architecture Improvements:

  • 🔄 JSON-RPC 2.0 Protocol: Stdio transport now uses standard JSON-RPC 2.0 for all communication
  • 📁 Unified Models: Consolidated agent request/response types into single agent.ts model file
  • 📝 Logger Infrastructure: Added comprehensive logging system with transport-specific behavior
  • 🏗️ Builder Pattern: Enhanced fluent API for agent configuration with start().onMessage().onTrigger().listen()
  • 🛡️ Type Safety: Improved TypeScript support with stricter typing and better error handling

All changes maintain full backward compatibility while improving code organization and protocol standardization.

🏗️ Architecturehttps://img.shields.io/badge/TypeScript-5.6.3-blue.svg)](https://www.typescriptlang.org/)

License: Apache 2.0

A modern Node.js library for creating AI agents that integrate seamlessly with Cubicler 2.6. Built with TypeScript, composition patterns, and dependency injection for maximum flexibility and testability.

🚀 Features

  • 🧱 Simple & Complete: CubicAgent class handles all Cubicler integration
  • 🔌 Composition-Based: Uses dependency injection for easy testing and flexibility
  • 📡 Multiple Transports: HTTP, SSE (Server-Sent Events), and Stdio support
  • 🔐 JWT Authentication: Complete JWT support with static tokens and OAuth 2.0 flows
  • 🧠 Memory System: SQLite-based persistent memory with LRU short-term caching
  • 📊 Tool Call Tracking: Automatic tracking of tool usage per request
  • 🛡️ Type-Safe: Full TypeScript support with strict typing and consolidated model architecture
  • 📝 Smart Logging: Transport-specific logging system (silent for stdio, console for HTTP/SSE)
  • 🔍 Error Transparent: All errors thrown up to implementers for custom handling

📦 Installation

npm install @cubicler/cubicagentkit

🏃‍♂️ Quick Start

Choose your preferred transport method:

HTTP Agent (Traditional Server)

import { CubicAgent, HttpAgentClient, HttpAgentServer, MessageHandler } from '@cubicler/cubicagentkit';

const client = new HttpAgentClient('http://localhost:1503');
const server = new HttpAgentServer(3000, '/agent');
const agent = new CubicAgent(client, server);

const messageHandler: MessageHandler = async (request, client, context) => {
  const lastMessage = request.messages[request.messages.length - 1];
  return {
    type: 'text',
    content: `Hello! You said: ${lastMessage.content}`,
    usedToken: 25
  };
};

await agent.start()
  .onMessage(messageHandler)
  .listen();

console.log('✅ Agent running on http://localhost:3000/agent');

SSE Agent (Real-time)

import { CubicAgent, HttpAgentClient, SSEAgentServer, MessageHandler } from '@cubicler/cubicagentkit';

const client = new HttpAgentClient('http://localhost:1503');
const server = new SSEAgentServer('http://localhost:8080', 'my-agent-id');
const agent = new CubicAgent(client, server);

const messageHandler: MessageHandler = async (request, client, context) => {
  // Same handler logic as HTTP version
  return { type: 'text', content: 'Hello from SSE!', usedToken: 15 };
};

await agent.start()
  .onMessage(messageHandler)
  .listen();

console.log('⚡ SSE Agent connected to Cubicler');

Stdio Agent (CLI/Subprocess)

For agents that run as subprocesses spawned by Cubicler:

#!/usr/bin/env node
import { CubicAgent, StdioAgentClient, StdioAgentServer, MessageHandler } from '@cubicler/cubicagentkit';

// Stdio agent is spawned by Cubicler, not the other way around
const client = new StdioAgentClient();
const server = new StdioAgentServer();
const agent = new CubicAgent(client, server);

const messageHandler: MessageHandler = async (request, client, context) => {
  const lastMessage = request.messages[request.messages.length - 1];
  
  // Make MCP calls back to Cubicler using JSON-RPC 2.0
  const weather = await client.callTool('weather_get_current', { city: 'Paris' });
  
  return {
    type: 'text',
    content: `Weather: ${weather.temperature}°C`,
    usedToken: 30
  };
};

await agent.start()
  .onMessage(messageHandler)
  .onTrigger(async (request) => ({
    type: 'text',
    content: `Webhook: ${request.trigger.name}`,
    usedToken: 15
  }))
  .listen();

console.error('Stdio Agent ready'); // Use stderr for logging

⚠️ Important: NPX Execution Fix

When using stdio agents that can be executed via npx, ensure proper main module detection by checking both the standard import.meta.url comparison and the process arguments for your package name:

// Only run if this is the main module (handle both direct execution and npx)
const isMainModule = import.meta.url === `file://${process.argv[1]}` || 
                     process.argv[1]?.includes('your-package-name');
if (isMainModule) {
  main().catch((error) => {
    console.error('Unhandled error:', error);
    process.exit(1);
  });
}

This prevents the common issue where stdio agents fail to start when executed via npx because process.argv[1] points to the npx wrapper instead of the actual module file.

Configure in Cubicler's agents.json:

{
  "agents": {
    "my_stdio_agent": {
      "name": "My Stdio Agent",
      "transport": "stdio",
      "command": "/path/to/my-agent.js",
      "description": "A stdio-based agent"
    }
  }
}

📚 Documentation

Transport Guides

  • HTTP Agent - Traditional server deployment with HTTP endpoints
  • SSE Agent - Real-time communication via Server-Sent Events
  • Stdio Agent - Command-line and subprocess integration with JSON-RPC 2.0 protocol

Feature Guides

  • JWT Authentication - Comprehensive authentication with static tokens and OAuth 2.0
  • Security note: the built-in server JWT verifier is development‑oriented and does not verify signatures. For production, use a jsonwebtoken/JWKS middleware as shown in docs/JWT_AUTH.md.
  • Memory System - Persistent memory with SQLite and LRU caching
  • Webhook Implementation - Complete guide for handling webhook triggers alongside user messages

� Recent Updates

v2.6.0 - Major Architecture Improvements:

  • 🔄 JSON-RPC 2.0 Protocol: Stdio transport now uses standard JSON-RPC 2.0 for all communication
  • 📁 Unified Models: Consolidated agent request/response types into single agent.ts model file
  • 📝 Logger Infrastructure: Added comprehensive logging system with transport-specific behavior
  • �🏗️ Builder Pattern: Enhanced fluent API for agent configuration with start().onMessage().onTrigger().listen()
  • 🛡️ Type Safety: Improved TypeScript support with stricter typing and better error handling

All changes maintain full backward compatibility while improving code organization and protocol standardization.

CubicAgentKit follows a composition-based architecture with clean separation of concerns:

┌─────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│   CubicAgent    │────│  AgentClient     │────│ HttpAgentClient  │
│   (Orchestrator)│    │  (Interface)     │    │ (HTTP Client)    │
└─────────────────┘    └──────────────────┘    └──────────────────┘
         │                                               │
         │              ┌──────────────────┐    ┌──────────────────┐
         ├──────────────│  AgentServer     │    │ StdioAgentClient │
         │              │  (Interface)     │    │ (CLI Client)     │
         │              └──────────────────┘    └──────────────────┘
         │                        │
         │              ┌──────────────────┐
         │              │ HttpAgentServer  │
         │              │ (HTTP Server)    │
         │              └──────────────────┘
         │                        │
         │              ┌──────────────────┐
         │              │ SSEAgentServer   │
         │              │ (SSE Client)     │
         │              └──────────────────┘
         │                        │
         │              ┌──────────────────┐
         │              │ StdioAgentServer │
         │              │ (CLI Server)     │
         │              └──────────────────┘
         │
         │              ┌──────────────────┐    ┌──────────────────┐
         └──────────────│ MemoryRepository │────│ SQLiteMemory +   │
                        │  (Interface)     │    │ LRUShortTerm     │
                        └──────────────────┘    └──────────────────┘

Core Components

  • CubicAgent: Main orchestrator handling server lifecycle, request routing, and memory integration
  • HttpAgentClient: HTTP client implementing Cubicler's MCP protocol
  • StdioAgentClient: Stdio client for CLI-based MCP communication using JSON-RPC 2.0
  • HttpAgentServer: HTTP server handling agent endpoint requests
  • StdioAgentServer: Stdio server for CLI-based agent communication using JSON-RPC 2.0
  • SSEAgentServer: SSE client for real-time communication with Cubicler
  • AgentMemoryRepository: Two-tier memory system with persistent storage and LRU cache

📝 API Reference

CubicAgent

Main class for creating and managing Cubicler agents. Uses a fluent builder to register handlers.

class CubicAgent {
  constructor(
    agentClient: AgentClient,
    server: AgentServer,
    memory?: MemoryRepository
  ) {}

  // Begin fluent configuration
  start(): AgentBuilder;

  // Stop the server
  async stop(): Promise<void>;

  // Manually dispatch a request using configured handlers
  async dispatch(request: AgentRequest): Promise<AgentResponse>;
}

interface AgentBuilder {
  onMessage(handler: MessageHandler): AgentBuilder;
  onTrigger(handler: TriggerHandler): AgentBuilder;
  listen(): Promise<void>;
}

interface CallContext {
  readonly toolCallCount: number; // tool calls in this request
  readonly memory?: MemoryRepository; // optional repository from constructor
}

Memory System

Create memory repositories with factory functions:

// In-memory SQLite (development)
const memory = await createDefaultMemoryRepository();

// File-based SQLite (production)
const memory = await createSQLiteMemoryRepository('./memories.db');

// Custom setup
const memory = await createMemoryRepository(longTermStorage, 2000, 0.7);

Trigger Handling

Register a webhook trigger handler with the builder. When Cubicler invokes a trigger, your handler receives a TriggerRequest:

import { CubicAgent, HttpAgentClient, HttpAgentServer, TriggerHandler } from '@cubicler/cubicagentkit';

const agent = new CubicAgent(
  new HttpAgentClient('http://localhost:1503'),
  new HttpAgentServer(3000, '/agent')
);

const onTrigger: TriggerHandler = async (request, client, ctx) => {
  // request.trigger contains identifier and payload
  return { type: 'text', content: `Triggered: ${request.trigger.identifier}` , usedToken: 5 };
};

await agent.start().onTrigger(onTrigger).listen();

Request & Response Types

// What your handler receives
interface AgentRequest {
  agent: { identifier: string; name: string; description: string; prompt: string; };
  tools: AgentTool[];
  servers: ServerInfo[];
  messages: Message[];
}

// What your handler returns (simplified)
interface RawAgentResponse {
  type: 'text' | 'null';
  content: string | null;
  usedToken: number;
}

🧪 Testing

The library is thoroughly tested with 25+ unit tests. Run tests with:

npm test          # Run in watch mode
npm run test:run  # Run once
npm run test:ui   # Run with UI

Mock Implementations

import { MockAgentClient, MockAgentServer } from '@cubicler/cubicagentkit/tests/mocks';

const mockClient = new MockAgentClient();
const mockServer = new MockAgentServer();
const testAgent = new CubicAgent(mockClient, mockServer);

mockClient.mockToolCall('weatherService_getWeather', { temperature: '22°C' });

🔨 Development

# Install dependencies
npm install

# Build the library
npm run build

# Lint code
npm run lint

# Run full check (lint + test + build)
npm run check

📄 License

Apache 2.0 License - see LICENSE file for details.

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

📞 Support


Built with ❤️ for the Cubicler ecosystem.