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

@gdrl/kronos-lib

v0.1.6

Published

Lightweight TypeScript SDK for the Kronos Knowledge Graph API

Downloads

474

Readme

kronos-lib

Lightweight TypeScript SDK for the Kronos Knowledge Graph API. Use it from Next.js, Node.js, or any JavaScript environment with fetch (Node 18+, browsers).

Installation

npm install kronos-lib
# or
pnpm add kronos-lib
# or
yarn add kronos-lib

Quick Start

import { KronosClient } from '@gdrl/kronos-lib';

const client = new KronosClient({
  workerUrl: 'https://your-worker.workers.dev',
  mastraUrl: 'https://your-mastra-server.com',
  apiKey: 'your-app-api-key',
  appId: 'your-app-id',
  tenantUserId: 'user-123',
});

// Ingest a document
const { ingest_id } = await client.ingest({
  source_type: 'email',
  content: { type: 'text', text: 'Document content...' },
  metadata: { sender: '[email protected]' },
});

// Check ingest status
const status = await client.getIngestStatus(ingest_id);

// Create an MCP server
const mcp = await client.createMCPServer({
  name: 'My MCP Server',
  collection_ids: ['col-1', 'col-2'],
  description: 'Optional description',
});

// Connect to the MCP server (short-lived access token, ~1 day)
const connection = await client.connectMCPServer({
  serverId: mcp.mcp_server_id,
});
// connection.url is the full MCP endpoint; connection.access_token is the Bearer token.

// Query the knowledge graph
const results = await client.query({
  query: 'What happened in Tokyo?',
  collection_ids: ['col-1', 'col-2'],
});
// results.episodes, results.entities, results.attributes, results.direct_answer

// Create a collection
const collection = await client.createCollection({
  spec: {
    name: 'Work Emails',
    include_query: 'work OR project',
    scope: 'episode',
    match_mode: 'broad',
  },
  created_by: 'user-123',
});
// collection.collection_id, collection.backfill_job_id

// Refresh collections for new episodes
await client.refreshCollections({ episode_ids: ['ep-1', 'ep-2'] });

Configuration

| Option | Description | |---------------|-----------------------------------------------------------------------------| | workerUrl | Base URL of the Cloudflare Worker (ingest, MCP server create/rotate). | | mastraUrl | Base URL of the Mastra server (query, collections). | | apiKey | App API key; used as Authorization: Bearer for Worker endpoints. | | appId | App ID; injected into Worker and Mastra request bodies. | | tenantUserId| Tenant/user ID; injected into request bodies. |

Local development

Set KRONOS_WORKER_URL and KRONOS_MASTRA_URL in your app's .env for local dev (e.g. http://localhost:8787, http://localhost:4111). Pass these when creating the client via your app's shared config helper, or the client will read them from process.env. Omit in production to use production defaults. For the frontend (KronosProvider), use NEXT_PUBLIC_KRONOS_WORKER_URL (kronos-nextjs already defaults to localhost).

API Overview

Ingest (Worker)

  • ingest(params) – Submit a document. Requires source_type and content: { type: 'text', text }. Optional: metadata, addToMemory, idempotencyKey. addToMemory defaults to true; set it to false to run ingest-trigger workflows without chunking or adding the content to memory. If idempotencyKey is omitted, one is generated. Returns { ingest_id }.
  • getIngestStatus(ingestId) – Get status and progress of an ingest.

MCP Servers (Worker)

  • createMCPServer(params) – Create an MCP server. Requires name, collection_ids. Optional: description. Returns MCP server metadata including mcp_server_id.
  • listMCPServers(params) – List MCP servers for a user. Returns metadata only (no token).
  • getMCPServer(params) – Get MCP server metadata by serverId (no token).
  • connectMCPServer(params) – Issue a short-lived MCP access token for a server. Returns { mcp_server_id, url, access_token, expires_at }.
  • rotateMCPServerToken(serverId) – Legacy token rotation endpoint (generally not needed with short-lived connect tokens).

Query (Mastra)

  • query(params) – Query the graph. Requires query, collection_ids. Returns { episodes, entities, attributes, direct_answer? }.

Collections (Mastra)

  • createCollection(params) – Create a collection. Requires spec (e.g. name, include_query, scope, match_mode), created_by. Optional: description. Returns { collection_id, backfill_job_id }.
  • refreshCollections(params) – Refresh collection membership for episode_ids. Optional: mode (default 'new_episodes_only'). Returns { accepted: true }.

Idempotency

For ingest, the Worker requires an Idempotency-Key header. You can pass idempotencyKey in the options; if omitted, the SDK generates one. For true idempotency (e.g. retries), pass a stable key (e.g. hash of source_type + content.text or your own id).

Error Handling

The SDK throws typed errors for HTTP failures:

  • KronosBadRequestError (400)
  • KronosUnauthorizedError (401)
  • KronosForbiddenError (403)
  • KronosNotFoundError (404)
  • KronosServerError (5xx)
  • KronosError (other)

All extend KronosError and include status, code, and body when available.

import { KronosClient, KronosNotFoundError } from '@gdrl/kronos-lib';

try {
  await client.getIngestStatus('missing-id');
} catch (e) {
  if (e instanceof KronosNotFoundError) {
    console.log('Ingest not found:', e.body);
  }
  throw e;
}

React integration (optional)

If you're building a React or Next.js app, you can use the optional React hook exported from the kronos-lib/react subpath.

useKronos (triggers)

For now, useKronos focuses on trigger operations (more domains can be added over time):

import { useKronos, type KronosTriggerOps } from '@gdrl/kronos-lib/react';

const ops: KronosTriggerOps = {
  async listTriggers() {
    // Example: call your own app route that proxies to Kronos
    const response = await fetch('/api/mercury/triggers');
    const body = await response.json();
    return {
      triggers: body.triggers ?? [],
      count: body.count ?? (body.triggers ?? []).length,
    };
  },
  async createNlTrigger({ nl, actionDescription }) {
    const response = await fetch('/api/mercury/triggers', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ type: 'nl_webhook', nl, actionDescription }),
    });
    const body = await response.json();
    return { triggerId: body.trigger_id ?? null };
  },
};

function Automations() {
  const {
    triggers,
    triggersLoading,
    triggersError,
    refreshTriggers,
    createNlTrigger,
    createLoading,
    createError,
  } = useKronos({ ops, tenantUserId: 'current-user' });

  // ...render UI...
}

This pattern lets you keep API keys and webhook secrets on the server (behind your own API routes), while still getting a clean React hook surface for reading and creating triggers.

Types

All request/response types are exported:

  • IngestRequest, IngestResponse, IngestStatusResponse
  • CreateMCPServerRequest, CreateMCPServerResponse, MCPServerDetails, ListMCPServersResponse, GetMCPServerResponse, ConnectMCPServerRequest, ConnectMCPServerResponse
  • RotateMCPServerTokenRequest, RotateMCPServerTokenResponse
  • QueryRequest, QueryResponse, EpisodeResult, EntityResult, AttributeResult
  • CollectionSpec, CreateCollectionRequest, CreateCollectionResponse
  • RefreshCollectionsRequest, RefreshCollectionsResponse
  • KronosClientConfig

Requirements

  • Node.js 18+ or a modern browser (uses global fetch)
  • TypeScript 4.7+ recommended for types

License

MIT