Back to skills
SkillHub ClubShip Full StackFull Stack

multi-chat-context-manager

CLI tool to store and retrieve conversation contexts per channel/user.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,072
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
B81.2

Install command

npx @skill-hub/cli install openclaw-skills-multi-chat-context-manager

Repository

openclaw/skills

Skill path: skills/derick001/multi-chat-context-manager

CLI tool to store and retrieve conversation contexts per channel/user.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install multi-chat-context-manager into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding multi-chat-context-manager to shared team environments
  • Use multi-chat-context-manager for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: multi-chat-context-manager
description: CLI tool to store and retrieve conversation contexts per channel/user.
version: 1.0.2
author: skill-factory
metadata:
  openclaw:
    requires:
      bins:
        - python3
---

# Multi-Chat Context Manager

## What This Does

A simple CLI tool to store, retrieve, and clear conversation contexts. Contexts are saved as JSON, keyed by channel/user/thread IDs. This is a utility library, not an auto-integration plugin.

## When To Use

- You need to manually store conversation history per channel or user
- You want a simple key-value context store for your scripts
- You're building custom integrations and need context persistence

## Usage

Store a conversation:
python3 scripts/context_manager.py store --channel "telegram-123" --user "user-456" --message "Hello" --response "Hi there"

Retrieve context:
python3 scripts/context_manager.py retrieve --channel "telegram-123" --user "user-456"

Clear context:
python3 scripts/context_manager.py clear --channel "telegram-123"

List all contexts:
python3 scripts/context_manager.py list

## Examples

### Example 1: Store and retrieve

Store:
python3 scripts/context_manager.py store --channel "discord-general" --user "john" --message "What is AI?" --response "AI is artificial intelligence."

Retrieve:
python3 scripts/context_manager.py retrieve --channel "discord-general" --user "john"

Output:
{
  "channel_id": "discord-general",
  "user_id": "john",
  "history": [{"message": "What is AI?", "response": "AI is artificial intelligence."}]
}

## Requirements

- Python 3.x
- No external dependencies

## Limitations

- This is a CLI tool, not an auto-integration plugin
- Does not automatically intercept messages from platforms
- Stores data in plaintext JSON (not encrypted)
- No file-locking for concurrent access
- You must call it manually from your scripts or workflows


---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "derick001",
  "slug": "multi-chat-context-manager",
  "displayName": "Multi-Chat Context Manager",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1772028252325,
    "commit": "https://github.com/openclaw/skills/commit/21e1b95b54c2c81e0138642b2d044a5c3cdbf578"
  },
  "history": [
    {
      "version": "1.0.3",
      "publishedAt": 1771950802864,
      "commit": "https://github.com/openclaw/skills/commit/0d714e0efe7a7252d328fb0c0db97e2c3d19d87a"
    }
  ]
}

```

### scripts/context-manager.sh

```bash
#!/usr/bin/env bash
# Multi-Chat Context Manager - Shell Wrapper
# Usage: context-manager.sh <command> [args]
# Commands: store, retrieve, clear, list

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYTHON_SCRIPT="${SCRIPT_DIR}/context_manager.py"

# Ensure Python script exists
if [[ ! -f "$PYTHON_SCRIPT" ]]; then
    echo "Error: Python script not found at $PYTHON_SCRIPT" >&2
    exit 1
fi

# Parse command
COMMAND="$1"
shift

case "$COMMAND" in
    store)
        # Expect arguments in key=value format for simplicity
        CHANNEL=""
        USER=""
        THREAD=""
        MESSAGE=""
        RESPONSE=""
        MAX_HISTORY="10"
        
        for arg in "$@"; do
            case "$arg" in
                channel=*) CHANNEL="${arg#*=}" ;;
                user=*) USER="${arg#*=}" ;;
                thread=*) THREAD="${arg#*=}" ;;
                message=*) MESSAGE="${arg#*=}" ;;
                response=*) RESPONSE="${arg#*=}" ;;
                max_history=*) MAX_HISTORY="${arg#*=}" ;;
                *) echo "Unknown argument: $arg" >&2; exit 1 ;;
            esac
        done
        
        if [[ -z "$CHANNEL" || -z "$MESSAGE" || -z "$RESPONSE" ]]; then
            echo "Usage: $0 store channel=<id> message=<text> response=<text> [user=<id>] [thread=<id>] [max_history=<n>]" >&2
            exit 1
        fi
        
        python3 "$PYTHON_SCRIPT" store \
            --channel "$CHANNEL" \
            ${USER:+--user "$USER"} \
            ${THREAD:+--thread "$THREAD"} \
            --message "$MESSAGE" \
            --response "$RESPONSE" \
            --max-history "$MAX_HISTORY"
        ;;
    
    retrieve)
        CHANNEL=""
        USER=""
        THREAD=""
        
        for arg in "$@"; do
            case "$arg" in
                channel=*) CHANNEL="${arg#*=}" ;;
                user=*) USER="${arg#*=}" ;;
                thread=*) THREAD="${arg#*=}" ;;
                *) echo "Unknown argument: $arg" >&2; exit 1 ;;
            esac
        done
        
        if [[ -z "$CHANNEL" ]]; then
            echo "Usage: $0 retrieve channel=<id> [user=<id>] [thread=<id>]" >&2
            exit 1
        fi
        
        python3 "$PYTHON_SCRIPT" retrieve \
            --channel "$CHANNEL" \
            ${USER:+--user "$USER"} \
            ${THREAD:+--thread "$THREAD"}
        ;;
    
    clear)
        CHANNEL=""
        USER=""
        THREAD=""
        
        for arg in "$@"; do
            case "$arg" in
                channel=*) CHANNEL="${arg#*=}" ;;
                user=*) USER="${arg#*=}" ;;
                thread=*) THREAD="${arg#*=}" ;;
                *) echo "Unknown argument: $arg" >&2; exit 1 ;;
            esac
        done
        
        python3 "$PYTHON_SCRIPT" clear \
            ${CHANNEL:+--channel "$CHANNEL"} \
            ${USER:+--user "$USER"} \
            ${THREAD:+--thread "$THREAD"}
        ;;
    
    list)
        python3 "$PYTHON_SCRIPT" list
        ;;
    
    *)
        echo "Usage: $0 {store|retrieve|clear|list} [args]" >&2
        echo ""
        echo "Examples:"
        echo "  $0 store channel=telegram-123 message=\"Hello\" response=\"Hi there\" user=user456"
        echo "  $0 retrieve channel=telegram-123 user=user456"
        echo "  $0 clear channel=telegram-123"
        echo "  $0 list"
        exit 1
        ;;
esac
```

### scripts/context_manager.py

```python
#!/usr/bin/env python3
"""
Multi-Chat Context Manager
Store, retrieve, and clear conversation contexts per channel/user.
"""

import json
import os
import sys
import argparse
from pathlib import Path

DEFAULT_STORAGE_PATH = str(Path(__file__).parent.parent / 'data' / 'contexts.json')

def load_contexts():
    """Load contexts from JSON file."""
    try:
        with open(DEFAULT_STORAGE_PATH, 'r') as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        return {}

def save_contexts(contexts):
    """Save contexts to JSON file."""
    os.makedirs(os.path.dirname(DEFAULT_STORAGE_PATH), exist_ok=True)
    with open(DEFAULT_STORAGE_PATH, 'w') as f:
        json.dump(contexts, f, indent=2)

def get_context_key(channel_id, user_id=None, thread_id=None):
    """Generate a unique key for a context."""
    key = f"channel:{channel_id}"
    if user_id:
        key += f":user:{user_id}"
    if thread_id:
        key += f":thread:{thread_id}"
    return key

def store_context(channel_id, user_id=None, thread_id=None, message=None, response=None, max_history=10):
    """Store a message/response pair in context."""
    contexts = load_contexts()
    key = get_context_key(channel_id, user_id, thread_id)
    
    if key not in contexts:
        contexts[key] = {
            'channel_id': channel_id,
            'user_id': user_id,
            'thread_id': thread_id,
            'history': []
        }
    
    entry = contexts[key]
    if message is not None and response is not None:
        entry['history'].append({
            'message': message,
            'response': response,
            'timestamp': os.path.getmtime(__file__)  # placeholder, could use datetime
        })
        # Keep only last N entries
        if len(entry['history']) > max_history:
            entry['history'] = entry['history'][-max_history:]
    
    save_contexts(contexts)
    return entry

def retrieve_context(channel_id, user_id=None, thread_id=None):
    """Retrieve context for a channel/user/thread."""
    contexts = load_contexts()
    key = get_context_key(channel_id, user_id, thread_id)
    return contexts.get(key, {})

def clear_context(channel_id=None, user_id=None, thread_id=None):
    """Clear context(s). If no IDs provided, clear all."""
    contexts = load_contexts()
    if channel_id is None:
        contexts.clear()
    else:
        key = get_context_key(channel_id, user_id, thread_id)
        if key in contexts:
            del contexts[key]
        # Also clear any sub-contexts? For simplicity, just exact match.
    save_contexts(contexts)
    return {'cleared': True}

def list_contexts():
    """List all stored contexts."""
    contexts = load_contexts()
    return contexts

def main():
    parser = argparse.ArgumentParser(description='Multi-Chat Context Manager')
    subparsers = parser.add_subparsers(dest='command', required=True)
    
    # store
    store_parser = subparsers.add_parser('store', help='Store a message/response pair')
    store_parser.add_argument('--channel', required=True, help='Channel ID')
    store_parser.add_argument('--user', help='User ID')
    store_parser.add_argument('--thread', help='Thread ID')
    store_parser.add_argument('--message', required=True, help='User message')
    store_parser.add_argument('--response', required=True, help='Agent response')
    store_parser.add_argument('--max-history', type=int, default=10, help='Maximum history entries to keep')
    
    # retrieve
    retrieve_parser = subparsers.add_parser('retrieve', help='Retrieve context')
    retrieve_parser.add_argument('--channel', required=True, help='Channel ID')
    retrieve_parser.add_argument('--user', help='User ID')
    retrieve_parser.add_argument('--thread', help='Thread ID')
    
    # clear
    clear_parser = subparsers.add_parser('clear', help='Clear context(s)')
    clear_parser.add_argument('--channel', help='Channel ID')
    clear_parser.add_argument('--user', help='User ID')
    clear_parser.add_argument('--thread', help='Thread ID')
    
    # list
    subparsers.add_parser('list', help='List all contexts')
    
    args = parser.parse_args()
    
    if args.command == 'store':
        result = store_context(
            channel_id=args.channel,
            user_id=args.user,
            thread_id=args.thread,
            message=args.message,
            response=args.response,
            max_history=args.max_history
        )
        print(json.dumps(result, indent=2))
    
    elif args.command == 'retrieve':
        result = retrieve_context(
            channel_id=args.channel,
            user_id=args.user,
            thread_id=args.thread
        )
        print(json.dumps(result, indent=2))
    
    elif args.command == 'clear':
        result = clear_context(
            channel_id=args.channel,
            user_id=args.user,
            thread_id=args.thread
        )
        print(json.dumps(result, indent=2))
    
    elif args.command == 'list':
        result = list_contexts()
        print(json.dumps(result, indent=2))
    
    else:
        parser.print_help()
        sys.exit(1)

if __name__ == '__main__':
    main()

```