Documentation

Everything you need to give your AI agents persistent memory.

Install

Python

pip install sulcus

# With async support:
pip install sulcus[async]
bash

Python 3.9+ · Zero dependencies · Async via optional httpx

Node.js

npm install sulcus
bash

Node 18+ · Zero dependencies · Full TypeScript support

Quick Start

Python

from sulcus import Sulcus

client = Sulcus(api_key="sk-...")

# Store memories
client.remember("User prefers dark mode", memory_type="preference")
client.remember("API rate limit is 1000/min", memory_type="semantic")

# Search
results = client.search("dark mode")
for m in results:
    print(f"[{m.memory_type}] {m.pointer_summary} (heat: {m.current_heat:.2f}")

# List with filters
memories = client.list(page=1, page_size=10, memory_type="preference")

# Pin important memories (prevents heat decay)
client.pin(memories[0].id)

# Update
client.update(memories[0].id, label="Updated content")

# Delete
client.forget(memories[0].id)
python

Node.js / TypeScript

import { Sulcus } from "sulcus";

const client = new Sulcus({ apiKey: "sk-..." });

// Store memories
await client.remember("User prefers dark mode", { memoryType: "preference" });
await client.remember("API rate limit is 1000/min", { memoryType: "semantic" });

// Search
const results = await client.search("dark mode");
for (const m of results) {
  console.log(`[${m.memory_type}] ${m.pointer_summary} (heat: ${m.current_heat.toFixed(2)})`);
}

// List with filters
const memories = await client.list({ page: 1, pageSize: 10, memoryType: "preference" });

// Pin important memories (prevents heat decay)
await client.pin(memories[0].id);

// Update
await client.update(memories[0].id, { label: "Updated content" });

// Delete
await client.forget(memories[0].id);
typescript

Python Async

import asyncio
from sulcus import AsyncSulcus

async def main():
    async with AsyncSulcus(api_key="sk-...") as client:
        await client.remember("async memory", memory_type="semantic")
        results = await client.search("async")
        print(results)

asyncio.run(main())
python

Memory Types

episodicDecay: Fast

Events, conversations, time-bound experiences

"Met with design team, decided on blue theme"

semanticDecay: Slow

Facts, knowledge, definitions

"Python 3.12 requires typing_extensions >= 4.0"

preferenceDecay: Medium

User preferences, settings, opinions

"User prefers dark mode and monospace fonts"

proceduralDecay: Slow

How-to knowledge, workflows, recipes

"To deploy: git push, then az acr build, then update app"

MCP Integration

Sulcus speaks MCP (Model Context Protocol) natively. Connect any MCP-compatible client — Claude Desktop, OpenAI agents, custom hosts — directly to your memory graph.

# Claude Desktop — add to claude_desktop_config.json:
{
  "mcpServers": {
    "sulcus": {
      "url": "https://server.sulcus.dforge.ca/mcp",
      "transport": "streamable-http",
      "headers": {
        "Authorization": "Bearer sk-your-api-key"
      }
    }
  }
}
json

29 MCP tools available: search_memory, commit_memory, record_memory, build_context, list_hot_nodes, tick, prune_cold_memories, forget_memory, page_in, compact_wal, sync_now, create_trigger, list_triggers, update_trigger, delete_trigger, trigger_history, and more.

Reactive Triggers

Set rules on your memory graph. When events happen — a memory is stored, recalled, boosted, or decays — Sulcus fires actions automatically. No competitor has this. Triggers run server-side and locally, fire during MCP tool calls, and surface notifications inline.

on_store

New memory created

on_recall

Memory searched/recalled

on_boost

Memory heat increased

on_relate

Edge created between memories

on_decay

Heat dropped during tick

on_threshold

Heat crosses boundary

pin
boost
tag
deprecate
notify
webhook
chain (v2)

Python

# Reactive Triggers — automate memory lifecycle
from sulcus import Sulcus

client = Sulcus(api_key="sk-...")

# Auto-pin every preference memory
client.create_trigger(
    event="on_store",
    action="pin",
    name="auto-pin-preferences",
    filter_memory_type="preference"
)

# Boost memories every time they're recalled (spaced repetition)
client.create_trigger(
    event="on_recall",
    action="boost",
    name="reinforce-on-recall",
    action_config={"strength": 0.15}
)

# Webhook when critical memory starts cooling
client.create_trigger(
    event="on_threshold",
    action="webhook",
    name="alert-cold-procedures",
    filter_memory_type="procedural",
    filter_heat_below=0.3,
    action_config={"url": "https://hooks.slack.com/your-webhook"}
)

