AgentStack
MCP verified MIT Self-run

Kalairos

mcp-labskrishna-kalairos · by LabsKrishna

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

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add mcp-labskrishna-kalairos

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Kalairos? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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.

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

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

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.

npx kalairos demo    # interactive demo, zero config

Layer 1 — Three calls and you're done

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

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.

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.

flowchart LR
    subgraph Entity["Entity #42 — 'Subscription price'"]
        direction LR
        v1["v1'$10/month'Jan 15"]
        v2["v2'$15/month'Feb 20"]
        v3["v3'$20/month'Mar 10 ← 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.

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:

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.

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:

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.

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:

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.

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.

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

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.