---
title: "OpenCode Integration"
description: "The Mem0 OpenCode integration exposes persistent semantic memory directly inside OpenCode agent sessions integrations/opencode-plugin/opencode-mem0.ts:2-5. Operating via the mem0ai SDK without requ..."
last_updated: "2026-10-11T17:37:10.212608+00:00"
canonical_url: "https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/agent-plugins/opencode-integration"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [integrations/opencode-plugin/opencode-mem0.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts)
- [integrations/codex-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/codex-plugin/core/memory_core.py)
- [integrations/openclaw/index.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/openclaw/index.ts)
- [integrations/claude-code-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/claude-code-plugin/core/memory_core.py)
- [integrations/agent-plugin-core/python/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/agent-plugin-core/python/memory_core.py)
- [integrations/antigravity-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/memory_core.py)
- [integrations/mem0-agent-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-agent-plugin/core/memory_core.py)
- [integrations/kimi-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/kimi-plugin/core/memory_core.py)
- [integrations/deepseek-plugin/src/index.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts)
- [integrations/hermes-plugin-mem0/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/hermes-plugin-mem0/__init__.py)
- [integrations/cursor-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/cursor-plugin/core/memory_core.py)
- [integrations/pi-agent-plugin/src/memory/tools.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/pi-agent-plugin/src/memory/tools.ts)
- [integrations/codex-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/codex-plugin/core/mcp_server.py)
- [integrations/kimi-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/kimi-plugin/core/mcp_server.py)
- [integrations/antigravity-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/mcp_server.py)
- [integrations/claude-code-plugin/hooks/hooks.json](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/claude-code-plugin/hooks/hooks.json)
- [integrations/codex-plugin/hooks/hooks.json](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/codex-plugin/hooks/hooks.json)
- [integrations/claude-code-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/claude-code-plugin/core/mcp_server.py)
- [integrations/mem0-agent-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-agent-plugin/core/mcp_server.py)
- [integrations/agent-plugin-core/python/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/agent-plugin-core/python/mcp_server.py)
- [integrations/pi-agent-plugin/src/entry.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/pi-agent-plugin/src/entry.ts)
- [integrations/cursor-plugin/core/mcp_server.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/cursor-plugin/core/mcp_server.py)
- [integrations/opencode-plugin/api-key.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts)
- [integrations/opencode-plugin/project.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/project.ts)
- [integrations/opencode-plugin/scope.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts)
</details>

## Overview

The Mem0 OpenCode integration exposes persistent semantic memory directly inside OpenCode agent sessions [integrations/opencode-plugin/opencode-mem0.ts:2-5](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L2-L5). Operating via the `mem0ai` SDK without requiring a separate Model Context Protocol (MCP) server, it wires memory management into OpenCode plugin hooks to capture and recall facts across sessions [integrations/opencode-plugin/opencode-mem0.ts:2-5](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L2-L5). Credentials are resolved hierarchically from process environments and user shell profiles, while project identity is derived robustly from Git remotes and repository root paths [integrations/opencode-plugin/opencode-mem0.ts:32-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L32-L51), [integrations/opencode-plugin/api-key.ts:15-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L15-L29). Furthermore, the subsystem normalizes memory scopes and search filters to partition memories by project, session, or global boundaries, and intercepts turn hooks to inject relevant memory contexts into agent prompts [integrations/opencode-plugin/opencode-mem0.ts:17](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L17), [integrations/opencode-plugin/scope.ts:12-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L12-L33).

Sources: [integrations/opencode-plugin/opencode-mem0.ts:2-5](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L2-L5), [integrations/opencode-plugin/opencode-mem0.ts:17](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L17), [integrations/opencode-plugin/opencode-mem0.ts:32-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L32-L51), [integrations/opencode-plugin/api-key.ts:15-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L15-L29), [integrations/opencode-plugin/scope.ts:12-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L12-L33)

## OpenCode Plugin Architecture and Lifecycle

### Initialization and SDK Wiring

The OpenCode plugin acts as the public entry point for memory integration, exporting a standard `Plugin` interface that wires native memory tools backed directly by the `mem0ai` SDK without requiring an intermediate Model Context Protocol server [integrations/opencode-plugin/opencode-mem0.ts:2-8](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L2-L8). During startup, the plugin resolves ambient environment variables such as `MEM0_USER_ID` and `MEM0_APP_ID`, falling back to operating system username and Git repository metadata when explicit configuration is absent [integrations/opencode-plugin/opencode-mem0.ts:23-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L23-L51). It integrates with the TypeScript agent lifecycle by invoking `createMemoryLifecycle` from the common agent core, binding turn interception hooks, and initializing project-level coding categories against the Mem0 platform [integrations/opencode-plugin/opencode-mem0.ts:20](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L20), [integrations/opencode-plugin/opencode-mem0.ts:115-149](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L115-L149).

> [!NOTE]
> The OpenCode plugin bypasses MCP transport layers entirely, instantiating the `MemoryClient` directly in TypeScript to register native tools for adding, searching, and managing memories [integrations/opencode-plugin/opencode-mem0.ts:4-8](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L4-L8).

Sources: [integrations/opencode-plugin/opencode-mem0.ts:2-8](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L2-L8), [integrations/opencode-plugin/opencode-mem0.ts:20](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L20), [integrations/opencode-plugin/opencode-mem0.ts:23-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L23-L51), [integrations/opencode-plugin/opencode-mem0.ts:115-149](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L115-L149)

### Lifecycle Constants and Matching Patterns

The plugin evaluates conversation turns against pre-compiled regular expressions and category fingerprints to determine when to trigger memory capture, project state synchronization, or context resumption [integrations/opencode-plugin/opencode-mem0.ts:98-160](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L98-L160). 

| Constant Name | Type | Value / Pattern | Purpose |
| --- | --- | --- | --- |
| `CODING_CATEGORIES` | `string[]` | 17 standard categories (`architecture_decisions`, `api_design`, etc.) | Defines custom project categories synchronized via `autoSetupCategories` [integrations/opencode-plugin/opencode-mem0.ts:98-104](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L98-L104) |
| `NUDGE_RE` | `RegExp` | `/\b(remember\s+(this|that)|memorize|save\s+this|...)\b/i` | Detects explicit user instructions to store memories [integrations/opencode-plugin/opencode-mem0.ts:151-152](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L151-L152) |
| `RESUME_RE` | `RegExp` | `/where\s+(did\s+)?(we|I)\s+(leave|left)\s+off\|.../i` | Identifies requests to load previous session context or state [integrations/opencode-plugin/opencode-mem0.ts:154-156](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L154-L156) |
| `ERROR_STRONG_RE` | `RegExp` | `/Traceback \(most recent call last\)\|panic: \|.../` | Matches critical runtime errors and panics in tool outputs [integrations/opencode-plugin/opencode-mem0.ts:157-158](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L157-L158) |
| `WRITE_TOOLS` | `Set<string>` | `["Write", "Edit", "MultiEdit", "write", "edit", "multiEdit"]` | Identifies file-modifying tools that trigger automatic memory flushing [integrations/opencode-plugin/opencode-mem0.ts:160](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L160) |

Sources: [integrations/opencode-plugin/opencode-mem0.ts:98-104](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L98-L104), [integrations/opencode-plugin/opencode-mem0.ts:151-160](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L151-L160)

## API Key Resolution and Authentication

### Credential Resolution Strategy

The OpenCode plugin resolves API keys hierarchically, checking active runtime environment variables before scanning user shell profile files in the home directory [integrations/opencode-plugin/api-key.ts:15-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L15-L27). The `resolveApiKey` function first inspects `env.MEM0_API_KEY` (defaulting to `process.env`), returning the explicit value immediately if present and non-empty [integrations/opencode-plugin/api-key.ts:15-17](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L15-L17). When no explicit environment variable is configured, the resolver iterates through a fixed sequence of user profile files located in the user's home directory [integrations/opencode-plugin/api-key.ts:5](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5), [integrations/opencode-plugin/api-key.ts:19-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L27).

> [!NOTE]
> If all candidate profile files are missing, unreadable, or contain no valid export statements, `resolveApiKey` falls back to returning an empty string [integrations/opencode-plugin/api-key.ts:25-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L25-L29).

Sources: [integrations/opencode-plugin/api-key.ts:5-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L29)

### Profile Parsing and Environment Files

When inspecting user shell configurations, the resolver evaluates each line of a profile file using `parseApiKeyLine` to extract assignment expressions [integrations/opencode-plugin/api-key.ts:7-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L7-L13), [integrations/opencode-plugin/api-key.ts:19-24](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L24). The parser matches lines containing optional `export` keywords followed by `MEM0_API_KEY=`, strips inline comments and enclosing single or double quotes, and rejects values that reference unexpanded shell variables beginning with a dollar sign [integrations/opencode-plugin/api-key.ts:7-12](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L7-L12).

| Profile File / Source | Target Variable | Parsing Rules | Fallback Behavior |
| --- | --- | --- | --- |
| `process.env` | `MEM0_API_KEY` | Direct trimmed string evaluation | Proceeds to filesystem profiles if undefined or empty [integrations/opencode-plugin/api-key.ts:15-17](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L15-L17) |
| `.zshrc` | `MEM0_API_KEY` | Matches `export MEM0_API_KEY=...`, strips `#` comments & quotes [integrations/opencode-plugin/api-key.ts:5-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L13) | Skips file on read errors, continues sequence [integrations/opencode-plugin/api-key.ts:19-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L27) |
| `.bashrc` | `MEM0_API_KEY` | Matches `export MEM0_API_KEY=...`, strips `#` comments & quotes [integrations/opencode-plugin/api-key.ts:5-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L13) | Skips file on read errors, continues sequence [integrations/opencode-plugin/api-key.ts:19-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L27) |
| `.zprofile` | `MEM0_API_KEY` | Matches `export MEM0_API_KEY=...`, strips `#` comments & quotes [integrations/opencode-plugin/api-key.ts:5-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L13) | Skips file on read errors, continues sequence [integrations/opencode-plugin/api-key.ts:19-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L27) |
| `.bash_profile` | `MEM0_API_KEY` | Matches `export MEM0_API_KEY=...`, strips `#` comments & quotes [integrations/opencode-plugin/api-key.ts:5-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L13) | Skips file on read errors, continues sequence [integrations/opencode-plugin/api-key.ts:19-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L19-L27) |
| `.profile` | `MEM0_API_KEY` | Matches `export MEM0_API_KEY=...`, strips `#` comments & quotes [integrations/opencode-plugin/api-key.ts:5-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L13) | Returns `""` if exhausted without match [integrations/opencode-plugin/api-key.ts:25-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L25-L29) |

