# Kalairos

> Durable, private, time-aware memory engine for long-running AI agents

- **Type:** MCP server
- **Install:** `agentstack add mcp-labskrishna-kalairos`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [LabsKrishna](https://agentstack.voostack.com/s/labskrishna)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [LabsKrishna](https://github.com/LabsKrishna)
- **Source:** https://github.com/LabsKrishna/kalairos
- **Website:** https://krishnalabs.ai

## Install

```sh
agentstack add mcp-labskrishna-kalairos
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Kalairos

[](https://www.npmjs.com/package/kalairos)
[](https://www.npmjs.com/package/kalairos)
[](https://github.com/LabsKrishna/kalairos/blob/main/LICENSE)
[](https://www.npmjs.com/package/kalairos)
[](https://codecov.io/gh/LabsKrishna/kalairos)
[](https://github.com/LabsKrishna/kalairos/actions/workflows/ci.yml)

> **Kalairos — the agent platform for AI that needs to act at the right moment.**
>
> Bitemporal memory at its foundation. Live observability through a control plane that traces every fact, every action, every decision. Local-first. JSONL canonical, SQLite derived. MIT.
>
> *Most systems store what is true. Kalairos stores what was true when decisions were made — and shows you why your agent acted on it.*

---

## The problem nobody talks about

Your agent stores a fact. The fact changes. Now you're stuck.

```js
await memory.remember('Employees must submit reports by Friday');
// ...two weeks later, policy changes...
await memory.remember('Deadline changed to Wednesday');
```

A user gets penalized for missing Wednesday's deadline.
They protest: *"I followed the rule. Why was I punished?"*

Your system shrugs. It only knows the **latest** rule. The old one is gone.

> Every vector DB has this bug. They overwrite. Or they duplicate and confuse retrieval. Either way, **history disappears.**

This is not a niche problem. It is every:

- **Policy change** that gets applied retroactively
- **Pricing dispute** where a customer signed up at the old rate
- **Compliance audit** asking *"what was your retention rule on March 12?"*
- **Code review** flagging old code against new rules
- **AI assistant** that contradicts itself because user preferences shifted

If your agent can't answer *"what did we believe at the time?"*, it cannot be trusted to make decisions that outlive a single session.

---

## The fix, in one call

```js
await kalairos.remember('Employees must submit reports by Friday');
await kalairos.remember('Deadline changed to Wednesday');

// Today
await kalairos.query('report deadline');
// → "Deadline changed to Wednesday"

// What was true last week?
await kalairos.queryAt('report deadline', lastWeek);
// → "Employees must submit reports by Friday"
```

That's it. Same memory. Two answers. Both correct — for their moment in time.

**Without Kalairos:** the system only knows the latest rule. The user looks wrong.
**With Kalairos:** the system knows what was true *then*. The user can prove they were right.

---

## Why this matters

For a hobby agent, losing history is an annoyance. For an agent that touches **legal, medical, financial, or HR decisions**, it's disqualifying:

- A compliance reviewer doesn't ask what your policy *is* — they ask what it was **on the date of the event**, and how you know.
- An agent that acted on a fact must be able to show **where that fact came from**, who wrote it, and how much it was trusted at the time.
- When a stored fact changes or contradicts an earlier one, someone has to **see the conflict** — silent overwrites are how agents get poisoned and how audits get failed.

Kalairos makes those properties structural, not bolted on. Every returned fact carries its **event time, ingest time, version id, provenance chain, data classification, and an explainable trust score**. Every mutation lands in a read-only **audit trail** (`trail()`), and any moment can be frozen as a named **checkpoint**. If your agent has to survive the question *"why did it do that, and what did it know at the time?"* — that's the platform's job, and this is the platform.

---

## Install

```bash
npm install kalairos
```

Local-first. No cloud service. No API key required. Bring any embedder. JSONL on disk — human-readable, git-friendly, easy to back up.

```bash
npx kalairos demo    # interactive demo, zero config
```

---

## Layer 1 — Three calls and you're done

`init`, `remember`, `query`. Most agents need nothing more.

```js
const kalairos = require('kalairos');
const embed = async (t) => [...t].map(c => c.charCodeAt(0) / 255); // toy embedder

await kalairos.init({ embedFn: embed });

await kalairos.remember('User prefers concise bullet points');
await kalairos.remember('Customer is on the $10/month plan');

const { results } = await kalairos.query('what plan are they on?');
console.log(results[0].text);
```

Swap the toy embedder for OpenAI, Cohere, or any `async (text) => number[]` when you're ready.

---

## Layer 2 — Time-aware memory

Once the basic loop makes sense, time-travel is one call away. `remember()` detects updates automatically and appends a new version. `queryAt(text, timestamp)` recalls whichever version was current at that moment. `getHistory(id)` returns the full trail.

```js
const id = await kalairos.remember('Subscription price is $10/month');

// ...later, pricing changes...
await kalairos.remember('Subscription price increased to $20/month');

// Current state
const now = await kalairos.query('subscription price');
console.log(now.results[0].text);     // → "$20/month"

// What did we charge this customer when they signed up?
const signupDate = new Date('2025-03-01').getTime();
const past = await kalairos.queryAt('subscription price', signupDate);
console.log(past.results[0].text);    // → "$10/month"

// Full version history with deltas and provenance
const history = await kalairos.getHistory(id);
history.versions.forEach(v => console.log(`v${v.version}: ${v.text}`));
```

One entity, many versions. Every query picks the version current at its chosen moment.

```mermaid
flowchart LR
    subgraph Entity["Entity #42 &mdash; 'Subscription price'"]
        direction LR
        v1["v1'$10/month'Jan 15"]
        v2["v2'$15/month'Feb 20"]
        v3["v3'$20/month'Mar 10 &larr; current"]
        v1 --> v2 --> v3
    end

    Q1["query('price')today"]              -.->|returns| v3
    Q2["queryAt('price', Feb 25)"]                     -.->|returns| v2
    Q3["queryAt('price', Jan 20)"]                     -.->|returns| v1
    Q4["getHistory(42)"]                               -.->|returns| Entity

    classDef current fill:#d4edda,stroke:#28a745,color:#155724
    classDef past    fill:#fff3cd,stroke:#ffc107,color:#856404
    classDef old     fill:#f8d7da,stroke:#dc3545,color:#721c24
    class v3 current
    class v2 past
    class v1 old
```

Versions are **linear per entity** — each new version supersedes the previous; there is no branching. The "fork" effect happens *across* entities: when a `remember()` falls below the similarity threshold, it creates a new entity instead of a new version. Linearity is what keeps `queryAt(t)` well-defined: there is always one unambiguous answer to *"what did we believe about entity X at time T."*

---

## Every change leaves a breadcrumb. Important moments become checkpoints.

Every `remember()` writes a trail event with `who` did it, `why`, when it became *effective*, and when it was *ingested*. Nothing extra to call. The trail is read-only and pure — `trail()` projects it from data already on disk.

```js
const policy = kalairos.scope({ source: { type: "agent", actor: "policy-bot" } });

await policy.remember("Employees must submit reports by Friday");
await policy.remember("Deadline changed to Wednesday", {
  why:         "Policy update from HR memo",
  effectiveAt: "2026-04-15",
});

const events = await kalairos.trail({ action: ["remembered", "superseded"] });
// → [{ action: "remembered", who: { agent: "policy-bot" }, ingestAt, effectiveAt, ... },
//    { action: "superseded", who: { agent: "policy-bot" }, why: "Policy update from HR memo", ... }]
```

Each event is one of a closed set: `remembered`, `superseded`, `corrected`, `contested`, `reaffirmed`, `forgotten`, `restored`, `imported`, `annotated`. Switch on it without guessing.

When a moment matters — quarter close, audit cut, model ship — name it:

```js
await kalairos.checkpoint("q1-close", {
  during: ["2026-01-01", "2026-04-01"],
  why:    "Q1 audit reference",
});

const q1 = await kalairos.trail({ checkpoint: "q1-close" });
const lastWeek = Date.now() - 7 * 86_400_000;
const past     = await kalairos.queryAt("report deadline", lastWeek);
```

Checkpoints are frozen by default — backdated writes do not silently join them. Pass `live: true` if you want the filter to re-evaluate on every read.

---

## Where this earns its keep

| Scenario | The pain | What `queryAt` proves |
|---|---|---|
| **Policy change** | "I was penalized for breaking a rule that didn't exist when I acted." | The rule that applied on the date of the action. |
| **Pricing dispute** | "I signed up at $10. Why am I being charged $20?" | The price at the moment of signup. |
| **Compliance audit** | "What was your data retention policy on March 12?" | The policy as it stood on March 12. |
| **Engineering review** | Old code flagged against rules that didn't exist when it was written. | The rule as it was when the code was committed. |
| **Drifting AI agent** | Assistant flips between contradictory user preferences with no record of why. | The preference at any past turn — and the full trail of changes. |

If your product makes promises that outlive the moment, you need memory that does too.

---

## A compliance audit, end to end

The scenarios above, as one runnable script. A policy pipeline records a regulated retention rule; the regulation changes; an auditor asks about a date in between. Provenance, classification, contradiction flagging, human review, audit trail, and a frozen checkpoint — all against the same store the 3-call quickstart uses.

```js
const kalairos = require('kalairos');

async function main() {
  const embed = async (t) => [...t].map(c => c.charCodeAt(0) / 255).slice(0, 64); // toy embedder
  await kalairos.init({ embedFn: embed, dataFile: ':memory:' });

  // Every write from this pipeline carries provenance + data classification.
  const policy = kalairos.scope({
    source: { type: 'agent', actor: 'policy-sync' },
    classification: 'regulated',
    tags: ['retention-policy'],
  });

  // January: the policy on the books.
  const id = await policy.remember('Customer records are retained for 5 years', {
    timestamp: new Date('2026-01-05').getTime(),
  });

  // April: the regulation changes. Same entity, new version — the old rule is not gone.
  await policy.remember('Customer records are retained for 7 years', {
    timestamp: new Date('2026-04-01').getTime(),
    why: 'Reg update 2026-113',
    effectiveAt: '2026-04-01',
  });

  // The auditor asks: "What was your retention rule on March 12?"
  const march12 = new Date('2026-03-12').getTime();
  const audit = await kalairos.queryAt('customer record retention rule', march12);
  console.log(audit.results[0].text);
  // → "Customer records are retained for 5 years"

  // Today's answer comes with explainable trust — the change was flagged, not silently absorbed.
  const today = await kalairos.query('customer record retention rule');
  console.log(today.results[0].text);
  console.log(today.results[0].trustBreakdown.formula);
  // → "Customer records are retained for 7 years"
  // → "Trust 0.30 = base 0.75 -0.16 contradictions ×0.50 recency"

  // A human reviews the flagged change and confirms it — on the record.
  await kalairos.annotate(id, {
    trustScore: 0.9,
    verified: true,
    notes: 'Confirmed against Reg update 2026-113 by compliance review',
  });

  // Evidence, not assertion: who changed what, when, and why.
  const events = await kalairos.trail({ entity: id });
  events.forEach(e => console.log(e.action, e.who, e.why ?? ''));
  // → remembered { agent: 'policy-sync' }
  // → superseded { agent: 'policy-sync' } Reg update 2026-113
  // → contested  { agent: 'policy-sync' } Reg update 2026-113
  // → annotated  ...

  // Freeze the audit window: reviewers see the same slice forever.
  await kalairos.checkpoint('fy26-q1-audit', {
    during: ['2026-01-01', '2026-04-01'],
    why: 'Q1 retention audit reference',
  });
  const q1 = await kalairos.trail({ checkpoint: 'fy26-q1-audit' });
  console.log(`${q1.length} events in the frozen Q1 window`);

  await kalairos.shutdown();
}

main().catch(e => { console.error(e); process.exit(1); });
```

Note the trust formula: the 5-year → 7-year change **contradicts** the prior version, so Kalairos flags it and cuts trust until a human confirms it. That's deliberate — a policy that changes without anyone noticing is exactly the failure mode a regulated deployment cannot have.

---

## Layer 3 — Advanced maintenance

Reach for these only when you need them. The 3-function path covers most agents.

### Trust and annotations

Every query result includes a `trust` score and a `source` provenance chain. Annotate an entity with trust signals without creating a new content version:

```js
await kalairos.annotate(id, { trustScore: 0.9, verified: true, notes: 'confirmed by finance' });
```

### Consolidation

Merge near-duplicate memories into a single entity. Useful at the end of long sessions.

```js
const { merged, totalMerged } = await kalairos.consolidate({ threshold: 0.9 });
```

### Contradiction inspection

When a new version contradicts a prior one, the delta is flagged. Surface the conflict instead of silently overwriting:

```js
const { contradictions } = await kalairos.getContradictions(id);
contradictions.forEach(v => console.log(`v${v.versionId}: ${v.delta.summary}`));
```

### Provenance defaults with `scope()`

If every write from one part of your agent shares the same source / classification / tags, `scope()` pre-fills them so you don't pass them every call. Reads behave exactly like the flat API.

```js
const support = kalairos.scope({
  source: { type: 'agent', actor: 'support-bot' },
  classification: 'confidential',
  tags: ['support'],
});

await support.remember('Customer reports checkout is broken on mobile');
const { results } = await support.query('checkout');
```

`scope()` is optional sugar. Everything it does is expressible with the flat API.

---

## What Kalairos gives you

|                                | Plain vector store     | Kalairos                             |
| ------------------------------ | ---------------------- | ------------------------------------ |
| **Updates**                    | Overwrite or duplicate | Automatic versioning                 |
| **History**                    | None                   | Full version trail with deltas       |
| **"What was true on Jan 15?"** | Can't answer           | `queryAt` any timestamp              |
| **Contradictions**             | Invisible              | Auto-detected between versions       |
| **Provenance**                 | Not tracked            | Who stored it, when, from where      |
| **Retrieval**                  | Cosine similarity      | Semantic + graph + keyword + recency |
| **Deployment**                 | Cloud SDK              | Local-first, zero cloud dependency   |
| **Embedding model**            | Bundled or locked in   | BYO — any provider, any model        |

---

## API stability

Kalairos follows semver. Within the `1.x` line, the signatures of **`init`, `remember`, `query`, `queryAt`, `getHistory`** are **frozen**. Additive fields land in minor releases; any breaking change bumps the major version. Deprecated APIs emit warnings for at least two minor versions before removal.

---

## Benchmarks

All numbers reproducible on any machine — deterministic bag-of-words embedder, no API key needed. Last full run: **2026-07-02** (M-series macOS, Node v23.7.0); the dated snapshot lives in [bench/RESULTS.md](bench/RESULTS.md).

| Metric                      | Score                            | What it measures                                      |
| --------------------------- | -------------------------------- | ----------------------------------------------------- |
| **Recall@5**                | 75% (finance), 50% (engineering) | Fraction of relevant items in top-5 results           |
| **Precision@3**             | 100% (health)

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [LabsKrishna](https://github.com/LabsKrishna)
- **Source:** [LabsKrishna/kalairos](https://github.com/LabsKrishna/kalairos)
- **License:** MIT
- **Homepage:** https://krishnalabs.ai

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-labskrishna-kalairos
- Seller: https://agentstack.voostack.com/s/labskrishna
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
