name: openloomi-memory description: "openloomi Memory tools - search memory files, knowledge base, and chat insights. Triggers: memory search, knowledge base, documents, insights" metadata: version: 0.5.1 allowed-tools: Bash(node $SKILL_DIR/scripts/openloomi-memory.cjs *)
Note: If you haven't downloaded or installed openloomi yet, please refer to Getting Started for installation instructions.
OpenLoomi Memory Skill
OpenLoomi Memory is a personal knowledge management tool that searches and manages three types of information:
| Type | Description | Data Location |
|---|---|---|
| Memory Files | Personal memory files (markdown/json) | ~/.openloomi/data/memory/ |
| Knowledge Base | Uploaded documents via RAG/embeddings | openloomi server |
| Insights | Structured info extracted from chat history, with usage tracking and automatic maintenance | openloomi server |
Overview
openloomi Memory is built on a unique architectural principle: instead of treating memory as an afterthought, it's the foundation.
How it works with Connectors: Before memory can search your data, you need to connect your platforms using the openloomi-connectors skill. Connectors handles OAuth authentication and integration setup for 26 platforms (Telegram, WhatsApp, Slack, Discord, Gmail, Outlook, Twitter/X, WeChat, and more). Once connected, openloomi continuously syncs everything with your permission—raw messages, meetings, emails, tweets, calendar events, voice calls, and any notes or ideas you've captured. This aggregated data becomes the single source of truth that powers openloomi's brain.
The memory is layered:
- Raw information: Original messages, files, transcripts
- Information insights: Extracted entities, decisions, key events
- Contextual memory: Recent conversation state
- Knowledge-base memory: Long-term people/projects/preferences knowledge graph
This enables reasoning across both immediate context and deep historical knowledge simultaneously. When you create custom agent roles to handle tasks, this memory acts as the orchestrator—dramatically improving execution quality.
Inside openloomi, memory is layered into multiple levels:
- Raw information: Original messages, files, transcripts
- Information insights: Extracted entities, decisions, key events
- Contextual memory: Recent conversation state
- Knowledge-base memory: Long-term people/projects/preferences knowledge graph
This enables reasoning across both immediate context and deep historical knowledge simultaneously.
Insights include automatic usage tracking—recording view frequency, sources, and calculating value scores to surface the most relevant information. A periodic maintenance system (daily analytics refresh, weekly compaction) keeps insight retrieval accurate and prevents context decay by archiving or removing stale, low-value content.
Authentication
The CLI auto-reads your token from ~/.openloomi/token (base64 encoded JWT).
Local Memory Filesystem
Overview
Memory files are stored locally at ~/.openloomi/data/memory/ and searched via direct filesystem access. This is a read-only operation that performs case-insensitive text search across .md and .json files.
Directory Structure
~/.openloomi/data/memory/
├── chats/ # Chat conversation exports
├── channels/ # Channel memory exports e.g., weixin, telegram, etc.
├── people/ # Person profiles
├── projects/ # Project notes
├── notes/ # General notes
└── strategy/ # Strategy documents
Write Operations
Memory files are plain markdown or JSON stored locally. You can add or delete files directly.
Adding a memory file:
node $SKILL_DIR/scripts/openloomi-memory.cjs add-memory "Content to remember" --file=filename.md --directory=notes
--file(optional): Filename. If not provided, auto-generated from first line of content.--directory(optional): Subdirectory under~/.openloomi/data/memory/. Created if doesn't exist.
Deleting a memory file:
node $SKILL_DIR/scripts/openloomi-memory.cjs delete-memory filename.md --directory=notes
How search-memory Works
- Path:
~/.openloomi/data/memory/(or subdirectory if specified) - Search Type: Case-insensitive full-text search
- Files: Scans
.mdand.jsonfiles recursively (max depth 5) - Matching: Each line is searched; returns first match per file
- Output: File path, line number, and line preview (first 200 chars)
Example Output
{
"results": [
{
"file": "people/boss.md",
"line": 42,
"preview": "My boss John mentioned the deadline is next Friday"
},
{
"file": "projects/app/notes.md",
"line": 10,
"preview": "Boss wants the app launched by end of month"
}
],
"total": 2
}
API Endpoints
Knowledge Base (RAG)
POST /api/rag/search - Search Documents
Semantic search of uploaded documents using embeddings.
curl -X POST http://localhost:3414/api/rag/search \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "project plan", "limit": 5}'
Parameters:
query(string, required) - Search querylimit(number, default 5) - Max results to return
Response:
{
"results": [
{
"id": "doc_xxx",
"title": "Project Document",
"content": "...",
"score": 0.95
}
]
}
GET /api/rag/documents - List Documents
List all documents in the knowledge base.
curl http://localhost:3414/api/rag/documents?limit=50 \
-H "Authorization: Bearer $TOKEN"
Parameters:
limit(number, default 50) - Max results to return
Response:
{
"documents": [
{
"id": "doc_xxx",
"name": "document.pdf",
"type": "pdf",
"size": 102400,
"createdAt": "2024-01-01T00:00:00Z"
}
],
"total": 10
}
GET /api/rag/documents/[id] - Get Document
Get a single document by ID.
curl http://localhost:3414/api/rag/documents/doc_xxx \
-H "Authorization: Bearer $TOKEN"
Response:
{
"id": "doc_xxx",
"name": "Project Document.pdf",
"type": "pdf",
"size": 102400,
"content": "Document text content...",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z"
}
Insights
Insights are structured information extracted from chat history, such as key decisions, action items, and relationship notes. Each insight belongs to one or more groups (channels/platforms) like gmail, telegram, whatsapp, slack, discord, linkedin, twitter, etc.
GET /api/insights - List Insights
List all insights from a time period.
curl "http://localhost:3414/api/insights?days=7&limit=50" \
-H "Authorization: Bearer $TOKEN"
Parameters:
days(number, default 7) - Look back period in dayslimit(number, default 50) - Max results to return
Insight Structure:
Each insight contains a groups field—an array of channel identifiers indicating which platform(s) the insight came from:
{
"id": "insight_xxx",
"chatId": "chat_xxx",
"type": "decision",
"content": "John sent an email about the project deadline",
"groups": ["gmail"],
"people": ["John"],
"time": "2024-01-01T00:00:00Z",
"createdAt": "2024-01-01T00:00:00Z"
}
Insight Types:
| Type | Description |
|---|---|
decision |
Key decisions made |
action_item |
Tasks or follow-ups |
note |
General notes |
preference |
User preferences |
relationship |
Notes about people |
event |
Important events |
Common Channel Groups:
| Channel | Group Value | Description |
|---|---|---|
| Gmail | "gmail" |
Google Mail messages |
| Outlook | "outlook" |
Microsoft Outlook emails |
| Telegram | "telegram" |
Telegram chats |
"whatsapp" |
WhatsApp messages | |
| Slack | "slack" |
Slack messages |
| Discord | "discord" |
Discord messages |
"linkedin" |
LinkedIn messages | |
| Twitter/X | "twitter" |
Twitter posts |
"weixin" |
WeChat messages | |
| RSS | "rss" |
RSS feed items |
POST /api/insights - Create Insight
Create a new insight manually.
curl -X POST http://localhost:3414/api/insights \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "preference", "content": "I prefer Americano coffee", "groups": ["whatsapp"]}'
Parameters:
type(string, required) - Insight type (decision, action_item, note, preference, relationship, event)content(string, required) - The insight textgroups(array, optional) - Channel groups to associate withpeople(array, optional) - People mentioned in the insight
Response:
{
"id": "insight_xxx",
"type": "preference",
"content": "I prefer Americano coffee",
"groups": ["whatsapp"],
"createdAt": "2024-01-01T00:00:00Z"
}
PUT /api/insights/[id] - Update Insight
Partial update an existing insight. Arrays (details, timeline, insights) are appended to, not replaced.
curl -X PUT http://localhost:3414/api/insights/insight_xxx \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"updates": {
"description": "Updated description",
"details": [{"content": "User mentioned new preference", "person": "User"}],
"timeline": [{"summary": "Progress update", "label": "Update"}]
}
}'
Update Fields:
title- New titledescription- New descriptionimportance- Important, General, Not Importanturgency- As soon as possible, Within 24 hours, Not urgent, Generaldetails- Array of detail objects (appended to existing)timeline- Array of timeline events (appended to existing)myTasks- Array of task objectsgroups- Array of group tags (replaced)categories- Array of categories (replaced)people- Array of people names (replaced)
Response:
{
"message": "Insight updated successfully",
"id": "insight_xxx"
}
GET /api/insights/[id]?fetch=true - Get Insight
Get a single insight by ID, including associated chat.
curl "http://localhost:3414/api/insights/insight_xxx?fetch=true" \
-H "Authorization: Bearer $TOKEN"
Response:
{
"id": "insight_xxx",
"chatId": "chat_xxx",
"type": "decision",
"content": "User decided to start new project next month",
"chat": {
"id": "chat_xxx",
"title": "Chat with John",
"messages": [...]
},
"createdAt": "2024-01-01T00:00:00Z"
}
DELETE /api/insights/[id] - Delete Insight
Delete a specific insight.
curl -X DELETE http://localhost:3414/api/insights/insight_xxx \
-H "Authorization: Bearer $TOKEN"
Response:
{
"success": true
}
GET /api/chat-insights?chatId=xxx - Get Chat Insights
Get all insights for a specific chat.
curl "http://localhost:3414/api/chat-insights?chatId=chat_xxx" \
-H "Authorization: Bearer $TOKEN"
Insight Usage Analytics & Maintenance
openloomi tracks insight usage and performs periodic maintenance to preserve retrieval quality, avoiding context decay.
Usage Tracking
Each insight view is recorded with:
- Access timestamp
- Access source (
list,detail,search,favorite) - Cumulative access counts (7-day / 30-day / total)
Data is stored in the insightWeights table:
accessCountTotal- Total access countaccessCount7d- Access count in last 7 daysaccessCount30d- Access count in last 30 dayslastAccessedAt- Last access timestamp
Analysis Dimensions
Each insight is scored on trend and value:
| Metric | Weight | Description |
|---|---|---|
| Frequency | 45% | Based on 7-day / 30-day access frequency |
| Freshness | 25% | Last access time |
| Relevance | 20% | Importance (70%) + Urgency (30%) |
| Favorites | 10% | Whether the insight is favorited |
Trend Indicators:
rising- Access frequency increasingfalling- Access frequency decreasingstable- Frequency stable
Periodic Maintenance
System automatically runs two maintenance tasks:
| Task | Frequency | Purpose |
|---|---|---|
| Daily analytics refresh | 24 hours | Refresh access stats, recalculate trends and scores |
| Weekly compaction | 7 days | Merge similar insights, prune low-value content |
Retention Policy:
delete: 90 days no access + low score + not high importance → soft delete, hard delete after 180 daysarchive: 30 days no access + low score OR falling trend + low score → archived
GET /api/insights/analytics - Get Insight Usage Analytics
curl "http://localhost:3414/api/insights/analytics" \
-H "Authorization: Bearer $TOKEN"
Response:
{
"generatedAt": "2024-01-15T10:30:00Z",
"summary": {
"totalInsights": 150,
"activeInsights": 45,
"dormantInsights": 105,
"totalAccesses30d": 230,
"averageValueScore": 42,
"risingInsights": 12,
"fallingInsights": 8,
"stableInsights": 25
},
"topInsights": [...],
"bottomInsights": [...],
"relationships": [...],
"insights": [
{
"id": "insight_xxx",
"title": "User decided to start new project",
"description": "",
"taskLabel": "",
"platform": "gmail",
"account": "user@gmail.com",
"importance": "general",
"urgency": "not_urgent",
"isFavorited": false,
"isArchived": false,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-10T00:00:00Z",
"time": "2024-01-01T00:00:00Z",
"accessCountTotal": 15,
"accessCount7d": 3,
"accessCount30d": 8,
"lastAccessedAt": "2024-01-15T10:30:00Z",
"trend": "rising",
"recent7dAccessCount": 3,
"previous7dAccessCount": 1,
"valueScore": 58,
"recommendation": {
"action": "keep",
"reason": "Usage, freshness, or relevance still supports keeping it active."
}
}
]
}
POST /api/insights/[id]/view - Record Insight View
curl -X POST "http://localhost:3414/api/insights/insight_xxx/view" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"viewSource": "search"}'
Parameters:
viewSource(string) - Source type:list,detail,search,favorite
Response:
{
"ok": true
}
CLI Script
Quick Start
# Search ALL memory sources at once (recommended for comprehensive search)
node $SKILL_DIR/scripts/openloomi-memory.cjs search-all "query"
# Search local memory files (full-text, case-insensitive)
node $SKILL_DIR/scripts/openloomi-memory.cjs search-memory "boss"
# Search local memory files in specific subdirectory
node $SKILL_DIR/scripts/openloomi-memory.cjs search-memory "project" --directory=projects
# Search knowledge base (RAG, semantic search)
node $SKILL_DIR/scripts/openloomi-memory.cjs search-knowledge "project plan"
# List knowledge base documents
node $SKILL_DIR/scripts/openloomi-memory.cjs list-documents
# Get document content
node $SKILL_DIR/scripts/openloomi-memory.cjs get-document doc_xxx
# List recent insights (last 7 days)
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --days=7
# List insights from a specific channel (e.g., Gmail, Telegram, WhatsApp)
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=gmail --days=7
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=telegram --days=30
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=whatsapp
# Filter insights by keyword (supports multiple keywords - OR logic)
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --keyword=screen --keyword=linkedin --days=30
# Get single insight
node $SKILL_DIR/scripts/openloomi-memory.cjs get-insight insight_xxx
# Create a new insight
node $SKILL_DIR/scripts/openloomi-memory.cjs add-insight --title="Coffee preference" --description="I prefer Americano coffee" --importance=General
# Update an insight (partial update with array append)
node $SKILL_DIR/scripts/openloomi-memory.cjs update-insight insight_xxx --description="Updated description" --detail="User mentioned new preference"
# Delete insight
node $SKILL_DIR/scripts/openloomi-memory.cjs delete-insight insight_xxx
# Add a memory file
node $SKILL_DIR/scripts/openloomi-memory.cjs add-memory "My boss John likes Monday project discussions" --file=people/boss.md
# Delete a memory file
node $SKILL_DIR/scripts/openloomi-memory.cjs delete-memory people/boss.md
Command Reference
| Command | Description | Target |
|---|---|---|
search-all |
Search all memory sources simultaneously | Local files + Knowledge base + Insights |
search-memory |
Full-text search in local .md/.json files |
~/.openloomi/data/memory/ |
search-knowledge |
Semantic search via embeddings | openloomi server (RAG) |
list-documents |
List uploaded documents | Knowledge base |
get-document |
Get document content by ID | Knowledge base |
list-insights |
List extracted insights (supports --channel filter) |
Insights API |
get-insight |
Get single insight by ID | Insights API |
delete-insight |
Delete an insight | Insights API |
add-insight |
Create a new insight (title, description, importance, urgency, groups, people) | Insights API |
update-insight |
Update an insight (partial update with array append logic) | Insights API |
add-memory |
Add a memory file (auto-generates filename from content) | Local filesystem |
delete-memory |
Delete a memory file | Local filesystem |
AI Agent Workflow
Triggered when the user asks about memory, knowledge, or past information:
- Memory file search - "search my memory", "find what I said about..."
- Knowledge base search - "search uploaded documents", "find in knowledge base"
- Insights management - "list insights", "delete an insight"
- Channel insights - "what messages on Gmail?", "show me Telegram chats", "any WhatsApp messages?"
- Comprehensive search - "search everything", "find in all my memory", "build relationship graph"
Execution Flow:
- Identify intent - determine if user wants comprehensive search or specific source
- Prefer
search-all- for general memory queries, always usesearch-allfirst to get comprehensive results across all sources - Execute in parallel - when specific sources are needed, run multiple searches simultaneously:
search-memoryfor local filessearch-knowledgefor uploaded documentslist-insightsfor extracted insights
- For channel queries - use
list-insightswith--channelparameter:"gmail"- Email messages via Gmail"outlook"- Email messages via Outlook"telegram"- Telegram chats"whatsapp"- WhatsApp messages"slack"- Slack messages"discord"- Discord messages"linkedin"- LinkedIn messages"twitter"- Twitter/X posts"weixin"- WeChat messages"rss"- RSS feed items
- Format output - aggregate and present results in user's language
Best Practice for Comprehensive Queries:
# When user asks about relationships, people, or general memory:
node $SKILL_DIR/scripts/openloomi-memory.cjs search-all "person/project/topic"
# Then optionally get details from specific sources
node $SKILL_DIR/scripts/openloomi-memory.cjs search-memory "person" --directory=people
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --days=30 --keyword=<keyword>
Channel-Based Message Queries:
# User asks "what emails did I receive?" or "show me Gmail messages"
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=gmail --days=7
# User asks "any Telegram messages about project X"?
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=telegram --days=30
# User asks "recent WhatsApp messages"?
node $SKILL_DIR/scripts/openloomi-memory.cjs list-insights --channel=whatsapp
Living Connections (Hebbian Potentiation)
Living Connections track relationships between insights that strengthen when they're accessed together. This implements Hebbian learning: "insights that fire together, wire together."
Commands
# Get related insights - "users who viewed X also viewed Y"
node $SKILL_DIR/scripts/openloomi-memory.cjs get-related-insights <insightId>
# Get related insights with filters
node $SKILL_DIR/scripts/openloomi-memory.cjs get-related-insights insight_xxx --limit=10 --minStrength=0.3
# Get connection statistics
node $SKILL_DIR/scripts/openloomi-memory.cjs get-connection-stats <insightId>
How It Works
- When you view an insight, connections to other insights viewed within 5 minutes are strengthened
- Connection strength decays over time using Ebbinghaus-style forgetting curve
- Strong connections (strength > 0.5) are considered "living" - actively referenced
Response Format
{
"insightId": "insight_xxx",
"connections": [...],
"relatedInsights": [
{
"insightId": "insight_yyy",
"strength": 0.72,
"coAccessCount": 5
}
],
"total": 5
}
Temporal Queries (Time-Travel)
Temporal validity enables "time-travel" queries - seeing what insights were relevant at a specific point in time.
Commands
# Get insights valid at a specific point in time (time-travel query)
node $SKILL_DIR/scripts/openloomi-memory.cjs get-insights-as-of 2026-01-01
# Get currently valid insights (no expiration or future expiration)
node $SKILL_DIR/scripts/openloomi-memory.cjs get-current-insights
# Get insights overlapping a time interval
node $SKILL_DIR/scripts/openloomi-memory.cjs get-insights-in-interval 2026-01-01 2026-06-01
Use Cases
- "What did I know about Project X on March 1st?"
- "What insights were valid during my vacation last July?"
- "Show me only currently relevant insights (hide expired ones)"
Entity Registry
Entity Registry tracks people, groups, concepts, projects, and companies as first-class entities with disambiguation support.
Commands
# List all entities of a specific type
node $SKILL_DIR/scripts/openloomi-memory.cjs list-entities --type=person
# Search entities by name
node $SKILL_DIR/scripts/openloomi-memory.cjs list-entities --search=John
# Get entity details with linked insights
node $SKILL_DIR/scripts/openloomi-memory.cjs get-entity <entityId> --insights
Entity Types
| Type | Description |
|---|---|
person |
People (contacts, colleagues, friends) |
group |
Groups (teams, organizations) |
concept |
Abstract concepts (ideas, methodologies) |
project |
Projects (initiatives, deliverables) |
company |
Companies (clients, vendors, employers) |
Search with Connections
Combined search that returns matching insights along with their Living Connections, providing a richer context.
# Search insights and include related insights
node $SKILL_DIR/scripts/openloomi-memory.cjs search-with-connections "project deadline"
# With custom limit
node $SKILL_DIR/scripts/openloomi-memory.cjs search-with-connections "project deadline" --limit=5