Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/MemOS-Cloud-OpenClaw-Plugin/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ node_modules
# Environment variables
.env
.env.*
.memos_arms_uid

# NPM
.npmrc
Expand Down
22 changes: 22 additions & 0 deletions apps/MemOS-Cloud-OpenClaw-Plugin/HOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: memos-cloud-openclaw-plugin
description: "OpenClaw lifecycle plugin for MemOS Cloud (add + recall memory)"
homepage: https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin
metadata: {
"openclaw": {
"emoji": "🧠",
"events": ["before_agent_start", "agent_end", "command:new"],
"requires": {
"bins": ["node"]
}
}
}
---

# MemOS Cloud OpenClaw Plugin Hooks

This plugin registers the following OpenClaw lifecycle hooks to interact with MemOS Cloud:

- `before_agent_start`: Intercepts the agent startup sequence to recall relevant memories from MemOS Cloud and injects them into the agent's context.
- `agent_end`: Intercepts the agent termination sequence to capture the completed conversation turn and saves it to MemOS Cloud.
- `command:new`: Increments a numeric conversation suffix when the `/new` command is issued to keep MemOS contexts distinct.
31 changes: 15 additions & 16 deletions apps/MemOS-Cloud-OpenClaw-Plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ A minimal OpenClaw lifecycle plugin that **recalls** memories from MemOS Cloud b
## Features
- **Recall**: `before_agent_start` → `/search/memory`
- **Add**: `agent_end` → `/add/message`
- **Config UI**: starting the gateway also starts a local plugin config page for editing `plugins.entries.memos-cloud-openclaw-plugin.config`
- Uses **Token** auth (`Authorization: Token <MEMOS_API_KEY>`)

## Config UI
- On gateway start, the plugin launches a local config page and prints the URL in the terminal (default: `http://127.0.0.1:38463`).
- The page reads and writes the host config file directly:
- OpenClaw: `~/.openclaw/openclaw.json`
- Moltbot: `~/.moltbot/moltbot.json`
- ClawDBot: `~/.clawdbot/clawdbot.json`
- If the preferred UI port is already in use, the plugin automatically picks the next free port.
- Saving changes writes `plugins.entries.memos-cloud-openclaw-plugin.config`. (Note: you may need to manually restart the gateway after saving for settings to take effect).

## Install

### Option A — NPM (Recommended)
Expand Down Expand Up @@ -55,9 +65,8 @@ Make sure it’s enabled in `~/.openclaw/openclaw.json`:
Restart the gateway after config changes.

## Environment Variables
The plugin resolves runtime config in this order: **plugin config → env files → process environment**.
Among env files, it tries them in order (**openclaw → moltbot → clawdbot**). For each key, the first file with a value wins.
If none of these files exist (or the key is missing), it falls back to the process environment.
The plugin resolves runtime config in this order: **plugin config → env files**. Due to strict security sandboxing, it **does not** read credentials from process environment variables.
For env files, it tries them in order (**openclaw → moltbot → clawdbot**). For each key, the first file with a value wins.

**Where to configure**
- Files (priority order):
Expand All @@ -66,19 +75,9 @@ If none of these files exist (or the key is missing), it falls back to the proce
- `~/.clawdbot/.env`
- Each line is `KEY=value`

**Quick setup (shell)**
**Quick setup (shell / Windows)**
```bash
echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.zshrc
source ~/.zshrc
# or

echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.bashrc
source ~/.bashrc
```

**Quick setup (Windows PowerShell)**
```powershell
[System.Environment]::SetEnvironmentVariable("MEMOS_API_KEY", "mpg-...", "User")
echo 'MEMOS_API_KEY="mpg-..."' >> ~/.openclaw/.env
```

If `MEMOS_API_KEY` is missing, the plugin will warn with setup instructions and the API key URL.
Expand Down Expand Up @@ -306,7 +305,7 @@ MEMOS_AGENT_OVERRIDES='{"research-agent": {"memoryLimitNumber": 12, "relativity"
- **What it does**: when enabled, session keys like `agent:main:<provider>:direct:<peer-id>` reuse `<peer-id>` as MemOS `user_id`.
- **What it does not do**: non-direct session keys such as `agent:main:<provider>:channel:<channel-id>` keep using the configured fallback `userId`.
- **Request paths affected**: the same resolver is used by both `buildSearchPayload()` and `buildAddMessagePayload()`, so recall and add stay consistent.
- **Config precedence**: runtime config still follows the same rule as the rest of the plugin - plugin config first, then `.env` files (`~/.openclaw/.env` -> `~/.moltbot/.env` -> `~/.clawdbot/.env`), then process env.
- **Config precedence**: runtime config still follows the same rule as the rest of the plugin - plugin config first, then `.env` files (`~/.openclaw/.env` -> `~/.moltbot/.env` -> `~/.clawdbot/.env`).


