Skip to content

Integration: CEMS ↔ Moltis AI Assistant Memory Bridge #3

@Chocksy

Description

@Chocksy

Overview

This issue proposes integrating CEMS (Continuous Evolving Memory System) with Moltis, an AI assistant framework (similar to Claude Code/Cursor hooks). The goal is to enable bidirectional memory flow between CEMS and Moltis, allowing memories created in either system to be accessible in both.

What is Moltis?

Moltis is an AI assistant runtime that provides:

  • Persistent memory across sessions (via memory_search, memory_save tools)
  • Scheduled cron jobs for proactive check-ins
  • MCP (Model Context Protocol) server integration
  • Skills system for slash commands (/remember, /recall, etc.)

Currently, Moltis stores memories in local markdown files. We want to connect it to CEMS as a richer, more structured memory backend.


Proposed Integration Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Moltis AI Assistant                       │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐ │
│  │   Skills    │  │   Memory    │  │      Cron Jobs          │ │
│  │  /remember  │  │    Tools    │  │  - Morning briefing     │ │
│  │  /recall    │◄─┤  (local)    │◄─┤  - PR checks            │ │
│  │  /context   │  │             │  │  - Jira/Slack sync      │ │
│  └──────┬──────┘  └──────┬──────┘  └─────────────────────────┘ │
│         │                │                                       │
│         └────────────────┼───────────────────────────────────────┘
│                          │
│         ┌────────────────▼────────────────┐
│         │     CEMS Memory Bridge          │
│         │  - Sync local → CEMS            │
│         │  - Sync CEMS → local            │
│         │  - Unified search               │
│         └────────────────┬────────────────┘
│                          │
└──────────────────────────┼──────────────────────────────────────┘
                           │ HTTP / MCP
┌──────────────────────────┼──────────────────────────────────────┐
│                          ▼                                       │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │                    CEMS Server                              │ │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────┐  │ │
│  │  │  REST    │  │   MCP    │  │  Vector  │  │ Maintenance│  │ │
│  │  │   API    │  │ Wrapper  │  │  Store   │  │   Jobs     │  │ │
│  │  │  :8765   │  │  :8766   │  │(pgvector)│  │(scheduler) │  │ │
│  │  └──────────┘  └──────────┘  └──────────┘  └───────────┘  │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Integration Options

Option 1: MCP Client Connection (Recommended)

Moltis connects to CEMS MCP server as a client:

{
  "mcpServers": {
    "cems": {
      "url": "https://cems.example.com/mcp",
      "headers": {
        "Authorization": "Bearer cems_usr_xxx"
      }
    }
  }
}

Pros:

  • Native MCP protocol
  • No custom code needed in CEMS
  • Works with any MCP client

Cons:

  • Requires Moltis to support MCP client mode
  • Less control over sync logic

Option 2: REST API Bridge (Current Approach)

Create a bridge module in Moltis that:

  1. Calls CEMS REST API (/api/memory/search, /api/memory/add)
  2. Syncs memories bidirectionally
  3. Merges CEMS results with local memory

Implementation sketch:

# moltis/cems_bridge.py
import os
import httpx

CEMS_API_URL = os.getenv("CEMS_API_URL")
CEMS_API_KEY = os.getenv("CEMS_API_KEY")

async def search_memories(query: str, scope: str = "both"):
    """Search both local and CEMS memories, merge results."""
    # Search CEMS
    cems_results = await search_cems(query, scope)
    # Search local
    local_results = search_local(query)
    # Merge with deduplication
    return merge_results(cems_results, local_results)

async def add_memory(content: str, **kwargs):
    """Add to both CEMS and local."""
    # Add to CEMS
    cems_id = await add_to_cems(content, **kwargs)
    # Add to local (for offline access)
    local_id = add_to_local(content, cems_id=cems_id, **kwargs)
    return {"cems_id": cems_id, "local_id": local_id}

Pros:

  • Full control over sync logic
  • Can implement smart merging (RRF, time decay, etc.)
  • Works today with existing tools

