You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* docs(mcp): document --project/ENGRAM_PROJECT override for engram mcp (#394)
The stale comment at DOCS.md:~1041 falsely claimed engram mcp did not
support --project or ENGRAM_PROJECT. Commit b094052 wired both into
MCPConfig.DefaultProject. Update DOCS.md body text, env-var table,
README CLI table, and printUsage() help string to reflect current behavior.
* docs(agent-setup): add VS Code/WSL project detection guide and Linux EXDEV fix (#419, #109)
Hosts that don't inherit cwd (VS Code, WSL, CI, Docker) need an explicit
--project flag or ENGRAM_PROJECT env var to avoid wrong project detection.
Add a worked example with both forms and explain when to use each.
Also document the EXDEV cross-device link error that appears on Linux when
/tmp and /home are on separate filesystems, with a one-shot TMPDIR workaround
and a permanent shell-rc fix.
* docs: expand topic_key guide and add Windows Task Scheduler template (#158, #421)
#158: Rewrite the Topic Key Workflow section in ARCHITECTURE.md into a
complete guide covering the upsert semantics, format convention with
FTS5 rationale, anti-patterns, decision table, mem_suggest_topic_key
workflow, hierarchy limit, lifecycle/pruning, and scope interaction.
#421: Add a Windows Task Scheduler template to the Running as a Service
section in DOCS.md, parallel to the existing systemd and launchd blocks.
Includes PowerShell setup snippet, note on persistent env vars for cloud
token, UTF-8 log guidance, and stop/remove instructions.
|`ENGRAM_DATA_DIR`| Override data directory |`~/.engram`|
459
459
|`ENGRAM_PORT`| Override HTTP server port |`7437`|
460
-
|`ENGRAM_PROJECT`|Default project for `engram serve``GET /sync/status`when no `project` query param is supplied. When unset, cwd detection is used as the fallback. | cwd-detected project |
460
+
|`ENGRAM_PROJECT`|Process-level default project override. For `engram serve`: used as the fallback when `GET /sync/status`receives no `project` query param. For `engram mcp`: sets `MCPConfig.DefaultProject`, which takes precedence over cwd detection for all read and write tools for the lifetime of that MCP process. When unset, cwd detection is used as the fallback.| cwd-detected project |
461
461
|`ENGRAM_HTTP_TOKEN`| Optional Bearer auth for the local HTTP server. When set, the following routes require `Authorization: Bearer <token>`: `DELETE /sessions/{id}`, `DELETE /observations/{id}`, `DELETE /prompts/{id}`, `GET /export`, `POST /import`, `POST /projects/migrate`. Comparison is constant-time. Token is read at request time (no restart needed). When unset, all routes are open (zero-config default). | (unset — open) |
462
462
|`ENGRAM_TIMEZONE`| Timezone for timestamp display in the TUI and cloud dashboard. Accepts any IANA zone name (e.g. `America/New_York`, `Europe/Berlin`). Falls back to system local time when unset or invalid. | system local |
463
463
|`ENGRAM_AGENT_CLI`| LLM runner name used by `engram conflicts scan --semantic` and the HTTP `/conflicts/scan` endpoint. Accepted values: `claude`, `opencode`. | (unset) |
@@ -1038,7 +1038,7 @@ MCP tools resolve project names at call time using the shared detection chain:
1038
1038
5. Multiple git-repo children of cwd returns `ambiguous_project` with `available_projects`
1039
1039
6. Current working directory basename
1040
1040
1041
-
The MCP command does not support startup-time `--project` or `ENGRAM_PROJECT` overrides; `engram mcp` only parses `--tools`for MCP tool allowlisting.
1041
+
`engram mcp` accepts a process-level default project via `--project <name>` / `--project=<name>` or `ENGRAM_PROJECT=<name>`. This override takes precedence over cwd detection for all read and write tools throughout the lifetime of that MCP process. It is a trusted startup-time value — use it when the host cannot supply a reliable cwd (VS Code, WSL, CI, Docker).
1042
1042
1043
1043
### Similar-project warnings
1044
1044
@@ -1251,6 +1251,45 @@ To unload (stop and disable): `launchctl unload ~/Library/LaunchAgents/com.gentl
1251
1251
1252
1252
> **Note on `brew upgrade`:** launchd does not expand `$HOME` or `~` inside plist values, which is why the template uses literal absolute paths.
1253
1253
1254
+
### Using Windows Task Scheduler
1255
+
1256
+
Windows Task Scheduler is the native service equivalent on Windows. It restarts `engram serve` on login and after reboots, keeping autosync alive without a third-party service manager.
1257
+
1258
+
**Setup steps:**
1259
+
1260
+
1. Confirm `engram.exe` is in your `PATH`: open PowerShell and run `Get-Command engram`.
1261
+
2. Set `ENGRAM_CLOUD_TOKEN` (and any other cloud vars) as a **user or system environment variable** in System Properties → Advanced → Environment Variables. Task Scheduler does not inherit session environment variables, so tokens set in your shell profile or in `$env:...` within a PowerShell session will not be visible to the scheduled task.
1262
+
3. Create the scheduled task by running the PowerShell snippet below in an elevated terminal (Run as Administrator), or import it manually through the Task Scheduler GUI.
1263
+
4. Verify: after the next login (or trigger manually), run `engram cloud status` — the `Local daemon:` line should report `running on port 7437`.
-Description "Engram persistent memory server (engram serve)"
1285
+
```
1286
+
1287
+
> **Environment variables:**`ENGRAM_CLOUD_TOKEN`, `ENGRAM_CLOUD_SERVER`, `ENGRAM_CLOUD_AUTOSYNC`, and `ENGRAM_DATA_DIR` must be set as persistent user or system environment variables (Control Panel → System → Advanced → Environment Variables) so Task Scheduler can read them. Variables you `export` or set with `$env:` in a terminal session are not visible to scheduled tasks.
1288
+
1289
+
> **Logs:** To capture stdout/stderr, redirect output in the PowerShell command string, for example: `... -Command "Start-Process engram -ArgumentList 'serve' -NoNewWindow -RedirectStandardOutput '$env:USERPROFILE\.engram\serve.out.log' -RedirectStandardError '$env:USERPROFILE\.engram\serve.err.log'"`. Ensure the log files are opened with UTF-8 encoding (`-Encoding UTF8`) if you post-process them.
1290
+
1291
+
> **Stopping the task:**`Stop-ScheduledTask -TaskName "EngramMemoryServer"` or `Unregister-ScheduledTask -TaskName "EngramMemoryServer" -Confirm:$false` to remove it entirely.
Copy file name to clipboardExpand all lines: docs/AGENT-SETUP.md
+73Lines changed: 73 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -310,6 +310,35 @@ PowerShell fallback test and local override example:
310
310
311
311
See [Plugins → Claude Code Plugin](PLUGINS.md#claude-code-plugin) for details on what the plugin provides.
312
312
313
+
### Troubleshooting: Claude Code plugin install on Linux
314
+
315
+
If `claude plugin install engram` fails on Linux with an error like:
316
+
317
+
```
318
+
EXDEV: cross-device link not permitted
319
+
```
320
+
321
+
this is a Node.js `fs.rename` limitation, not an Engram bug. Node uses `fs.rename` to move the downloaded plugin archive from the system temp directory (`/tmp`) to the plugin destination under your home directory. On many Linux systems `/tmp` and `/home` live on separate filesystems (common with `tmpfs` on `/tmp`), and the kernel rejects cross-device renames.
322
+
323
+
**One-shot workaround** — set `TMPDIR` to a location on the same filesystem as your home directory before running the install:
324
+
325
+
```bash
326
+
mkdir -p ~/.cache/claude-tmp
327
+
TMPDIR=~/.cache/claude-tmp claude plugin install engram
328
+
```
329
+
330
+
**Permanent fix** — add the export to your shell rc file so all future `claude plugin install` commands work without the prefix:
331
+
332
+
```bash
333
+
# ~/.bashrc or ~/.zshrc
334
+
export TMPDIR="$HOME/.cache/claude-tmp"
335
+
mkdir -p "$TMPDIR"
336
+
```
337
+
338
+
Then reload your shell (`source ~/.bashrc`) and re-run the install.
339
+
340
+
> This is an upstream Claude Code CLI limitation that affects any plugin installed via `claude plugin install`, not just Engram. Docker-based environments are typically not affected because the container's `/tmp` and `/home` usually share the same overlay filesystem.
341
+
313
342
---
314
343
315
344
## Gemini CLI
@@ -463,6 +492,50 @@ The Memory Protocol tells the agent:
463
492
464
493
See [Surviving Compaction](#surviving-compaction-recommended) for the minimal version, or [DOCS.md](../DOCS.md#memory-protocol-full-text) for the full Memory Protocol text you can copy-paste.
465
494
495
+
### Project detection in VS Code, WSL, and CI
496
+
497
+
VS Code, WSL, and most CI runners start the MCP server process without inheriting the shell's working directory, so cwd-based project detection may resolve to the wrong project or fall back to a directory basename you don't recognise.
498
+
499
+
The reliable fix is to pin the project explicitly at startup time. Both forms below work:
**Environment variable form** (useful when the config format does not support extra args, or when you want to override without editing the config file):
515
+
516
+
```json
517
+
{
518
+
"servers": {
519
+
"engram": {
520
+
"command": "engram",
521
+
"args": ["mcp", "--tools=agent"],
522
+
"env": {
523
+
"ENGRAM_PROJECT": "my-project"
524
+
}
525
+
}
526
+
}
527
+
}
528
+
```
529
+
530
+
Both `--project=my-project` and `ENGRAM_PROJECT=my-project` set `MCPConfig.DefaultProject`, which takes precedence over cwd detection for every read and write tool for the lifetime of that MCP process.
531
+
532
+
> The `--project` flag and `ENGRAM_PROJECT` env var are the same mechanism. If both are supplied, the flag wins. The value must match an existing project name in your Engram store; unknown names are rejected so typos fail loudly instead of silently creating a new project bucket.
533
+
534
+
Same pattern applies to:
535
+
- WSL terminals where VS Code opens a remote window (`\\wsl$\...` paths) — the MCP server process runs inside WSL but VS Code does not forward the workspace directory as cwd.
536
+
- CI pipelines (GitHub Actions, GitLab CI, etc.) where the agent runs in a container and the checkout path differs from the project name you use locally.
537
+
- Any Docker-based agent host where the container cwd does not match your Engram project name.
Use this when a topic evolves over time (architecture, long-running feature decisions, etc.):
105
+
### What topic_key is
106
+
107
+
`topic_key` turns `mem_save` into an **upsert**: if a memory with the same `project + scope + topic_key` already exists, the existing observation is updated in place (`revision_count++`) instead of creating a new row. Without a `topic_key`, every `mem_save` creates a new observation even when the content describes the same evolving topic.
108
+
109
+
Use topic keys for knowledge that changes over time: architecture decisions, long-running feature notes, recurring patterns, configuration choices. Skip them for one-off bugs, single facts, or anything that does not evolve.
**Why this format?** SQLite FTS5 tokenises on word boundaries. Lowercase kebab-case ensures the key fragments are individually searchable and do not create unexpected FTS5 token splits.
|`ARCHITECTURE/AUTH`| uppercase is inconsistent with FTS5 normalisation |`architecture/auth-model`|
135
+
|`auth/model/v2/final`| more than 2 levels — use `v2` in the description |`architecture/auth-model-v2`|
136
+
|`bugfix`| no slash — looks like a family with no description |`bug/auth-nil-panic`|
137
+
138
+
### Decision table — when to use topic_key
139
+
140
+
| Situation | Use topic_key? | Reasoning |
141
+
|---|---|---|
142
+
| Architecture or design decision that may evolve | Yes | Keeps history in one observation, incrementing `revision_count`|
143
+
| Long-running feature work (spans multiple sessions) | Yes | Single source of truth across sessions |
144
+
| A pattern or convention established for the project | Yes | One canonical entry, updated as the pattern matures |
145
+
| Bug fix that was self-contained and is now closed | No | A single observation is fine; no future updates expected |
146
+
| One-off discovery or fact | No | Creating a key you will never reuse adds noise |
147
+
| Multiple independent decisions on the same broad topic | No — use distinct keys | Different decisions must have different keys or they will overwrite each other |
148
+
149
+
### The mem_suggest_topic_key-first workflow
150
+
151
+
When you are not sure which key to use, call `mem_suggest_topic_key` before `mem_save`. It applies a family heuristic based on the observation type and title, returning a suggested key you can use directly or adjust:
-`discovery/*` — non-obvious findings about the codebase
172
+
-`learning/*` — team knowledge and onboarding notes
173
+
174
+
If none of these families fit, it is usually fine to skip the key and let `mem_save` create a plain observation.
115
175
116
-
`mem_suggest_topic_key` now applies a family heuristic for consistency across sessions:
176
+
### Hierarchical keys — max 2 levels
177
+
178
+
Keys are organisational only; there is no parent–child relationship in the store. Two levels (`family/description`) cover almost every case. Use the description segment to add specificity rather than adding more slashes:
179
+
180
+
```
181
+
architecture/auth-model ✓ two levels, specific
182
+
architecture/auth-model-v2 ✓ version in description
183
+
architecture/auth/model/detail ✗ three levels — flatten to two
184
+
```
185
+
186
+
### Lifecycle and pruning
187
+
188
+
Topic keys are not pruned automatically. An observation updated via upsert keeps a single row with the latest content and an incremented `revision_count`. Use `mem_delete` to remove an observation (soft-delete by default) when a topic is no longer relevant. Soft-deleted observations are excluded from search and context but their IDs remain in the store for audit purposes. Use `--hard` to remove them permanently.
189
+
190
+
### Scope interaction
191
+
192
+
`topic_key` upsert is scoped to `project + scope + topic_key`. The same key used with different scopes creates independent observations:
193
+
194
+
```
195
+
project=engram, scope=project, topic_key=architecture/auth-model → observation A
196
+
project=engram, scope=personal, topic_key=architecture/auth-model → observation B (independent)
197
+
```
117
198
118
-
-`architecture/*` for architecture/design/ADR-like changes
119
-
-`bug/*` for fixes, regressions, errors, panics
120
-
-`decision/*`, `pattern/*`, `config/*`, `discovery/*`, `learning/*` when detected
199
+
This means a `personal` note on the same topic does not overwrite the shared `project` observation.
0 commit comments