## Notes
Expand Down
29 changes: 14 additions & 15 deletions apps/MemOS-Cloud-OpenClaw-Plugin/README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@
## 功能
- **Recall**:`before_agent_start` → `/search/memory`
- **Add**:`agent_end` → `/add/message`
- **Config UI**:启动 gateway 时同时启动本地插件配置页面,用来编辑 `plugins.entries.memos-cloud-openclaw-plugin.config`
- 使用 **Token** 认证(`Authorization: Token <MEMOS_API_KEY>`)

## 配置页面
- Gateway 启动后,插件会同时拉起一个本地配置页面,并在终端输出访问地址(默认:`http://127.0.0.1:38463`)。
- 页面会直接读取并写回当前宿主的配置文件:
- OpenClaw:`~/.openclaw/openclaw.json`
- Moltbot:`~/.moltbot/moltbot.json`
- ClawDBot:`~/.clawdbot/clawdbot.json`
- 如果默认端口被占用,插件会自动顺延到下一个可用端口。
- 页面保存后会写回 `plugins.entries.memos-cloud-openclaw-plugin.config`。(注意:保存后可能需要手动重启 Gateway 以使配置生效)

## 安装

### 方式 A — NPM(推荐)
Expand Down Expand Up @@ -57,9 +67,8 @@ openclaw gateway restart
修改配置后需要重启 gateway。

## 环境变量
插件运行时配置的优先级是:**插件 config → env 文件 → 进程环境变量**
插件运行时配置的优先级是:**插件 config → env 文件**。为符合纯粹的安全沙箱规范,插件不再支持回退到进程环境变量去读取敏感凭证
在 env 文件层,按顺序读取(**openclaw → moltbot → clawdbot**),每个键优先使用最先匹配到的值。
若三个文件都不存在(或该键未找到),才会回退到进程环境变量。

**配置位置**
- 文件(优先级顺序):
Expand All @@ -68,19 +77,9 @@ openclaw gateway restart
- `~/.clawdbot/.env`
- 每行格式:`KEY=value`

**快速配置(Shell)**
**快速配置(Shell / Windows)**
```bash
echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.zshrc
source ~/.zshrc
# 或者

echo 'export MEMOS_API_KEY="mpg-..."' >> ~/.bashrc
source ~/.bashrc
```

**快速配置(Windows PowerShell)**
```powershell
[System.Environment]::SetEnvironmentVariable("MEMOS_API_KEY", "mpg-...", "User")
echo 'MEMOS_API_KEY="mpg-..."' >> ~/.openclaw/.env
```

若未读取到 `MEMOS_API_KEY`,插件会提示配置方式并附 API Key 获取地址。
Expand Down Expand Up @@ -311,7 +310,7 @@ MEMOS_AGENT_OVERRIDES='{"research-agent": {"memoryLimitNumber": 12, "relativity"
- **行为说明**:开启后,像 `agent:main:<provider>:direct:<peer-id>` 这样的私聊 sessionKey,会把 `<peer-id>` 当作 MemOS `user_id`。
- **不会影响的场景**:像 `agent:main:<provider>:channel:<channel-id>` 这类非私聊 sessionKey,仍继续使用配置好的 fallback `userId`。
- **作用范围**:同一套解析逻辑同时作用于 `buildSearchPayload()` 和 `buildAddMessagePayload()`,保证 recall 与 add 一致。
- **配置优先级**:仍遵循插件现有规则——插件 config 优先,其次是 `.env` 文件(`~/.openclaw/.env` -> `~/.moltbot/.env` -> `~/.clawdbot/.env`),最后才回退到进程环境变量
- **配置优先级**:仍遵循插件现有规则——插件 config 优先,其次是 `.env` 文件(`~/.openclaw/.env` -> `~/.moltbot/.env` -> `~/.clawdbot/.env`)。