Cons:

  • Requires custom bridge code
  • Need to handle auth/token management

Option 3: Hybrid Sync with Webhooks

CEMS sends webhooks to Moltis when memories change:

# CEMS webhook handler
@app.post("/webhook/cems")
async def cems_webhook(event: CemsEvent):
    if event.type == "memory.added":
        sync_to_local(event.memory)
    elif event.type == "memory.deleted":
        delete_local(event.memory_id)

Pros:

  • Real-time sync
  • Efficient (only sync changes)

Cons:

  • Requires CEMS to support webhooks (not yet implemented)
  • More complex infrastructure

Specific Integration Points

1. Memory Search Unification

When Moltis searches memories, query CEMS in parallel:

User: "What did I say about the database schema?"

Moltis:
  ├─ Search local memory (fast, always available)
  ├─ Search CEMS (rich, with embeddings/graph)
  └─ Merge results (RRF + time boost + relevance)

Return: Unified, ranked list of memories

2. Proactive Memory Injection

CEMS has UserPromptSubmit hooks. Moltis could call:

# Before every user prompt
context = await cems.get_session_profile()
relevant_memories = await cems.search(query, max_tokens=2000)
augmented_prompt = f"{context}\n\n{relevant_memories}\n\nUser: {user_input}"

3. Session Learning Export

When Moltis session ends, export learnings to CEMS:

# On session end
learnings = extract_learnings(session_transcript)
for learning in learnings:
    await cems.add_memory(
        content=learning,
        category="session-learning",
        source_ref=f"moltis:session:{session_id}",
        tags=["moltis", "auto-extracted"]
    )

4. Bidirectional Category Mapping

Map Moltis categories to CEMS categories:

Moltis (local) CEMS Notes
preferences preferences Coding style, tools
projects projects Active work context
people contacts Team members, relationships
decisions decisions ADRs, choices made
routines routines Daily/weekly patterns

5. Shared Namespace for Team Context

Use CEMS shared scope for team memories:

# Shared team knowledge
await cems.add_memory(
    content="Team uses PostgreSQL with pgvector",
    scope="shared",
    category="architecture",
    source_ref="team:ai-squad"
)

Authentication & Security

Moltis needs CEMS credentials. Options:

  1. Environment variables:

    CEMS_API_URL=https://cems.example.com
    CEMS_API_KEY=cems_usr_xxx
  2. Credentials file (~/.moltis/cems-credentials):

    api_url: https://cems.example.com
    api_key: cems_usr_xxx
  3. Moltis settings.json (merged like Claude Code):

    {
      "cems": {
        "api_url": "https://cems.example.com",
        "api_key": "cems_usr_xxx"
      }
    }

Open Questions

  1. Conflict resolution: If same memory exists in both with different content, which wins?
  2. Offline mode: Should Moltis fall back to local-only if CEMS is unreachable?
  3. Rate limiting: CEMS has embedding costs. Batch sync vs. real-time?
  4. Memory ownership: Who "owns" a memory created via Moltis but stored in CEMS?
  5. Deletion sync: If deleted in CEMS, delete locally? Vice versa?

Implementation Plan

Phase 1: Read-Only Bridge (Week 1)

  • Create moltis/cems_bridge.py with search-only integration
  • Add CEMS env vars to Moltis config
  • Test unified search (local + CEMS)

Phase 2: Bidirectional Sync (Week 2)

  • Add memory creation to CEMS
  • Export Moltis session learnings to CEMS
  • Category mapping

Phase 3: Smart Features (Week 3-4)

  • Proactive memory injection before prompts
  • Conflict resolution rules
  • Webhook listener (if CEMS adds webhooks)

Related

  • CEMS MCP wrapper: mcp-wrapper/src/index.ts
  • CEMS REST API: src/cems/api/handlers/memory.py
  • Moltis memory tools: memory_search, memory_save

Next Steps:

  • Discuss integration approach (MCP vs REST vs Hybrid)
  • Create proof-of-concept branch
  • Test with real data

cc: @Chocksy

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions