Use the official OpenClaw and Hermes plugins to connect your agent to the Tablestore Memory Service. The plugins automatically retrieve relevant long-term memories before each conversation turn and write back new memories afterward.
OpenClaw plugin
openclaw-tablestore-memory is an OpenClaw memory plugin that calls the Memory Service through the Tablestore Agent Storage SDK (AgentStorageClient from @tablestore/agent-storage). The plugin supports both AccessKey (AK/SK) and API Key authentication.
Installation
openclaw plugins install @tablestore/openclaw-tablestore-memory
Authentication methods
The plugin supports the following two authentication modes. Choose one:
-
AccessKey (AK/SK): supports all features. When AK/SK is used, if
endpointandotsInstanceNameare left unset, the plugin automatically creates and reuses a managed instance incn-beijing. -
API Key: takes precedence over AK/SK when
apiKeyis set. The API Key only authorizes data-plane operations of the Memory Service (not the control plane), so an HTTPSendpointandotsInstanceNamemust be specified explicitly, and automatic managed-instance creation is not supported.
Configuration
Minimum AK/SK configuration:
{
"plugins": {
"slots": {
"memory": "tablestore-mem"
},
"entries": {
"tablestore-mem": {
"enabled": true,
"config": {
"endpoint": "https://<instance>.cn-beijing.ots.aliyuncs.com",
"otsInstanceName": "<instance-name>",
"accessKeyId": "<AccessKey ID>",
"accessKeySecret": "<AccessKey secret>"
}
}
}
}
}
API Key configuration:
{
"plugins": {
"slots": { "memory": "tablestore-mem" },
"entries": {
"tablestore-mem": {
"enabled": true,
"hooks": { "allowConversationAccess": true },
"config": {
"apiKey": "<API Key>",
"endpoint": "https://<instance>.cn-beijing.ots.aliyuncs.com",
"otsInstanceName": "<instance-name>"
}
}
}
}
}
hooks.allowConversationAccess=true is the trust switch introduced in OpenClaw 2026.4.26+. When it is enabled, writeback runs during agent_end. When it is disabled, retrieval during before_prompt_build still works, but OpenClaw blocks the automatic writeback.
The following settings can also be overridden through environment variables: TABLESTORE_MEMORY_APP_ID, TABLESTORE_MEMORY_TENANT_ID, and TABLESTORE_MEMORY_API_KEY.
Optional parameters
|
Parameter |
Default |
Description |
|
|
Auto-created |
Data endpoint. Not required when using AK/SK (the plugin auto-creates and reuses an instance in |
|
|
Auto-created |
Instance name. Not required when using AK/SK (auto-created). Required when using API Key. |
|
|
None |
Memory Service API Key. Takes precedence over AK/SK when set. Requires an explicit HTTPS |
|
|
|
Application identifier. |
|
|
Derived from session user information |
Tenant or user identifier. Takes precedence over the session user identity when set. |
|
|
|
Name of the memory store. |
|
|
|
Description written when the memory store is created. |
|
|
None |
Custom extraction instructions at the memory-store level (up to 4,096 characters), used to guide long-term memory extraction. Applied at creation time, or aligned through |
|
|
|
Whether to automatically create the memory store if it does not exist. |
|
|
|
Whether to write back memories after a conversation ends. |
|
|
|
Whether to include relevance scores when injecting retrieved memories into context. |
|
|
|
Number of memory entries to return per retrieval ( |
|
|
|
Similarity filter threshold ( |
|
|
|
Automatic retrieval is skipped when the prompt is shorter than this length. |
|
|
|
Whether to enable reranking. |
|
|
|
Whether to enable offline Dream memory consolidation (background schedule plus |
|
|
|
Background Dream consolidation cycle, in hours. |
|
|
Same as |
Minimum interval before the same Scope is consolidated again. |
|
|
|
|
|
|
|
Default confidence threshold ( |
|
|
None |
Per-action confidence thresholds for |
|
|
None |
Custom consolidation instructions (up to 4,000 characters) that guide Dream behavior. |
|
|
|
Maximum number of Scopes consolidated per background run. |
|
|
|
Whether to immediately trigger a Dream consolidation for the current Scope when a session ends. |
Scope mapping
When writing memories, the plugin uses the current runtime identity:
{
"appId": "openclaw",
"tenantId": "<current-user>",
"agentId": "<runtime-agent>",
"runId": "<runtime-session>"
}
When retrieving memories, the plugin uses a tenant-level scope across all agents and sessions, with agentId and runId set to *:
{
"appId": "openclaw",
"tenantId": "<current-user>",
"agentId": "*",
"runId": "*"
}
Runtime behavior
-
Retrieves relevant long-term memories during
before_prompt_build. -
Injects retrieved memories into hidden context, not visible in conversation history.
-
Collects user and assistant messages from the current turn during
agent_end. -
Writes back to the memory store through
AddMemories(asynchronous by default).
Memory consolidation (Dream)
The plugin includes an offline Dream consolidation process that deduplicates, rewrites, merges, and cleans up previously written long-term memories:
-
Each successful writeback enqueues the exact Scope (
appId/tenantId/agentId/runId) for consolidation. -
The background scheduler processes the queue every
dreamIntervalHours(default: 24 hours), consolidating up todreamMaxScopesPerRunScopes per run withapplyMode=safe_autoandincremental=true. -
When
dreamOnSessionEndis enabled (the default), a session end (rotation, reset, idle, or compaction) immediately consolidates that session Scope. It shares the per-Scope watermark anddreamMinIntervalHoursthrottle with the background scheduler, so the same Scope is never consolidated twice within the interval. -
safe_autoautomatically appliesadd,update, andmergeactions that meet the confidence threshold.DELETEis never applied automatically. Threshold precedence: CLI--threshold(covers all actions) > per-actiondreamConfidenceThresholds> single-valuedreamConfidenceThreshold(default:0.9). -
When
dreamInstructionsis configured, the background job,session_endtrigger, and CLI Dream jobs all pass the custom instructions. -
Consolidation targets specific Scopes only (no wildcards), preserves results in place (
preserve_scope), and runs completely outside the real-time path. Failures are logged only and do not affect retrieval or writeback. -
The background scheduler runs only while the OpenClaw process is alive. For non-resident environments, drive the CLI with cron (see below).
CLI and slash commands
The OpenClaw plugin provides the following debugging and operations commands:
# Write and retrieve
openclaw tablestore-mem add "Alice likes jasmine tea" --uid alice
openclaw tablestore-mem search "what does Alice like" --uid alice
openclaw tablestore-mem search "what does Alice like" --uid alice --top-k 10 --min-similarity 0.3
# Diagnose connectivity, memory stores, and Scope listings
openclaw tablestore-mem doctor --uid alice
# Trigger memory consolidation (Dream) on demand
openclaw tablestore-mem dream --uid alice --wait
openclaw tablestore-mem dream --uid alice --apply-mode proposal --wait
openclaw tablestore-mem dream --uid alice --threshold 0.8 --wait
openclaw tablestore-mem dream --uid alice --instructions "Prioritize merging duplicate preferences" --wait
Within an OpenClaw session, use the following slash commands:
/tablestore-mem-add Alice likes jasmine tea
/tablestore-mem-search jasmine tea
Hermes plugin
hermes-tablestore-memory is a Hermes Agent plugin that connects to the Memory Service through the Tablestore Python SDK.
Installation
hermes plugins install https://github.com/aliyun/hermes-tablestore-memory
hermes memory setup
During hermes memory setup, select tablestore-mem.
The plugin requires tablestore>=6.4.5. If this dependency is missing from the Hermes Python environment, install the SDK manually.
Configure credentials
Store credentials in ~/.hermes/.env:
TABLESTORE_MEMORY_AK=<AccessKey ID>
TABLESTORE_MEMORY_SK=<AccessKey secret>
Configure the Memory Service
Store non-sensitive settings in $HERMES_HOME/tablestore_memory.json:
{
"endpoint": "https://<instance>.cn-beijing.ots.aliyuncs.com",
"instance_name": "<instance-name>",
"memory_store_name": "hermes_mem",
"description": "",
"app_id": "hermes",
"tenant_id": "",
"enable_rerank": true,
"auto_create_store": true,
"timeout": 30
}
Default values
|
Parameter |
Default |
Description |
|
|
|
Name of the memory store. |
|
|
|
Application identifier. |
|
|
Empty string |
Derived from session context if left blank. Defaults to |
|
|
|
Whether to enable reranking. |
|
|
|
Whether to automatically create the memory store if it does not exist. |
|
|
|
Request timeout period, in seconds. |
Scope mapping
The Hermes plugin maps the four Scope fields as follows:
|
Field |
Source |
|
|
|
|
|
Hermes session |
|
|
Hermes session identity. Defaults to |
|
|
|
When writing, the plugin uses the exact session scope. When retrieving, it broadens to tenant-level by setting agentId="" and runId="".
Available tools
|
Tool |
Description |
|
|
Views memories under the current scope. |
|
|
Retrieves long-term memories. |
|
|
Writes a long-term memory. |
|
|
Deletes a long-term memory. |
The plugin also automatically syncs user and assistant messages after each turn and prefetches relevant memories before the next turn.
Hermes CLI commands
After setting memory.provider to tablestore-mem, run the following commands:
hermes tablestore-mem add "User prefers concise answers."
hermes tablestore-mem add "User likes Rust." --metadata source=manual --metadata topic=preferences
hermes tablestore-mem add "Write this memory synchronously." --sync
hermes tablestore-mem search "concise answers"
hermes tablestore-mem search "Rust" --top-k 10
Claude Code plugin
The Claude Code plugin adds long-term memory to Claude Code. It calls the Tablestore Memory Service through @tablestore/agent-storage. Its capabilities align with the OpenClaw tablestore-mem plugin and additionally expose MCP tools.
Capabilities
-
Per-turn automatic retrieval (
UserPromptSubmithook): retrieves relevant long-term memories before the prompt is submitted, and injects them into hidden context that is not shown in the visible conversation. -
Per-turn automatic writeback (
Stophook): after the turn ends, the new user and assistant messages from that turn are incrementally written to the memory store. Batches respect the service limits (up to 20 messages and 32,000 bytes per batch). -
Offline Dream consolidation (
SessionEndhook and CLI or cron): deduplicates, rewrites, merges, and removes stale memories. -
MCP tools (invoked explicitly by the model):
search_memory,add_memory, andconsolidate_memory. -
Slash commands:
/search,/add,/doctor, and/dream. -
CLI:
search,add,doctor, anddream. -
Supports both API Key and AccessKey (AK/SK) authentication.
Requirements
-
Node.js 18 or later.
-
A Tablestore instance that is already created (the Memory Service is only available in the China (Beijing) region). Prepare the HTTPS endpoint and instance name, together with an API Key or an AK/SK pair.
-
The plugin does not automatically create an instance. Provide the endpoint and instance name explicitly.
Installation
Repository: https://github.com/aliyun/tablestore-memory-claude-plugin. Dependencies are pre-bundled with esbuild into dist/ (shipped with the repository), so npm install is not required for installation.
# Option 1 (recommended): install from the GitHub marketplace
claude plugin marketplace add aliyun/tablestore-memory-claude-plugin
claude plugin install tablestore-memory@tablestore-memory-marketplace
# Option 2: clone the repository and install from the local directory
git clone https://github.com/aliyun/tablestore-memory-claude-plugin.git
claude plugin marketplace add ./tablestore-memory-claude-plugin
claude plugin install tablestore-memory@tablestore-memory-marketplace
During development, skip the marketplace and point directly to the plugin directory:
claude --plugin-dir /path/to/tablestore-memory-claude-plugin
After modifying the plugin source, rebuild the bundle:
npm run build # Rebuild into dist/
Configuration
Set the following variables in the env block of ~/.claude/settings.json. They are injected into both the hooks and the MCP server:
{
"env": {
"TABLESTORE_MEMORY_ENDPOINT": "https://<instance>.cn-beijing.ots.aliyuncs.com",
"TABLESTORE_MEMORY_INSTANCE": "<instance>",
"TABLESTORE_MEMORY_API_KEY": "<api-key>"
}
}
To use AK/SK instead, replace TABLESTORE_MEMORY_API_KEY with TABLESTORE_ACCESS_KEY_ID and TABLESTORE_ACCESS_KEY_SECRET.
Authentication precedence: if TABLESTORE_MEMORY_API_KEY is set, the plugin uses API Key authentication (which requires an HTTPS endpoint). Otherwise, AK/SK is used. If neither is set, the plugin is silently disabled.
A configuration file can also serve as a fallback: ~/.tablestore-memory/config.json (with camelCase keys endpoint, instanceName, apiKey, accessKeyId, accessKeySecret, and storeName). Environment variables take precedence over the configuration file.
Full list of environment variables:
|
Environment variable |
Default |
Description |
|
|
None |
Required. Tablestore instance endpoint. |
|
|
None |
Required. Tablestore instance name. |
|
|
None |
API Key authentication (takes precedence over AK/SK). |
|
|
None |
AK/SK authentication. |
|
|
None |
AK/SK authentication. |
|
|
|
Memory store name. |
|
|
|
Whether to automatically create the memory store if it does not exist. |
|
|
|
Whether to enable Dream consolidation. |
|
|
|
|
|
|
|
Automatic-apply confidence threshold for |
|
|
|
Maximum number of Scopes consolidated per run. |
|
|
|
Minimum interval between two consolidations of the same Scope. |
|
|
Empty |
When set, debug logs are written to stderr. |
Scope design (a global per-user pool)
-
Writes anchor to a specific session:
appId / tenantId / agentId / runId=<session_id>. -
Retrieval broadens within a fixed tenant:
agentId=*andrunId=*, which enables cross-session and cross-project recall. -
Wildcards follow the service hierarchy rule: once a level uses
*, all deeper levels must also use*.
Dream (memory consolidation)
-
A session end (
SessionEnd) triggers a consolidation for the tenant Scope, throttled byDREAM_MIN_INTERVAL_HOURS. State is stored in~/.tablestore-memory/dream-state.json. -
Because the plugin cannot run as a background daemon, drive periodic consolidation by calling the CLI from cron:
# Example: consolidate a tenant's memories daily at 03:17 and wait for the result
17 3 * * * node /path/to/tablestore-memory/dist/cli.mjs dream --uid <tenant> --wait
CLI
node dist/cli.mjs search "What beverages does the user like?" --top-k 5
node dist/cli.mjs add "The user likes Americano." --sync
node dist/cli.mjs doctor
node dist/cli.mjs dream --uid <tenant> --apply-mode safe_auto --wait
--uid overrides the tenant (intended for operations and cron). -q/--quiet emits data fields only.
Behavior and boundaries
-
Fail-open: missing configuration or any SDK exception does not interrupt the conversation. Hooks log to stderr and exit with status 0.
-
Hook stdout carries only the protocol JSON. All logs go to stderr.
-
After asynchronous writes (
sync=false), long-term memories become retrievable within roughly 15 seconds.--syncextracts them immediately.
Choose an integration method
Select a method based on your requirements:
|
Scenario |
Recommended method |
Description |
|
Application uses OpenClaw or Hermes |
Official plugin |
Retrieves long-term memories across all agents and sessions within the same tenant. Suits most personal assistant and business agent scenarios. |
|
Custom memory write, retrieval, or context assembly logic required |
SDK |
For more information, see Python SDK or Node.js SDK. |
|
Strict session-level retrieval isolation required |
SDK with a custom full Scope |
For the field definitions, see Memory Storage API. |
To share memories between agents, use the same Tablestore instance and ensure appId, tenantId, and memoryStoreName match exactly across both configurations. agentId is determined by each agent runtime and set to * during retrieval.