## 说明
Expand Down
110 changes: 49 additions & 61 deletions apps/MemOS-Cloud-OpenClaw-Plugin/clawdbot.plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "memos-cloud-openclaw-plugin",
"name": "MemOS Cloud OpenClaw Plugin",
"description": "MemOS Cloud recall + add memory via lifecycle hooks",
"version": "0.1.11",
"version": "0.1.12",
"kind": "lifecycle",
"main": "./index.js",
"configSchema": {
Expand All @@ -18,8 +18,7 @@
},
"userId": {
"type": "string",
"description": "MemOS user_id (default: openclaw-user)",
"default": "openclaw-user"
"description": "MemOS user_id (default: openclaw-user)"
},
"conversationId": {
"type": "string",
Expand All @@ -38,17 +37,14 @@
"enum": [
"none",
"counter"
],
"default": "none"
]
},
"useDirectSessionUserId": {
"type": "boolean",
"description": "When enabled, direct-session keys like agent:main:<provider>:direct:<id> use the direct id as MemOS user_id instead of the default configured userId.",
"default": false
"description": "When enabled, direct-session keys like agent:main:<provider>:direct:<id> use the direct id as MemOS user_id instead of the default configured userId."
},
"resetOnNew": {
"type": "boolean",
"default": true
"type": "boolean"
},
"queryPrefix": {
"type": "string",
Expand All @@ -63,8 +59,37 @@
"default": true
},
"recallGlobal": {
"type": "boolean",
"default": true
"type": "boolean"
},
"recallFilterEnabled": {
"type": "boolean"
},
"recallFilterBaseUrl": {
"type": "string",
"description": "OpenAI-compatible base URL for recall filter model"
},
"recallFilterApiKey": {
"type": "string",
"description": "API key for recall filter model endpoint"
},
"recallFilterModel": {
"type": "string",
"description": "Model name used to filter recall candidates"
},
"recallFilterTimeoutMs": {
"type": "integer"
},
"recallFilterRetries": {
"type": "integer"
},
"recallFilterCandidateLimit": {
"type": "integer"
},
"recallFilterMaxItemChars": {
"type": "integer"
},
"recallFilterFailOpen": {
"type": "boolean"
},
"addEnabled": {
"type": "boolean",
Expand All @@ -75,26 +100,23 @@
"enum": [
"last_turn",
"full_session"
],
"default": "last_turn"
]
},
"maxMessageChars": {
"type": "integer",
"description": "Max chars per message when adding",
"default": 20000
"description": "Max chars per message when adding"
},
"maxItemChars": {
"type": "integer",
"description": "Max chars per memory item when injecting prompt",
"default": 8000
},
"includeAssistant": {
"type": "boolean",
"default": true
"type": "boolean"
},
"memoryLimitNumber": {
"type": "integer",
"default": 6
"default": 9
},
"preferenceLimitNumber": {
"type": "integer",
Expand All @@ -112,50 +134,15 @@
"type": "integer",
"default": 6
},
"relativity": {
"type": "number",
"description": "Minimum relativity score required before a recalled item is injected"
},
"filter": {
"type": "object",
"description": "MemOS search filter",
"additionalProperties": true
},
"relativity": {
"type": "number",
"description": "Search relativity threshold",
"default": 0.45
},
"recallFilterEnabled": {
"type": "boolean",
"default": false
},
"recallFilterBaseUrl": {
"type": "string",
"description": "OpenAI-compatible API base URL for recall filtering"
},
"recallFilterApiKey": {
"type": "string"
},
"recallFilterModel": {
"type": "string"
},
"recallFilterTimeoutMs": {
"type": "integer",
"default": 30000
},
"recallFilterRetries": {
"type": "integer",
"default": 1
},
"recallFilterCandidateLimit": {
"type": "integer",
"default": 30
},
"recallFilterMaxItemChars": {
"type": "integer",
"default": 500
},
"recallFilterFailOpen": {
"type": "boolean",
"default": true
},
"knowledgebaseIds": {
"type": "array",
"items": {
Expand All @@ -176,8 +163,7 @@
"type": "string"
},
"multiAgentMode": {
"type": "boolean",
"default": false
"type": "boolean"
},
"allowedAgents": {
"type": "array",
Expand All @@ -200,6 +186,9 @@
}
},
"asyncMode": {
"type": "boolean"
},
"rumEnabled": {
"type": "boolean",
"default": true
},
Expand All @@ -212,8 +201,7 @@
"default": 1
},
"throttleMs": {
"type": "integer",
"default": 0
"type": "integer"
},
"agentOverrides": {
"type": "object",
Expand Down
Loading
Loading