@gdrl/kronos-lib
v0.1.6
Published
Lightweight TypeScript SDK for the Kronos Knowledge Graph API
Downloads
474
Maintainers
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-libQuick 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. Requiressource_typeandcontent: { type: 'text', text }. Optional:metadata,addToMemory,idempotencyKey.addToMemorydefaults totrue; set it tofalseto run ingest-trigger workflows without chunking or adding the content to memory. IfidempotencyKeyis 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. Requiresname,collection_ids. Optional:description. Returns MCP server metadata includingmcp_server_id.listMCPServers(params)– List MCP servers for a user. Returns metadata only (no token).getMCPServer(params)– Get MCP server metadata byserverId(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. Requiresquery,collection_ids. Returns{ episodes, entities, attributes, direct_answer? }.
Collections (Mastra)
createCollection(params)– Create a collection. Requiresspec(e.g.name,include_query,scope,match_mode),created_by. Optional:description. Returns{ collection_id, backfill_job_id }.refreshCollections(params)– Refresh collection membership forepisode_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,IngestStatusResponseCreateMCPServerRequest,CreateMCPServerResponse,MCPServerDetails,ListMCPServersResponse,GetMCPServerResponse,ConnectMCPServerRequest,ConnectMCPServerResponseRotateMCPServerTokenRequest,RotateMCPServerTokenResponseQueryRequest,QueryResponse,EpisodeResult,EntityResult,AttributeResultCollectionSpec,CreateCollectionRequest,CreateCollectionResponseRefreshCollectionsRequest,RefreshCollectionsResponseKronosClientConfig
Requirements
- Node.js 18+ or a modern browser (uses global
fetch) - TypeScript 4.7+ recommended for types
License
MIT
