memoryrail 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,163 @@
1
+ # Connect your agent
2
+
3
+ MemoryRail reaches an agent in two ways:
4
+
5
+ 1. **The MCP server** (`memoryrail serve`): the agent calls tools like `precheck`, `recall` and `remember`. This is the full experience.
6
+ 2. **Generated instruction files** (`memoryrail sync`): your rules, decisions and failed attempts are written into `AGENTS.md`, `CLAUDE.md` and `.cursor/rules/memoryrail.mdc`. Agents that read those files see the memory even without MCP, but can't write to it.
7
+
8
+ Install the CLI first: `npm install -g memoryrail` (Node 20 or newer). Then pick your client below.
9
+
10
+ > **How much of this is tested.** The server is tested with the official MCP SDK client over stdio, and the config shapes below were checked against each vendor's documentation (linked in each section, checked 2026-10-10). We have **not** run Codex or any Copilot surface against MemoryRail ourselves. If a snippet doesn't work, please open an issue with the client version and the error.
11
+
12
+ ## How the server finds your memory
13
+
14
+ The server looks for `.memoryrail/` starting in the directory the client launches it in, then walks up. If your client launches servers somewhere else (a user-level config shared by many projects, or a cloud runner), point it at the repo:
15
+
16
+ ```
17
+ memoryrail serve --root /path/to/repo
18
+ ```
19
+
20
+ or set `MEMORYRAIL_ROOT=/path/to/repo` in the server's environment.
21
+
22
+ ## Claude Code
23
+
24
+ ```sh
25
+ memoryrail install claude
26
+ ```
27
+
28
+ This adds a `memoryrail` server to the project's `.mcp.json`, keeping any other servers. Restart Claude Code. `CLAUDE.md` is updated by `memoryrail sync`.
29
+
30
+ ## Cursor
31
+
32
+ ```sh
33
+ memoryrail install cursor
34
+ ```
35
+
36
+ This adds the server to `.cursor/mcp.json`. `memoryrail sync` also writes `.cursor/rules/memoryrail.mdc` (always applied).
37
+
38
+ ## OpenAI Codex
39
+
40
+ Codex reads MCP servers from `~/.codex/config.toml`, or from `.codex/config.toml` in a project (trusted projects only). Add one with the CLI:
41
+
42
+ ```sh
43
+ codex mcp add memoryrail -- memoryrail serve
44
+ ```
45
+
46
+ or edit the TOML:
47
+
48
+ ```toml
49
+ [mcp_servers.memoryrail]
50
+ command = "memoryrail"
51
+ args = ["serve"]
52
+ ```
53
+
54
+ If you haven't installed MemoryRail globally, use `command = "npx"` and `args = ["-y", "memoryrail", "serve"]`. The server looks for `.memoryrail/` from the directory Codex launches it in (we haven't confirmed which directory that is for a user-level config), so for a single project you can pin it with `args = ["serve", "--root", "/path/to/repo"]`.
55
+
56
+ **Instructions:** Codex reads `AGENTS.md` from the project root down to your working directory, which `memoryrail sync` writes. By default Codex **stops reading after 32 KiB** of combined instructions (`project_doc_max_bytes`), so a large memory can be silently cut off. `memoryrail doctor` warns when `AGENTS.md` passes 32 KiB; archive stale memories (`memoryrail forget <ref>`) or raise the limit in your Codex config.
57
+
58
+ Sources: [Codex MCP](https://developers.openai.com/codex/mcp), [Codex AGENTS.md](https://developers.openai.com/codex/guides/agents-md).
59
+
60
+ ## GitHub Copilot
61
+
62
+ Copilot has several surfaces, and they are configured differently.
63
+
64
+ ### Copilot in VS Code
65
+
66
+ Create `.vscode/mcp.json` in the workspace. The top-level key is `servers` (not `mcpServers`):
67
+
68
+ ```json
69
+ {
70
+ "servers": {
71
+ "memoryrail": {
72
+ "type": "stdio",
73
+ "command": "memoryrail",
74
+ "args": ["serve"]
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ MCP tools are available in Copilot's agent mode. VS Code starts the server with the workspace folder as its working directory by default, so no `--root` is needed.
81
+
82
+ Source: [VS Code MCP configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration).
83
+
84
+ ### Copilot CLI
85
+
86
+ ```sh
87
+ copilot mcp add memoryrail -- memoryrail serve
88
+ ```
89
+
90
+ This writes to `~/.copilot/mcp-config.json`. To configure it by hand, or per project in `.github/mcp.json`, the top-level key is `mcpServers` and each server has a `type`:
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "memoryrail": {
96
+ "type": "local",
97
+ "command": "memoryrail",
98
+ "args": ["serve"],
99
+ "tools": ["*"]
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ Copilot CLI can also read a project-level `.mcp.json`, but expects its own format. The entry that `memoryrail install claude` writes has no `type` field, which the Copilot CLI docs show, so use `copilot mcp add` or the JSON above for Copilot CLI instead of relying on that file.
106
+
107
+ Source: [Adding MCP servers for GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers).
108
+
109
+ ### Copilot cloud agent (assigned issues and pull requests)
110
+
111
+ The cloud agent doesn't read a file from your repo for MCP. A repository administrator pastes JSON into the repository's settings on GitHub.com (under Copilot, in the cloud/coding agent section; the exact menu name has changed between releases). `tools` is required:
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "memoryrail": {
117
+ "type": "local",
118
+ "command": "npx",
119
+ "args": ["-y", "memoryrail", "serve"],
120
+ "tools": ["resume", "precheck", "recall", "list_memories"]
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ Notes:
127
+
128
+ - The cloud agent runs on GitHub's side, not on your machine, so MemoryRail isn't installed there. Use `npx`.
129
+ - The example allows **read-only** tools. Add `"remember"` and `"handoff"` to let the agent write memory; its changes then appear in the pull request for you to review. Turning on `memoryrail config review agents` makes those writes wait for your approval.
130
+ - The cloud agent supports MCP **tools** only, not resources or prompts. MemoryRail exposes tools only, so nothing is lost.
131
+ - **Not verified:** which directory the cloud agent starts MCP servers in. If the server reports that it can't find `.memoryrail/`, add `"--root", "."` or the checkout path to `args`.
132
+
133
+ Source: [Configure MCP servers for the Copilot cloud agent](https://docs.github.com/en/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp).
134
+
135
+ ### Copilot instructions
136
+
137
+ - The Copilot cloud agent and Copilot CLI read `AGENTS.md` from the repository root, which `memoryrail sync` writes. ([Changelog](https://github.blog/changelog/2025-08-28-copilot-coding-agent-now-supports-agents-md-custom-instructions/))
138
+ - Copilot also reads **`.github/copilot-instructions.md`**. `sync` doesn't write that file by default. To have it written there too, add `--also`:
139
+
140
+ ```sh
141
+ memoryrail sync --also .github/copilot-instructions.md
142
+ ```
143
+
144
+ Pass the same flag to `sync --check` in CI. Existing content in that file is kept; MemoryRail only manages the block between its markers. ([Copilot custom instructions](https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot))
145
+
146
+ ## Any other MCP client
147
+
148
+ Register this as a stdio server in the client's MCP config:
149
+
150
+ ```
151
+ command: memoryrail
152
+ args: serve
153
+ ```
154
+
155
+ Clients differ in file name and top-level key (`mcpServers` or `servers`) and some require a `type`; check the client's docs. If the client can't use MCP, the same commands work in a terminal (`memoryrail precheck "..." --file path`), and any tool that reads `AGENTS.md` still gets the summary from `memoryrail sync`.
156
+
157
+ ## Check it worked
158
+
159
+ ```sh
160
+ memoryrail doctor
161
+ ```
162
+
163
+ reports whether memory is valid, synced, and registered for Claude Code or Cursor (it doesn't detect Codex or Copilot config). To test the server itself, ask your agent to call `list_memories`; it should return the memories in the repo.
package/docs/SPEC.md ADDED
@@ -0,0 +1,109 @@
1
+ # MemoryRail format, version 1
2
+
3
+ MemoryRail stores project memory as plain files in a repository so that people, git, and any AI coding agent can read and write it. This document is the contract. Tools that follow it interoperate, whether or not they use this package.
4
+
5
+ ## Layout
6
+
7
+ ```
8
+ .memoryrail/
9
+ config.json { "version": 1, "review": "off" }
10
+ memories/
11
+ 20261010-use-drizzle-over-prisma.md
12
+ 20261010-session-2026-10-10-17-30.md
13
+ ```
14
+
15
+ A repository is a MemoryRail project if it contains `.memoryrail/config.json`. Tools locate the nearest one by walking up from the working directory.
16
+
17
+ ## Memory files
18
+
19
+ One memory per file, named `<id>.md`. A file is YAML frontmatter followed by a free-form Markdown body.
20
+
21
+ ```markdown
22
+ ---
23
+ id: "20261010-use-drizzle-over-prisma"
24
+ type: "decision"
25
+ title: "Use Drizzle over Prisma"
26
+ status: "active"
27
+ created: "2026-10-10T17:30:00.000Z"
28
+ updated: "2026-10-10T17:30:00.000Z"
29
+ tags: ["db"]
30
+ links: ["src/db"]
31
+ ---
32
+
33
+ Edge deploys need a small runtime, and Prisma's engine is too large.
34
+ ```
35
+
36
+ Writers SHOULD encode every frontmatter value as JSON (which is valid YAML) so that files parse identically everywhere. Readers MUST accept any valid YAML scalar or flow sequence for these fields. The JSON Schema is at [`spec/memory.schema.json`](../spec/memory.schema.json).
37
+
38
+ ### Fields
39
+
40
+ | Field | Required | Meaning |
41
+ |---|---|---|
42
+ | `id` | yes | Unique id. MUST equal the file name without `.md`. By convention `YYYYMMDD-slug`. |
43
+ | `type` | yes | One of `decision`, `constraint`, `gotcha`, `attempt`, `thread`, `session`. |
44
+ | `title` | yes | One line. State the conclusion, not the topic. |
45
+ | `status` | yes | `active`, `proposed`, `superseded`, `archived`, or `resolved`. |
46
+ | `created`, `updated` | yes | ISO 8601 timestamps. |
47
+ | `tags` | no | Free-form labels. |
48
+ | `links` | no | Repo-relative POSIX paths the memory is about. Used for staleness detection. MUST NOT escape the repository. |
49
+ | `pinned` | no | If `true`, always surfaced first. Use sparingly. |
50
+ | `supersedes` | no | Id of the memory this one replaces. |
51
+ | `superseded_by` | no | Id of the memory that replaced this one. Set on the old memory. |
52
+
53
+ Unknown fields MUST be preserved by tools that rewrite files.
54
+
55
+ ### Types
56
+
57
+ - **decision**: a choice that was made and why. Treated as settled unless superseded.
58
+ - **constraint**: a rule to follow (conventions, things not to touch).
59
+ - **gotcha**: a mistake made once that should not be repeated.
60
+ - **attempt**: an approach that was tried and **failed**, with why. Surfaced by `precheck` so nobody retries it without a new reason.
61
+ - **thread**: unfinished work or an open question. Becomes `resolved` when done.
62
+ - **session**: an end-of-session handoff: what was done and the next steps.
63
+
64
+ ### Lifecycle
65
+
66
+ - Memories are never silently overwritten. To change a decision, create a new memory with `supersedes` set. The old one becomes `superseded` and gets `superseded_by`. Both stay in the repository, and git keeps the rest of the history.
67
+ - `archived` means "wrong or no longer relevant"; `resolved` applies to threads.
68
+ - `proposed` means written by an agent and **waiting for a human**. See Review gate.
69
+ - Only `active` memories are returned by default and written into generated agent files.
70
+
71
+ ## Short refs
72
+
73
+ Every memory has a short, citable handle: a three-letter type prefix and four hex characters of the SHA-1 of its `id`, e.g. `DEC-a3f9`. Prefixes: `DEC` decision, `CON` constraint, `GOT` gotcha, `ATT` attempt, `THR` thread, `SES` session. Refs are **derived, never stored**, so two branches cannot allocate the same one. Tools MUST accept a ref wherever an id is accepted, and MUST report an ambiguity instead of guessing if two memories share a ref.
74
+
75
+ ## Review gate
76
+
77
+ `config.json` may set `"review": "agents"`. Then durable memories (`decision`, `constraint`, `gotcha`, `attempt`) written by an agent are saved with `status: "proposed"` and are ignored by recall, precheck and sync until a human approves them (`status: "active"`) or rejects them (file deleted). A proposal with `supersedes` does **not** change the superseded memory until approval. The default is `"off"`: agent writes are active immediately and are reviewed in git like any change.
78
+
79
+ ## Secrets
80
+
81
+ Memory is committed and replayed into model context, so tools MUST refuse to write text that looks like a credential (private keys, cloud and API tokens, URL credentials, `password=...` style assignments) and SHOULD report which rule matched without echoing the value. A human-only override is allowed. Linters SHOULD flag existing files that match.
82
+
83
+ ## Precheck
84
+
85
+ Given a plan (free text) and/or the files about to change, `precheck` returns the active `constraint`, `attempt`, `gotcha` and `decision` memories that apply, most binding first. A memory applies if it is a pinned constraint, if one of its `links` is the changed path or a directory containing it, or if its text matches the plan. Agents are instructed to cite what they rely on as `[per REF]` and to stop and ask if a plan conflicts with a constraint or decision.
86
+
87
+ ## Generated agent files
88
+
89
+ `memoryrail sync` writes a managed block into `AGENTS.md`, `CLAUDE.md`, and `.cursor/rules/memoryrail.mdc`:
90
+
91
+ ```
92
+ <!-- memoryrail:start -->
93
+ ...generated, deterministic...
94
+ <!-- memoryrail:end -->
95
+ ```
96
+
97
+ Content outside the markers is never modified. The block lists active memories with their refs, followed by short usage instructions (precheck first, cite refs, stop on conflict, record failures). It is a pure function of the memories, with no timestamps, so `memoryrail sync --check` can fail CI when it is out of date.
98
+
99
+ ## Staleness
100
+
101
+ For each `active` memory and each entry in `links`:
102
+
103
+ - the path does not exist: `stale-link` (warning)
104
+ - the path's last git commit is newer than the memory's `updated`: `maybe-stale` (warning)
105
+ - the path resolves outside the repository: `link-outside-repo` (error)
106
+
107
+ ## Versioning
108
+
109
+ `config.json` carries `version`. Version 1 is this document. Breaking changes will increment it.
package/package.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "memoryrail",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Git-native project memory for coding agents. Plain Markdown in your repo, readable by people and any MCP-capable agent.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "homepage": "https://memoryrail.si",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/OutVersus/memoryrail.git"
11
+ },
12
+ "keywords": [
13
+ "mcp",
14
+ "ai-agents",
15
+ "memory",
16
+ "claude-code",
17
+ "cursor",
18
+ "agents-md",
19
+ "context"
20
+ ],
21
+ "bin": {
22
+ "memoryrail": "dist/cli.js"
23
+ },
24
+ "main": "dist/index.js",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "spec",
35
+ "docs",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "engines": {
40
+ "node": ">=20"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -p tsconfig.json",
44
+ "dev": "tsc -p tsconfig.json --watch",
45
+ "typecheck": "tsc -p tsconfig.json --noEmit",
46
+ "test": "vitest run",
47
+ "prepublishOnly": "npm run build && npm test"
48
+ },
49
+ "dependencies": {
50
+ "@modelcontextprotocol/sdk": "^1.12.0",
51
+ "zod": "^3.25.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^22.0.0",
55
+ "typescript": "^5.6.0",
56
+ "vitest": "^2.1.0"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/OutVersus/memoryrail/issues"
60
+ }
61
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://memoryrail.si/spec/memory.schema.json",
4
+ "title": "MemoryRail memory (frontmatter)",
5
+ "description": "Schema for the frontmatter of a file in .memoryrail/memories/. Format version 1.",
6
+ "type": "object",
7
+ "required": ["id", "type", "title", "status", "created", "updated"],
8
+ "additionalProperties": true,
9
+ "properties": {
10
+ "id": {
11
+ "type": "string",
12
+ "pattern": "^[A-Za-z0-9._-]+$",
13
+ "description": "Must equal the file name without .md."
14
+ },
15
+ "type": { "enum": ["decision", "constraint", "gotcha", "attempt", "thread", "session"] },
16
+ "title": { "type": "string", "minLength": 1 },
17
+ "status": { "enum": ["active", "proposed", "superseded", "archived", "resolved"] },
18
+ "created": { "type": "string", "format": "date-time" },
19
+ "updated": { "type": "string", "format": "date-time" },
20
+ "tags": { "type": "array", "items": { "type": "string" } },
21
+ "links": {
22
+ "type": "array",
23
+ "items": { "type": "string" },
24
+ "description": "Repo-relative POSIX paths. Must not escape the repository."
25
+ },
26
+ "pinned": { "type": "boolean" },
27
+ "supersedes": { "type": "string" },
28
+ "superseded_by": { "type": "string" }
29
+ }
30
+ }