Sources: [integrations/opencode-plugin/api-key.ts:5-29](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/api-key.ts#L5-L29)

## Workspace Project Identity Extraction

### Project Identity Derivation Logic

The OpenCode workspace derives its unique project identifier by evaluating runtime environment variables, git repository remotes, and local working directory structures [integrations/opencode-plugin/opencode-mem0.ts:32-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L32-L51). The `getProjectId` function first inspects `process.env.MEM0_APP_ID`, returning this explicit configuration immediately if present [integrations/opencode-plugin/opencode-mem0.ts:33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L33). When no application ID environment variable is defined, the function executes a series of asynchronous shell commands via the tagged template literal `$` to query git state [integrations/opencode-plugin/opencode-mem0.ts:34-41](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L34-L41).

> [!NOTE]
> Git remote parsing extracts the repository's owner and repository name, providing an identity that remains stable across clones, worktrees, and custom host aliases [integrations/opencode-plugin/opencode-mem0.ts:34-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L34-L39).

```typescript
async function getProjectId($: any): Promise<string> {
  if (process.env.MEM0_APP_ID) return process.env.MEM0_APP_ID;
  // Prefer the git remote's owner/repo — stable across clones, worktrees, and
  // sub-directories (handles https + ssh, incl. custom host aliases).
  try {
    const r = await $`git remote get-url origin`.quiet();
    const project = parseProjectFromRemote(r.stdout.toString());
    if (project) return project;
  } catch {
  }
  // No usable remote: use the git repo ROOT dir name, not cwd (which may be a
  // sub-directory, or your home dir if OpenCode was launched outside a repo).
  try {
    const r = await $`git rev-parse --show-toplevel`.quiet();
    const top = r.stdout.toString().trim();
    if (top) return basename(top);
  } catch {
  }
  return basename(process.cwd());
}
```
Sources: [integrations/opencode-plugin/opencode-mem0.ts:32-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L32-L51)

### Fallback Resolution and Branch Detection

When a git remote is unavailable or parsing fails, `getProjectId` attempts to locate the repository root via `git rev-parse --show-toplevel` and extracts its basename [integrations/opencode-plugin/opencode-mem0.ts:42-49](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L42-L49). This prevents sub-directories or home directory launches from polluting project scopes [integrations/opencode-plugin/opencode-mem0.ts:42-43](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L42-L43). If all git queries fail, the function falls back to the basename of the current working directory (`process.cwd()`) [integrations/opencode-plugin/opencode-mem0.ts:50](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L50). Concurrently, branch identification is handled by `getBranch`, which executes `git branch --show-current` and defaults to `"main"` if the command throws an error or yields an empty string [integrations/opencode-plugin/opencode-mem0.ts:53-60](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L53-L60).

| Resolution Method | Command / Source | Target Property | Fallback Behavior |
| --- | --- | --- | --- |
| Environment Override | `process.env.MEM0_APP_ID` | Project Identifier | Proceeds to git remote check if undefined [integrations/opencode-plugin/opencode-mem0.ts:33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L33) |
| Git Remote Parsing | `git remote get-url origin` | Owner/Repository | Proceeds to repository root discovery on failure [integrations/opencode-plugin/opencode-mem0.ts:37-41](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L37-L41) |
| Repository Root | `git rev-parse --show-toplevel` | Top-level Basename | Falls back to `process.cwd()` basename [integrations/opencode-plugin/opencode-mem0.ts:45-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L45-L51) |
| Branch Detection | `git branch --show-current` | Current Git Branch | Defaults to `"main"` if detached or non-git directory [integrations/opencode-plugin/opencode-mem0.ts:55-59](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L55-L59) |

```typescript
export { parseProjectFromRemote } from "../agent-plugin-core/typescript/src/identity.ts";
```
Sources: [integrations/opencode-plugin/opencode-mem0.ts:32-60](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L32-L60), [integrations/opencode-plugin/project.ts:1-1](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/project.ts#L1-L1)

## Scope Normalization and Search Filtering

### Scoping Parameters and Default Resolution

Memory read and write operations are governed by scope configurations that dictate whether memories apply globally, to the current project, or to an active session. The scope subsystem normalizes user preferences and applies runtime parameters using shared utilities from the [TypeScript agent core](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/agent-plugins/typescript-agent-core) [integrations/opencode-plugin/scope.ts:1-6](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L1-L6). The `resolveDefaultScope` function inspects user settings stored in `~/.mem0/settings.json`, falling back to standard scoping rules via `normalizeScope` [integrations/opencode-plugin/opencode-mem0.ts:74-96](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L74-L96), [integrations/opencode-plugin/scope.ts:37-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L37-L39).

Sources: [integrations/opencode-plugin/opencode-mem0.ts:74-96](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L74-L96), [integrations/opencode-plugin/scope.ts:1-6](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L1-L6), [integrations/opencode-plugin/scope.ts:37-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L37-L39)

> [!TIP]
> The default scope reads fresh from persistent settings on every operation, allowing users to modify their active scope via the `mem0-scope` skill without restarting OpenCode [integrations/opencode-plugin/opencode-mem0.ts:89-96](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L89-L96).

### Scope Guidance and Filter Adaptation

Memory tools rely on explicit scope instructions defined by `SCOPE_GUIDANCE`, which directs agents on when to omit the scope parameter for normal queries, restrict it to the current run using `"session"`, or escalate to `"global"` after user authorization [integrations/opencode-plugin/scope.ts:41-42](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L41-L42). Search filters and write parameters adapt these scopes into concrete identifiers using `scopeSearchFilters` and `scopeWriteParams` [integrations/opencode-plugin/scope.ts:12-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L12-L33).

| Scope Function | Input Parameters | Return Structure | Purpose |
| --- | --- | --- | --- |
| `scopeSearchFilters` | `scope`, `userId`, `appId`, `runId` | `Record<string, string>` | Builds search query filters matching the active scope level [integrations/opencode-plugin/scope.ts:12-19](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L12-L19) |
| `scopeWriteParams` | `scope`, `userId`, `appId`, `runId` | `{ user_id: string; app_id?: string; run_id?: string }` | Formats parameters for memory storage operations [integrations/opencode-plugin/scope.ts:21-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L21-L33) |
| `asScope` | Raw scope input | `Scope` | Normalizes arbitrary scope strings via core utilities [integrations/opencode-plugin/scope.ts:35](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L35) |
| `resolveDefaultScope` | `settings` object | `Scope` | Extracts and normalizes default scope from settings file [integrations/opencode-plugin/scope.ts:37-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L37-L39) |

```typescript
export function scopeSearchFilters(
  scope: Scope,
  userId: string,
  appId: string,
  runId: string,
): Record<string, string> {
  return sharedSearchFilters(scope, context(userId, appId, runId));
}

export function scopeWriteParams(
  scope: Scope,
  userId: string,
  appId: string,
  runId: string,
): { user_id: string; app_id?: string; run_id?: string } {
  const values = scopeAddParams(scope, context(userId, appId, runId));
  return {
    user_id: values.userId,
    ...(values.appId ? { app_id: values.appId } : {}),
    ...(values.runId ? { run_id: values.runId } : {}),
  };
}

export const asScope = normalizeScope;

export function resolveDefaultScope(settings: Record<string, unknown> | null | undefined): Scope {
  return normalizeScope(settings?.default_scope);
}
```
Sources: [integrations/opencode-plugin/scope.ts:12-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/scope.ts#L12-L39)

## Turn Hooks and Memory Injection

### Interception Hooks and Message Extraction

Conversation streams and agent turns in OpenCode are intercepted through lifecycle hooks that monitor session flow, extract relevant user text, and manage background capture or prompt assembly [integrations/deepseek-plugin/src/index.ts:130-198](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts#L130-L198). Regular expressions such as `NUDGE_RE` detect explicit user memory directives like "remember this", "memorize", or "don't forget", while `RESUME_RE` identifies patterns for continuing previous work like "where did we leave off" or "catch me up" [integrations/opencode-plugin/opencode-mem0.ts:151-156](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L151-L156). Additionally, error patterns such as `ERROR_STRONG_RE` capture stack traces and compiler panics (`Traceback (most recent call last)`, `panic:`, `FATAL:`, `error[E\d+:]`) to trigger automated memory preservation [integrations/opencode-plugin/opencode-mem0.ts:157-159](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L157-L159).

```typescript
const NUDGE_RE =
  /\b(remember\s+(this|that)|memorize|save\s+this|note\s+(this|that)|don'?t\s+forget|always\s+remember|never\s+forget|keep\s+(this|that)\s+in\s+(mind|memory)|store\s+(this|that))\b/i;

const RESUME_RE =
  /where\s+(did\s+)?(we|I)\s+(leave|left)\s+off|continue\s+(from\s+)?(where|last)|what\s+were\s+we\s+(working|doing)|pick\s+up\s+where|resume\s+(from\s+|where\s+)|what.s\s+the\s+(current|latest)\s+(state|status)|catch\s+me\s+up|where\s+are\s+we/i;

const ERROR_STRONG_RE =
  /Traceback \(most recent call last\)|panic: |FATAL:|error\[E\d+\]/;
const ERROR_MULTI_RE = /(Error:|Exception:)/g;
const WRITE_TOOLS = new Set(["Write", "Edit", "MultiEdit", "write", "edit", "multiEdit"]);
```
Sources: [integrations/opencode-plugin/opencode-mem0.ts:151-160](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L151-L160)

> [!WARNING]
> Write tools such as `Write`, `Edit`, and `MultiEdit` (tracked in `WRITE_TOOLS`) modify codebase state and require careful handling during conversation captures to prevent duplicating raw file diffs into long-term semantic memory [integrations/opencode-plugin/opencode-mem0.ts:160](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts#L160).

### Prompt Compaction and Context Injection

Prompt assembly phases leverage the TypeScript agent core lifecycle (`createMemoryLifecycle`) to prepare conversation histories and sanitize user inputs before executing semantic similarity searches against the Mem0 platform [integrations/deepseek-plugin/src/index.ts:110-144](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts#L110-L144). When a user prompt is submitted, the system filters out non-user message sources, strips extraneous metadata, and prepares the text for recall [integrations/deepseek-plugin/src/index.ts:136-140](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts#L136-L140). Retrieved memory results are formatted with clear section headers and injected directly into the system prompt context array under descriptors like `mem0:recall` or `<relevant-memories>` [integrations/deepseek-plugin/src/index.ts:166-169](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts#L166-L169), [integrations/openclaw/index.ts:685](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/openclaw/index.ts#L685).

```typescript
ctx.on("system-prompt/assemble", async (_input, context, next): Promise<PromptAssembly> => {
  const assembly = await next();
  const { agent, signal } = context;
  if (!agent || signal?.aborted) return assembly;

  const state = stateFor(agent.session);
  const prompt = state.lifecycle.prepareConversation(
    agent.session
      .deriveMessages()
      .filter((message) => message.role === "user" && message.source?.kind === "user"),
  ).at(-1)?.content;
  if (!prompt) return assembly;

  const memoryContext = await state.lifecycle.recall(prompt, true, async (query) => {
    const started = Date.now();
    try {
      const result = await client.search(query, {
        filters: resolveSearchFilters({}, userId),
        topK: AUTO_RECALL_LIMIT,
      });
      captureEvent("deepseek.recall.auto", {
        success: true,
        duration_ms: Date.now() - started,
        result_count: result.results?.length ?? 0,
      }, client);
      return result;
    } catch (err) {
      captureEvent("deepseek.recall.auto", {
        success: false,
        duration_ms: Date.now() - started,
        error_kind: errorKind(err),
      }, client);
      throw err;
    }
  });
  if (!memoryContext || signal?.aborted) return assembly;
  return {
    ...assembly,
    contexts: [...assembly.contexts, { name: "mem0:recall", text: memoryContext }],
  };
});
```
Sources: [integrations/deepseek-plugin/src/index.ts:130-170](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/deepseek-plugin/src/index.ts#L130-L170), [integrations/openclaw/index.ts:685](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/openclaw/index.ts#L685)

## Related

- [TypeScript Agent Core](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/agent-plugins/typescript-agent-core)
- [OpenClaw Integration](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/agent-plugins/openclaw-integration)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/llms.txt) for all pages in this wiki.