# List active triggers
triggers = client.list_triggers()
for t in triggers:
    print(f"{t['name']}: {t['event']} → {t['action']} (fired {t['fire_count']}x)")
python

Node.js

import { Sulcus } from "sulcus";

const client = new Sulcus({ apiKey: "sk-..." });

// Auto-pin every preference memory
await client.createTrigger("on_store", "pin", {
  name: "auto-pin-preferences",
  filterMemoryType: "preference",
});

// Boost memories every time they're recalled
await client.createTrigger("on_recall", "boost", {
  name: "reinforce-on-recall",
  actionConfig: { strength: 0.15 },
});

// Webhook when critical memory starts cooling
await client.createTrigger("on_threshold", "webhook", {
  name: "alert-cold-procedures",
  filterMemoryType: "procedural",
  filterHeatBelow: 0.3,
  actionConfig: { url: "https://hooks.slack.com/your-webhook" },
});

// Check trigger history
const history = await client.triggerHistory();
for (const h of history) {
  console.log(`${h.event} → ${h.action} at ${h.fired_at}`);
}
typescript

REST API

# Create a trigger
curl -X POST https://server.sulcus.dforge.ca/api/v1/triggers \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "auto-pin-preferences",
    "event": "on_store",
    "action": "pin",
    "filter_memory_type": "preference"
  }'

# List triggers
curl https://server.sulcus.dforge.ca/api/v1/triggers \
  -H "Authorization: Bearer sk-..."

# Delete a trigger
curl -X DELETE https://server.sulcus.dforge.ca/api/v1/triggers/{id} \
  -H "Authorization: Bearer sk-..."
bash

REST API

Base URL: https://server.sulcus.dforge.ca
Authentication: Authorization: Bearer <api-key>

POST/api/v1/agent/nodesCreate a memory node
GET/api/v1/agent/nodesList memories (paginated)
GET/api/v1/agent/nodes/:idGet a single memory
PATCH/api/v1/agent/nodes/:idUpdate a memory
DELETE/api/v1/agent/nodes/:idDelete a memory
POST/api/v1/agent/searchText search memories
GET/api/v1/agent/hot_nodesList hottest memories
POST/api/v1/agent/syncCRDT sync (push/pull ops)
GET/api/v1/metricsStorage & health metrics
GET/api/v1/orgTenant/org info & limits
GET/api/v1/keysList API keys
POST/api/v1/keysGenerate new API key
GET/api/v1/settings/thermoGet thermodynamic engine config
PATCH/api/v1/settings/thermoUpdate thermodynamic engine config
POST/api/v1/feedbackRecall quality feedback (relevant/irrelevant/outdated)
GET/api/v1/analytics/recallRecall analytics with tuning suggestions
GET/api/v1/triggersList active triggers
POST/api/v1/triggersCreate a reactive trigger
PATCH/api/v1/triggers/:idUpdate a trigger
DELETE/api/v1/triggers/:idDelete a trigger
GET/api/v1/triggers/historyTrigger firing history
POST/mcpMCP Streamable HTTP (JSON-RPC)
GET/mcpMCP SSE notification stream

Examples

# Create a memory
curl -X POST https://server.sulcus.dforge.ca/api/v1/agent/nodes \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"label": "User prefers dark mode", "memory_type": "preference"}'

# Search memories
curl -X POST https://server.sulcus.dforge.ca/api/v1/agent/search \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"query": "dark mode", "limit": 10}'

# List memories
curl https://server.sulcus.dforge.ca/api/v1/agent/nodes?page=1&page_size=10 \
  -H "Authorization: Bearer sk-..."
bash

Self-Hosted

Point any SDK at your own server. The entire stack — server, database, sync — runs on your infrastructure.

# Python
client = Sulcus(api_key="your-key", base_url="http://localhost:4200")

# Node.js
const client = new Sulcus({ apiKey: "your-key", baseUrl: "http://localhost:4200" });
python

Framework Integrations

Dedicated packages for popular LLM frameworks. Each wraps the Sulcus API with framework-native abstractions.

LangChainpip install sulcus-langchain
LlamaIndexpip install sulcus-llamaindex
Vercel AI SDKnpm install sulcus-vercel-ai
OpenAI ToolsCopy tools.json
Anthropic ToolsCopy tools.json
CrewAIpip install sulcus-crewai
Deep Agentspip install sulcus-deepagents
CLInpm install -g sulcus-cli
OpenClawopenclaw plugins install
VS CodeMarketplace (coming)

Source code for all integrations: github.com/digitalforgeca/sulcus/integrations

Resources