@cairnkeep/cli 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/CONTRIBUTING.md +6 -1
- package/README.md +43 -0
- package/docs/building-an-overlay.md +9 -0
- package/docs/domain-knowledge.md +14 -10
- package/docs/operating.md +2 -0
- package/docs/overlay-distributions.md +97 -0
- package/docs/privacy-and-data-flow.md +49 -0
- package/docs/releasing.md +33 -0
- package/docs/storage.md +24 -0
- package/examples/anythingllm/README.md +66 -0
- package/examples/anythingllm/anythingllm-projects.example.json +30 -0
- package/examples/anythingllm/sync_to_anythingllm.py +596 -0
- package/examples/overlay-distribution/cairnkeep.overlay.json +25 -0
- package/mcp-memory-server/dist/index.js +3 -4
- package/package.json +7 -3
- package/schemas/cairnkeep-overlay.schema.json +79 -0
- package/scripts/probe-memory-server.mjs +17 -5
- package/scripts/smoke-mcp-boot.sh +6 -13
- package/scripts/test-overlay-schema.sh +41 -0
- package/scripts/test-package-install.sh +4 -0
- package/templates/env.example.template +6 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable user-facing changes are documented here. This project follows
|
|
4
|
+
[Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## [1.1.2] - 2026-07-14
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Define a provider-neutral managed-distribution contract for private overlays.
|
|
11
|
+
- Ship a versioned overlay manifest schema and local-first example.
|
|
12
|
+
- Document wrapper commands, profile locks, data-routing diagnostics, private
|
|
13
|
+
registry delivery, package hygiene, fleet migration, and rollback practices.
|
|
14
|
+
|
|
15
|
+
## [1.1.1] - 2026-07-14
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Ship and resolve the default document-RAG sync helper from the npm package,
|
|
20
|
+
with user-owned XDG config/state paths and legacy-path compatibility.
|
|
21
|
+
- Make repository CI install locked root dependencies before running checks.
|
|
22
|
+
- Make the clean macOS bootstrap test create its target directory explicitly.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Add release-to-npm automation with provenance, tarball, and SBOM artifacts.
|
|
27
|
+
- Document supported clients, platforms, storage placement, and optional data
|
|
28
|
+
flows more explicitly.
|
|
29
|
+
- Add community contribution, support, and conduct templates.
|
|
30
|
+
|
|
31
|
+
## [1.1.0] - 2026-07-13
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Add authenticated remote HTTP memory with stable per-project session routing.
|
|
36
|
+
- Add explicit client routing headers for scopes and document-RAG workspaces.
|
|
37
|
+
- Document local, remote, export, backup, and bearer-token deployment models.
|
|
38
|
+
|
|
39
|
+
## [1.0.5] - 2026-07-13
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- Make the npm tarball install self-contained and verify it on clean systems.
|
|
44
|
+
- Preserve executable permissions and Bash 3.2 portability on macOS.
|
|
45
|
+
- Add backup-first uninstall and SQLite-safe memory export/import guidance.
|
|
46
|
+
|
|
47
|
+
[1.1.1]: https://github.com/cairnkeep/cairnkeep/compare/v1.1.0...v1.1.1
|
|
48
|
+
[1.1.0]: https://github.com/cairnkeep/cairnkeep/compare/v1.0.5...v1.1.0
|
|
49
|
+
[1.0.5]: https://github.com/cairnkeep/cairnkeep/compare/v1.0.4...v1.0.5
|
package/CONTRIBUTING.md
CHANGED
|
@@ -15,7 +15,9 @@ Contributions are welcome through GitHub issues and pull requests.
|
|
|
15
15
|
|
|
16
16
|
## Development setup
|
|
17
17
|
|
|
18
|
-
The memory server requires Node.js 18 or newer. Node.js
|
|
18
|
+
The memory server requires Node.js 18 or newer. Node.js 22 or 24 is recommended
|
|
19
|
+
for development; current CI uses Node.js 24 and retains a clean Node.js 18
|
|
20
|
+
compatibility boot check.
|
|
19
21
|
|
|
20
22
|
```bash
|
|
21
23
|
git clone https://github.com/cairnkeep/cairnkeep.git
|
|
@@ -47,3 +49,6 @@ endpoints. They are not part of the default offline test suite.
|
|
|
47
49
|
|
|
48
50
|
By contributing, you agree that your contribution is licensed under the
|
|
49
51
|
Apache License 2.0 found in [LICENSE](LICENSE).
|
|
52
|
+
|
|
53
|
+
Release publishing is maintainer-only and documented in
|
|
54
|
+
[docs/releasing.md](docs/releasing.md).
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Cairnkeep
|
|
2
2
|
|
|
3
|
+
[](https://github.com/cairnkeep/cairnkeep/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@cairnkeep/cli)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
> A durable, harness-agnostic **memory + context layer** for coding agents.
|
|
4
8
|
|
|
5
9
|
A *cairn* is a stack of stones left as a trail marker for whoever follows; a
|
|
@@ -20,6 +24,23 @@ a thin routing seam (`route_check`), both of which delegate to
|
|
|
20
24
|
[token-miser](https://github.com/cairnkeep/token-miser), a public
|
|
21
25
|
cairnkeep-org sibling project.
|
|
22
26
|
|
|
27
|
+
## Compatibility
|
|
28
|
+
|
|
29
|
+
Node.js 22 or 24 is recommended. Node.js 18 and 20 remain compatible for the
|
|
30
|
+
1.x line but are end-of-life upstream; the minimum will move in the next major
|
|
31
|
+
release.
|
|
32
|
+
|
|
33
|
+
| Client or platform | Support level |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Claude Code on Linux/macOS | Memory server plus commands, agents, hooks, and launchers |
|
|
36
|
+
| OpenCode on Linux/macOS | Memory server plus commands, plugins, hooks, and launchers |
|
|
37
|
+
| Codex CLI | Memory MCP server; no Cairnkeep operating-layer assets |
|
|
38
|
+
| Other MCP clients | Memory and optional domain-knowledge MCP tools |
|
|
39
|
+
| Native Windows | Not supported by the Bash-based installer; use WSL (not yet CI-verified) |
|
|
40
|
+
|
|
41
|
+
Linux, macOS, Bash 3.2 portability, and a clean Node 18 compatibility install
|
|
42
|
+
are exercised in CI.
|
|
43
|
+
|
|
23
44
|
## Components
|
|
24
45
|
|
|
25
46
|
- **`mcp-memory-server/`** — an MCP server exposing durable, scoped memory
|
|
@@ -85,6 +106,19 @@ cd /path/to/project && cairn doctor
|
|
|
85
106
|
./.ai/start-claude.sh
|
|
86
107
|
```
|
|
87
108
|
|
|
109
|
+
After setup, the basic workflow is intentionally small:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
> /remember Use transactional migrations for schema changes
|
|
113
|
+
Stored as patterns/transactional-migrations.
|
|
114
|
+
|
|
115
|
+
> /recall transactional migrations
|
|
116
|
+
patterns/transactional-migrations: Use transactional migrations for schema changes
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The exact command rendering depends on the client. Any MCP client can call
|
|
120
|
+
`memory_write` and `memory_search` directly.
|
|
121
|
+
|
|
88
122
|
Prefer working from a clone? Build the server with `cd mcp-memory-server && npm
|
|
89
123
|
install && npm run build`, then use `scripts/sync-claude-assets.sh` and
|
|
90
124
|
`bin/cairn` in place of the installed `cairn`.
|
|
@@ -139,16 +173,25 @@ search):
|
|
|
139
173
|
| `CAIRN_EXPLORE_REPO_ROOT` | Default repo root for `context_explore` when no per-call `repo_root` is given |
|
|
140
174
|
| `CAIRN_EXTRA_SETTINGS` | Optional settings/config file the launcher layers onto the harness (wrapper seam) |
|
|
141
175
|
| `CAIRN_ANYTHINGLLM_SYNC_SCRIPT` | Override path to the domain-knowledge sync script (when the integration lives outside the repo) |
|
|
176
|
+
| `CAIRN_ANYTHINGLLM_PROJECTS_FILE` | Override path to the bundled sync script's project configuration |
|
|
177
|
+
| `CAIRN_ANYTHINGLLM_STATE_FILE` | Override path to the bundled sync script's incremental state |
|
|
142
178
|
|
|
143
179
|
Without an API key, search degrades gracefully to substring matching.
|
|
180
|
+
There is no Cairnkeep telemetry. Optional extraction, embeddings, document RAG,
|
|
181
|
+
remote memory, and delegated exploration can send content to endpoints you
|
|
182
|
+
configure. Review [Privacy and data flow](docs/privacy-and-data-flow.md) before
|
|
183
|
+
enabling them.
|
|
144
184
|
|
|
145
185
|
## More
|
|
146
186
|
|
|
147
187
|
- **Optional document RAG** (`domain_knowledge_*` via AnythingLLM) — [docs/domain-knowledge.md](docs/domain-knowledge.md)
|
|
148
188
|
- **Building a private overlay** (wrap cairnkeep for your org/provider) — [docs/building-an-overlay.md](docs/building-an-overlay.md)
|
|
189
|
+
- **Managed overlay distributions** (wrapper CLI, policy lock, private registry, rollback) — [docs/overlay-distributions.md](docs/overlay-distributions.md)
|
|
149
190
|
- **Full operating guide** — [docs/operating.md](docs/operating.md)
|
|
150
191
|
- **Memory storage and deployment** — [docs/storage.md](docs/storage.md)
|
|
192
|
+
- **Privacy and data flow** — [docs/privacy-and-data-flow.md](docs/privacy-and-data-flow.md)
|
|
151
193
|
- **Git providers** — [docs/git-providers.md](docs/git-providers.md)
|
|
194
|
+
- **Support** — [SUPPORT.md](SUPPORT.md)
|
|
152
195
|
- **Contributing** — [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
153
196
|
- **Security policy** — [SECURITY.md](SECURITY.md)
|
|
154
197
|
|
|
@@ -6,6 +6,11 @@ credentials, and no organization-specific launchers. Everything specific to
|
|
|
6
6
|
launchers, policy — belongs in a small private **overlay** that wraps cairnkeep.
|
|
7
7
|
This guide shows the pattern.
|
|
8
8
|
|
|
9
|
+
For multi-machine or organization-wide use, package the overlay as a managed
|
|
10
|
+
distribution that owns the enrolled machine's `cairn` command. See
|
|
11
|
+
[Managed Cairnkeep distributions](overlay-distributions.md) for the command,
|
|
12
|
+
manifest, profile-lock, private-registry, and rollback contract.
|
|
13
|
+
|
|
9
14
|
## Principles
|
|
10
15
|
|
|
11
16
|
1. **Consume, don't fork.** Treat cairnkeep as an upstream dependency: install it
|
|
@@ -122,3 +127,7 @@ secret storage, not generated project files.
|
|
|
122
127
|
- [ ] Operating layer scoped as intended (global vs `--live-root`)
|
|
123
128
|
- [ ] Optional integrations wired only where wanted
|
|
124
129
|
- [ ] A single documented command takes a fresh machine to a working setup
|
|
130
|
+
- [ ] Managed machines resolve `cairn` to the overlay distribution, not raw core
|
|
131
|
+
- [ ] `cairn config explain` reports memory and RAG destinations without secrets
|
|
132
|
+
- [ ] A project profile lock prevents silent cross-overlay reconfiguration
|
|
133
|
+
- [ ] Private packages reject public-registry publication and exclude runtime data
|
package/docs/domain-knowledge.md
CHANGED
|
@@ -28,7 +28,9 @@ work exactly the same without them.
|
|
|
28
28
|
|---|---|
|
|
29
29
|
| `ANYTHINGLLM_API_KEY` | **Required** for the domain-knowledge tools. Unset → the tools error at call time (everything else works). |
|
|
30
30
|
| `ANYTHINGLLM_BASE_URL` | AnythingLLM base URL. Default `http://localhost:3001`. |
|
|
31
|
-
| `CAIRN_ANYTHINGLLM_SYNC_SCRIPT` |
|
|
31
|
+
| `CAIRN_ANYTHINGLLM_SYNC_SCRIPT` | Optional path to a custom document-sync script. Unset -> `domain_knowledge_sync` uses the bundled deployment-neutral example. |
|
|
32
|
+
| `CAIRN_ANYTHINGLLM_PROJECTS_FILE` | Optional config path for the bundled sync script. Default `${XDG_CONFIG_HOME:-~/.config}/cairnkeep/anythingllm-projects.json`. |
|
|
33
|
+
| `CAIRN_ANYTHINGLLM_STATE_FILE` | Optional state path for the bundled sync script. Default `${XDG_STATE_HOME:-~/.local/state}/cairnkeep/anythingllm-sync.json`. |
|
|
32
34
|
|
|
33
35
|
The workspaces the tools target come from the project's **memory config** — the
|
|
34
36
|
first of `.agent/memory.json`, `.opencode/memory.json`, `.claude/memory.json`, or
|
|
@@ -73,10 +75,10 @@ returns a grounded answer.
|
|
|
73
75
|
|
|
74
76
|
## Setup (sync / embedding)
|
|
75
77
|
|
|
76
|
-
`domain_knowledge_sync` shells out to a document-upload/embed script.
|
|
77
|
-
|
|
78
|
-
deployment-specific,
|
|
79
|
-
at
|
|
78
|
+
`domain_knowledge_sync` shells out to a document-upload/embed script. Cairnkeep
|
|
79
|
+
ships a deployment-neutral example that reads its project mapping from a config
|
|
80
|
+
file. For deployment-specific authentication, checkout rules, or document
|
|
81
|
+
selection, keep a customized script in your overlay and point Cairnkeep at it:
|
|
80
82
|
|
|
81
83
|
```bash
|
|
82
84
|
CAIRN_ANYTHINGLLM_SYNC_SCRIPT=/abs/path/to/your/sync_to_anythingllm.py
|
|
@@ -86,11 +88,13 @@ The script receives the workspace slug and is expected to upload + embed the
|
|
|
86
88
|
project's documents into that AnythingLLM workspace. See
|
|
87
89
|
[building-an-overlay.md](building-an-overlay.md) for the wrapper pattern.
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
[`examples/anythingllm/`](../examples/anythingllm/): an incremental
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
The bundled default lives in
|
|
92
|
+
[`examples/anythingllm/`](../examples/anythingllm/): an incremental,
|
|
93
|
+
SHA-256-tracked multi-project sync script plus a config schema. Put a customized
|
|
94
|
+
copy of the example JSON at the default user config path, or set
|
|
95
|
+
`CAIRN_ANYTHINGLLM_PROJECTS_FILE`. Existing custom scripts with configuration
|
|
96
|
+
and state beside the script retain that legacy behavior. To customize the
|
|
97
|
+
implementation itself, set `CAIRN_ANYTHINGLLM_SYNC_SCRIPT` to the adapted copy.
|
|
94
98
|
|
|
95
99
|
## Not using RAG?
|
|
96
100
|
|
package/docs/operating.md
CHANGED
|
@@ -156,6 +156,8 @@ vendor or host.
|
|
|
156
156
|
| `ANYTHINGLLM_API_KEY` | Required to enable the optional `domain_knowledge_*` RAG tools (unset → those tools error at call time; nothing else affected). See [domain-knowledge.md](domain-knowledge.md) |
|
|
157
157
|
| `ANYTHINGLLM_BASE_URL` | AnythingLLM base URL for `domain_knowledge_*` (default `http://localhost:3001`) |
|
|
158
158
|
| `CAIRN_ANYTHINGLLM_SYNC_SCRIPT` | Override path to the `domain_knowledge_sync` document-sync script (unset → in-repo default) |
|
|
159
|
+
| `CAIRN_ANYTHINGLLM_PROJECTS_FILE` | Override path to the bundled sync script's project configuration |
|
|
160
|
+
| `CAIRN_ANYTHINGLLM_STATE_FILE` | Override path to the bundled sync script's incremental state |
|
|
159
161
|
|
|
160
162
|
### Domain knowledge (RAG via AnythingLLM, opt-in)
|
|
161
163
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Managed Cairnkeep distributions
|
|
2
|
+
|
|
3
|
+
A private overlay becomes significantly easier to operate when it is treated as
|
|
4
|
+
a **distribution** rather than a directory of configuration fragments. The
|
|
5
|
+
distribution owns the `cairn` command on enrolled machines while consuming the
|
|
6
|
+
public `@cairnkeep/cli` package as an exact dependency.
|
|
7
|
+
|
|
8
|
+
This keeps Cairnkeep neutral and upgradeable. The distribution owns environment
|
|
9
|
+
policy, data routing, launchers, private integrations, and delivery through an
|
|
10
|
+
approved package registry. It should not patch or fork the core implementation.
|
|
11
|
+
|
|
12
|
+
## Command contract
|
|
13
|
+
|
|
14
|
+
An overlay package can expose its own `cairn` binary and delegate to its pinned
|
|
15
|
+
core dependency:
|
|
16
|
+
|
|
17
|
+
- `cairn bootstrap <project>` runs core bootstrap and then applies the overlay.
|
|
18
|
+
- `cairn doctor` runs core diagnostics plus overlay policy checks.
|
|
19
|
+
- `cairn config explain` reports effective storage and service destinations
|
|
20
|
+
without printing credentials.
|
|
21
|
+
- `cairn overlay info` reports distribution and core versions separately.
|
|
22
|
+
- `cairn core <command>` explicitly bypasses overlay behavior for diagnosis.
|
|
23
|
+
- Other commands, especially `memory-server`, delegate to the pinned core with
|
|
24
|
+
the validated machine and project environment loaded.
|
|
25
|
+
|
|
26
|
+
Do not replace core source files. A small wrapper preserves the upstream command
|
|
27
|
+
surface while making managed bootstrap the default users reasonably expect.
|
|
28
|
+
|
|
29
|
+
## Distribution manifest
|
|
30
|
+
|
|
31
|
+
Store non-secret capabilities and data-routing policy in
|
|
32
|
+
`cairnkeep.overlay.json`. The reference schema is
|
|
33
|
+
[`schemas/cairnkeep-overlay.schema.json`](../schemas/cairnkeep-overlay.schema.json),
|
|
34
|
+
with a complete example in
|
|
35
|
+
[`examples/overlay-distribution`](../examples/overlay-distribution/cairnkeep.overlay.json).
|
|
36
|
+
|
|
37
|
+
The distribution version and core version are independent. Pin the core exactly
|
|
38
|
+
and test every distribution release against it.
|
|
39
|
+
|
|
40
|
+
After a successful bootstrap, write an untracked project profile lock containing
|
|
41
|
+
the distribution identity, versions, and non-secret policy. Refuse a different
|
|
42
|
+
overlay identity before making changes. A stale lock should make `doctor` fail
|
|
43
|
+
with an instruction to rerun managed bootstrap.
|
|
44
|
+
|
|
45
|
+
## Configuration and secrets
|
|
46
|
+
|
|
47
|
+
Use two explicit configuration layers:
|
|
48
|
+
|
|
49
|
+
1. A mode-0600 machine profile in the user's configuration directory.
|
|
50
|
+
2. An optional untracked, mode-0600 project override in `.ai/.env`.
|
|
51
|
+
|
|
52
|
+
Validate both files before sourcing them: reject symlinks, permissive modes, and
|
|
53
|
+
tracked project files. The manifest and project lock must never contain tokens,
|
|
54
|
+
cookies, private keys, or credential-bearing URLs.
|
|
55
|
+
|
|
56
|
+
`cairn config explain` should answer these questions directly:
|
|
57
|
+
|
|
58
|
+
- Is memory local or remote?
|
|
59
|
+
- Which transport is used?
|
|
60
|
+
- Which directory or endpoint receives memory?
|
|
61
|
+
- Is document RAG disabled, local, or remote?
|
|
62
|
+
- Which configuration files selected those values?
|
|
63
|
+
|
|
64
|
+
## Private package delivery
|
|
65
|
+
|
|
66
|
+
A distribution can be an ordinary scoped npm package with:
|
|
67
|
+
|
|
68
|
+
- `@cairnkeep/cli` as an exact dependency;
|
|
69
|
+
- a `bin.cairn` entry for the wrapper;
|
|
70
|
+
- `publishConfig.access` set to `restricted`;
|
|
71
|
+
- an explicit guard that rejects the public npm registry;
|
|
72
|
+
- registry credentials supplied by a user credential helper or protected CI
|
|
73
|
+
variables, never by repository files.
|
|
74
|
+
|
|
75
|
+
Support installation from a private registry, a reviewed tarball, and a local
|
|
76
|
+
checkout. Avoid `postinstall` enrollment: installing a package must not silently
|
|
77
|
+
replace machine policy. Provide an explicit enrollment command with a retained
|
|
78
|
+
rollback target.
|
|
79
|
+
|
|
80
|
+
## Release and fleet safety
|
|
81
|
+
|
|
82
|
+
Every release should verify:
|
|
83
|
+
|
|
84
|
+
- fresh managed bootstrap and idempotent reruns;
|
|
85
|
+
- core delegation and the explicit core escape hatch;
|
|
86
|
+
- profile mismatch rejection before mutation;
|
|
87
|
+
- storage and RAG policy enforcement;
|
|
88
|
+
- secret and runtime-artifact exclusion from the package;
|
|
89
|
+
- package installation from the produced tarball;
|
|
90
|
+
- checksums, an SBOM, and an immutable version;
|
|
91
|
+
- pre-upgrade and post-upgrade `doctor` results;
|
|
92
|
+
- rollback to the previous command or package version.
|
|
93
|
+
|
|
94
|
+
For a fleet migration, update the machine operating layer once, reapply managed
|
|
95
|
+
bootstrap to projects without altering tracked Git status, and validate every
|
|
96
|
+
profile lock. Storage migrations require their own backup, integrity, canary,
|
|
97
|
+
and rollback procedure; changing an overlay version alone must not move data.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Privacy and data flow
|
|
2
|
+
|
|
3
|
+
Cairnkeep has no telemetry, analytics collector, hosted control plane, or
|
|
4
|
+
automatic remote-service discovery. A default local stdio installation stores
|
|
5
|
+
memory in SQLite on the machine running the MCP server and makes no model or RAG
|
|
6
|
+
request unless the corresponding endpoint and credential are configured.
|
|
7
|
+
|
|
8
|
+
## Data flows
|
|
9
|
+
|
|
10
|
+
| Feature | Data that can leave the server machine | Destination |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| Local substring search | None | Local SQLite only |
|
|
13
|
+
| Embedding-ranked search | Stored memory values that are not cached, plus the search query | `CAIRN_MEMORY_EMBEDDING_URL` or `CAIRN_LLM_API_URL` |
|
|
14
|
+
| `memory_extract` | The transcript supplied to the tool | `CAIRN_LLM_API_URL` |
|
|
15
|
+
| `domain_knowledge_query` | Workspace slug and query | `ANYTHINGLLM_BASE_URL` |
|
|
16
|
+
| `domain_knowledge_sync` | Files selected by the sync configuration | `ANYTHINGLLM_BASE_URL` |
|
|
17
|
+
| `route_check` | A health request, with no memory or prompt content | `CAIRN_ROUTE_ENDPOINT` |
|
|
18
|
+
| `context_explore` | Repository path and query are passed to the configured local executable | `CAIRN_EXPLORE_BINARY`; any further data flow is controlled by that tool |
|
|
19
|
+
| Remote HTTP memory | MCP requests and responses, including memory content | The explicitly registered Cairnkeep HTTP server |
|
|
20
|
+
|
|
21
|
+
Model endpoints may be local or remote. Cairnkeep cannot determine a provider's
|
|
22
|
+
retention, training, or logging policy; verify it before sending confidential
|
|
23
|
+
material. Disabling `CAIRN_LLM_API_KEY`, `ANYTHINGLLM_API_KEY`, remote HTTP
|
|
24
|
+
registration, and delegated tools keeps the core memory workflow local.
|
|
25
|
+
|
|
26
|
+
## Data at rest
|
|
27
|
+
|
|
28
|
+
Memories are stored in SQLite databases. They are not encrypted by Cairnkeep at
|
|
29
|
+
the application layer. Use operating-system disk encryption, restrictive file
|
|
30
|
+
permissions, encrypted backups, and host access controls appropriate to the
|
|
31
|
+
sensitivity of the material. SQLite `-wal` and `-shm` sidecars and exported
|
|
32
|
+
archives can contain sensitive content too.
|
|
33
|
+
|
|
34
|
+
Project-scoped and named/global database locations are documented in
|
|
35
|
+
[Memory storage and deployment](storage.md). A remote client stores memory on
|
|
36
|
+
the remote server host; changing a storage environment variable on the client
|
|
37
|
+
does not relocate that server's databases.
|
|
38
|
+
|
|
39
|
+
## Credentials and transport
|
|
40
|
+
|
|
41
|
+
Keep API keys and bearer tokens out of repositories and command output. Load
|
|
42
|
+
them from a secret manager or protected environment file. For remote HTTP mode,
|
|
43
|
+
use TLS or an encrypted private network and keep the raw listener on loopback.
|
|
44
|
+
One HTTP bearer token grants access to the entire server; Cairnkeep does not
|
|
45
|
+
provide tenant isolation or per-scope authorization.
|
|
46
|
+
|
|
47
|
+
Before sharing diagnostics, remove credentials, private endpoints, database
|
|
48
|
+
files, memory values, local paths, and project names. Report vulnerabilities
|
|
49
|
+
through the private channel in [SECURITY.md](../SECURITY.md).
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
Publishing is driven by a GitHub Release. Maintainers do not publish the package
|
|
4
|
+
from a workstation.
|
|
5
|
+
|
|
6
|
+
## Release contract
|
|
7
|
+
|
|
8
|
+
1. Update the root `package.json` version and `CHANGELOG.md` on a pull request.
|
|
9
|
+
2. Run `npm ci`, `npm run check:public`, and
|
|
10
|
+
`npm --prefix mcp-memory-server test`.
|
|
11
|
+
3. Merge only after every required CI check passes.
|
|
12
|
+
4. Publish a GitHub Release whose tag is exactly `v<package.json version>`.
|
|
13
|
+
5. The `Publish release` workflow checks out that immutable tag, repeats the
|
|
14
|
+
tests, and publishes `@cairnkeep/cli` with npm provenance.
|
|
15
|
+
6. The workflow attaches the npm tarball, a CycloneDX SBOM, and SHA-256 checksums
|
|
16
|
+
to the GitHub Release.
|
|
17
|
+
|
|
18
|
+
Stable versions must use a stable GitHub Release and publish to npm's `latest`
|
|
19
|
+
tag. SemVer prerelease versions must use a GitHub prerelease and publish to
|
|
20
|
+
`next`. A mismatch fails before publication.
|
|
21
|
+
|
|
22
|
+
The workflow is safe to rerun: it skips `npm publish` when that exact version is
|
|
23
|
+
already present, then regenerates and replaces the release artifacts.
|
|
24
|
+
|
|
25
|
+
## Repository configuration
|
|
26
|
+
|
|
27
|
+
The repository must provide an `NPM_TOKEN` Actions secret authorized to publish
|
|
28
|
+
`@cairnkeep/cli`. Keep that credential out of local files and rotate it according
|
|
29
|
+
to the npm account's security policy. The workflow grants only `contents: write`
|
|
30
|
+
and `id-token: write`; the latter is required for npm provenance.
|
|
31
|
+
|
|
32
|
+
Treat a published version as immutable. If a release is wrong, fix it in a new
|
|
33
|
+
version rather than moving its tag or replacing the npm package.
|
package/docs/storage.md
CHANGED
|
@@ -129,8 +129,18 @@ claude mcp remove cairn-memory -s user 2>/dev/null || true
|
|
|
129
129
|
claude mcp add --transport http -s user \
|
|
130
130
|
cairn-memory "$CAIRN_MEMORY_REMOTE_URL" \
|
|
131
131
|
--header "Authorization: Bearer $CAIRN_MEMORY_HTTP_TOKEN"
|
|
132
|
+
|
|
133
|
+
codex mcp remove cairn-memory 2>/dev/null || true
|
|
134
|
+
codex mcp add cairn-memory \
|
|
135
|
+
--url "$CAIRN_MEMORY_REMOTE_URL" \
|
|
136
|
+
--bearer-token-env-var CAIRN_MEMORY_HTTP_TOKEN
|
|
132
137
|
```
|
|
133
138
|
|
|
139
|
+
Codex reads the bearer token from the named environment variable when it
|
|
140
|
+
starts. Do not run `codex mcp login cairn-memory`: that command starts an OAuth
|
|
141
|
+
flow, while Cairnkeep intentionally uses a static bearer token and advertises
|
|
142
|
+
no OAuth authorization endpoint.
|
|
143
|
+
|
|
134
144
|
OpenCode is configured separately in its per-user `opencode.json`. It supports
|
|
135
145
|
environment references in remote MCP headers, so the token does not need to be
|
|
136
146
|
written literally into the JSON:
|
|
@@ -161,3 +171,17 @@ expands `${VAR}` references in project `.mcp.json` URL and header values;
|
|
|
161
171
|
OpenCode uses `{env:VAR}` references. A private overlay should generate and
|
|
162
172
|
merge these files so secrets remain in the process environment rather than the
|
|
163
173
|
repository.
|
|
174
|
+
|
|
175
|
+
For Codex, put the routing configuration in the trusted project's private
|
|
176
|
+
`.codex/config.toml` and exclude it from version control:
|
|
177
|
+
|
|
178
|
+
```toml
|
|
179
|
+
[mcp_servers.cairn-memory]
|
|
180
|
+
url = "https://memory.example.com/mcp"
|
|
181
|
+
bearer_token_env_var = "CAIRN_MEMORY_HTTP_TOKEN"
|
|
182
|
+
|
|
183
|
+
[mcp_servers.cairn-memory.http_headers]
|
|
184
|
+
"X-Cairn-Project" = "example-project"
|
|
185
|
+
"X-Cairn-Scopes" = "identity,personal,project"
|
|
186
|
+
"X-Cairn-AnythingLLM-Workspaces" = "engineering-patterns"
|
|
187
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# AnythingLLM sync — reference example
|
|
2
|
+
|
|
3
|
+
The bundled reference implementation of the document-sync script that
|
|
4
|
+
Cairnkeep's `domain_knowledge_sync` tool shells out to. It is a usable,
|
|
5
|
+
deployment-neutral starting point; copy and adapt it when endpoint,
|
|
6
|
+
authentication, or include/exclude rules are deployment-specific.
|
|
7
|
+
|
|
8
|
+
See [`../../docs/domain-knowledge.md`](../../docs/domain-knowledge.md) for the
|
|
9
|
+
full RAG picture.
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
Incrementally syncs each configured project's docs into its own AnythingLLM
|
|
14
|
+
workspace: creates the workspace, uploads changed files (tracked by sha256),
|
|
15
|
+
embeds them, and removes docs that disappeared. Supports `--dry-run`, `--full`,
|
|
16
|
+
`--replace`, `--rebuild-state`, `--list`, and `--project <slug>`.
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
1. Requires Python 3 and `requests` (`pip install requests`).
|
|
21
|
+
2. Copy the config to the default user config location and fill in your
|
|
22
|
+
projects:
|
|
23
|
+
```bash
|
|
24
|
+
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/cairnkeep"
|
|
25
|
+
cp anythingllm-projects.example.json \
|
|
26
|
+
"${XDG_CONFIG_HOME:-$HOME/.config}/cairnkeep/anythingllm-projects.json"
|
|
27
|
+
# edit: set each project's absolute path, slug, and include/exclude globs
|
|
28
|
+
```
|
|
29
|
+
3. Point at your AnythingLLM instance:
|
|
30
|
+
```bash
|
|
31
|
+
export ANYTHINGLLM_BASE_URL=http://localhost:3001 # default
|
|
32
|
+
export ANYTHINGLLM_API_KEY=<your AnythingLLM API key>
|
|
33
|
+
```
|
|
34
|
+
4. First upload, then keep it in sync:
|
|
35
|
+
```bash
|
|
36
|
+
python3 sync_to_anythingllm.py --full --project my-project
|
|
37
|
+
python3 sync_to_anythingllm.py # incremental, all projects
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Wiring into cairnkeep
|
|
41
|
+
|
|
42
|
+
The installed server uses this script by default. To use an adapted copy, set:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
CAIRN_ANYTHINGLLM_SYNC_SCRIPT=/abs/path/to/sync_to_anythingllm.py
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Override the user-owned configuration or state locations when needed:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
CAIRN_ANYTHINGLLM_PROJECTS_FILE=/abs/path/to/anythingllm-projects.json
|
|
52
|
+
CAIRN_ANYTHINGLLM_STATE_FILE=/abs/path/to/anythingllm-sync.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For backward compatibility, an existing `anythingllm-projects.json` beside a
|
|
56
|
+
customized script and its `.anythingllm-sync.json` state are still used when the
|
|
57
|
+
override variables are unset.
|
|
58
|
+
|
|
59
|
+
## Files
|
|
60
|
+
|
|
61
|
+
| File | Committed? | Notes |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `sync_to_anythingllm.py` | yes | the script |
|
|
64
|
+
| `anythingllm-projects.example.json` | yes | schema template |
|
|
65
|
+
| `anythingllm-projects.json` | **no** | User-owned config; defaults under the XDG config directory |
|
|
66
|
+
| `anythingllm-sync.json` | **no** | Machine-local SHA-256 state; defaults under the XDG state directory |
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projects": [
|
|
3
|
+
{
|
|
4
|
+
"slug": "my-project",
|
|
5
|
+
"display_name": "My Project Documentation",
|
|
6
|
+
"path": "/abs/path/to/my-project",
|
|
7
|
+
"patterns": [
|
|
8
|
+
"README.md",
|
|
9
|
+
"docs/**/*.md"
|
|
10
|
+
],
|
|
11
|
+
"exclude_patterns": [
|
|
12
|
+
"CHANGELOG.md",
|
|
13
|
+
"LICENSE.md"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"slug": "another-project",
|
|
18
|
+
"display_name": "Another Project Docs",
|
|
19
|
+
"path": "/abs/path/to/another-project",
|
|
20
|
+
"patterns": [
|
|
21
|
+
"AGENTS.md",
|
|
22
|
+
"docs/**/*.md",
|
|
23
|
+
".planning/wiki/**/*.md"
|
|
24
|
+
],
|
|
25
|
+
"exclude_patterns": [
|
|
26
|
+
".planning/wiki/tmp/**"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|