relic-mcp 0.2.0 → 0.3.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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "relic",
12
12
  "description": "Publish a file from your machine as an encrypted, shareable link. The agent encrypts locally, uploads only ciphertext, and hands back a URL whose fragment holds the key, so the service stores something it cannot read.",
13
- "version": "0.2.0",
13
+ "version": "0.3.1",
14
14
  "source": "./",
15
15
  "author": {
16
16
  "name": "The Bushido Collective",
@@ -21,6 +21,6 @@
21
21
  }
22
22
  ],
23
23
  "metadata": {
24
- "version": "0.2.0"
24
+ "version": "0.3.1"
25
25
  }
26
26
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relic",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Publish a file from your machine as an encrypted, shareable link. The agent encrypts locally, uploads only ciphertext, and hands back a URL whose fragment holds the key, so the service stores something it cannot read.",
5
5
  "mcpServers": "./mcp-servers.json",
6
6
  "author": {
package/README.md CHANGED
@@ -5,8 +5,8 @@ encryption key is generated on your machine and is never sent to the service.
5
5
 
6
6
  ```bash
7
7
  claude mcp add relic \
8
- --env RELIC_SERVICE_ORIGIN=https://your-relic-service \
9
- -- npx -y relic-mcp
8
+ --env RELIC_SERVICE_ORIGIN=https://relik.link \
9
+ -- npx -y relic-mcp@latest
10
10
  ```
11
11
 
12
12
  Then: *"publish ./report.md as a relic."*
@@ -18,8 +18,8 @@ For any client that takes a JSON config:
18
18
  "mcpServers": {
19
19
  "relic": {
20
20
  "command": "npx",
21
- "args": ["-y", "relic-mcp"],
22
- "env": { "RELIC_SERVICE_ORIGIN": "https://your-relic-service" }
21
+ "args": ["-y", "relic-mcp@latest"],
22
+ "env": { "RELIC_SERVICE_ORIGIN": "https://relik.link" }
23
23
  }
24
24
  }
25
25
  }
@@ -33,9 +33,14 @@ For any client that takes a JSON config:
33
33
  3. Encrypts locally with AES-128-GCM under RFC 8188 `aes128gcm` framing.
34
34
  4. Uploads **only ciphertext**, straight to object storage under a signed URL.
35
35
  It does not pass through the Relic service.
36
- 5. Tells the service three things: a coarse renderer class from a seven-value
36
+ 5. Tells the service three things: a coarse renderer class from an eight-value
37
37
  list, this client's name, and the ciphertext's byte length. Not your
38
38
  filename, not the mimetype, not the contents.
39
+ 6. Records the relic's id, key, and publish token locally, in a 0600 file
40
+ under your user config directory, so the relic can be republished from
41
+ this machine later. See [Republishing](#republishing). The service never
42
+ receives the key or the token plaintext; it keeps only a SHA-256 of the
43
+ token.
39
44
 
40
45
  Call the `relic_describe_client` tool and it will tell you all of this itself,
41
46
  without reading a file or making a request.
@@ -49,6 +54,48 @@ holds against the Relic operator. It does not hold against your model provider
49
54
  or whoever stores your transcripts. That is structural, not a defect awaiting
50
55
  a fix.
51
56
 
57
+ ## Republishing
58
+
59
+ `relic_republish` publishes a new version of a relic this machine originally
60
+ published: same id, same key, **same share URL**. Everyone holding the
61
+ existing link sees the new content; there is no new link to hand out.
62
+
63
+ ```json
64
+ {
65
+ "name": "relic_republish",
66
+ "arguments": { "relic_id": "0a2c...", "path": "./report-v2.md" }
67
+ }
68
+ ```
69
+
70
+ It takes `relic_id` (the 26-character id the original publish returned) and
71
+ `path`, plus an optional `filename` override and an optional `ttl_days` that
72
+ is forwarded on the request. Versions count from 1: `relic_publish` reports
73
+ version 1, each republish reports the next number, and the URL never changes
74
+ across them. A relic's lifetime is fixed at its first publish and carries
75
+ across versions.
76
+
77
+ Republishing needs the relic's key and its publish token, so the first
78
+ `relic_publish` records both in a local state file:
79
+ `$XDG_CONFIG_HOME/relic-mcp/publish-state.json` by default
80
+ (`~/.config/relic-mcp/publish-state.json` when `XDG_CONFIG_HOME` is unset),
81
+ created `0600` inside a `0700` directory, and redirectable with
82
+ `RELIC_PUBLISH_STATE`. Consequences worth stating plainly:
83
+
84
+ - **Only that machine can republish.** Anywhere else, the tool refuses: the
85
+ relic was published from another machine and cannot be republished here.
86
+ Copying the state file to another machine moves the ability with it.
87
+ - **The file holds the key and the token.** They are never printed, logged,
88
+ or returned by any tool result. The service stores only a SHA-256 of the
89
+ token, so it cannot reconstruct either one.
90
+ - **Losing the file changes nothing for existing links**; it only ends that
91
+ machine's ability to update those relics.
92
+ - **A takedown is permanent.** A removed relic answers `relic_removed`
93
+ (HTTP 410) forever, whatever token is presented, and republishing cannot
94
+ revive it. Publish the content as a new relic instead. A rejected token is
95
+ its own refusal (`invalid_publish_token`, HTTP 403): the local record no
96
+ longer matches the service's, and the relic cannot be republished from
97
+ this machine, though it can still be read.
98
+
52
99
  ## Why it runs locally
53
100
 
54
101
  Encryption has to happen where the plaintext is, so a hosted version of this
@@ -65,7 +112,8 @@ binding the tarball to a specific commit and workflow.
65
112
 
66
113
  | Tool | Input | Notes |
67
114
  |---|---|---|
68
- | `relic_publish` | `path`, optional `filename` | A filesystem path. Inline content is deliberately not accepted, so the plaintext never joins the key in your transcript. |
115
+ | `relic_publish` | `path`, optional `filename`, `ttl_days` | A filesystem path. Inline content is deliberately not accepted, so the plaintext never joins the key in your transcript. A relic is kept until it is deleted; `ttl_days` (an integer, 1 to 3650) gives it a lifetime. Reports the relic as version 1. |
116
+ | `relic_republish` | `relic_id`, `path`, optional `filename`, `ttl_days` | Publishes a new version under the same key, so the share URL is unchanged. Works only on the machine holding that relic's key and publish token; a taken-down relic can never be revived. |
69
117
  | `relic_describe_client` | none | Explains the encryption path. Reads nothing, sends nothing. |
70
118
 
71
119
  ## Environment
@@ -75,6 +123,7 @@ binding the tarball to a specific commit and workflow.
75
123
  | `RELIC_SERVICE_ORIGIN` | The Relic service to publish to. |
76
124
  | `RELIC_ORIGIN` | Origin used to build the shareable URL. Defaults to the above. |
77
125
  | `RELIC_CLIENT_NAME` | Reported to the service as the publishing client. |
126
+ | `RELIC_PUBLISH_STATE` | Where the publish state file lives. Defaults to `$XDG_CONFIG_HOME/relic-mcp/publish-state.json`, or `~/.config/relic-mcp/publish-state.json`. |
78
127
  | `RELIC_MCP_HTTP` | `1` to serve Streamable HTTP instead of stdio. |
79
128
  | `RELIC_MCP_PORT`, `RELIC_MCP_HOST` | HTTP bind. Defaults to `127.0.0.1:7333`. |
80
129
  | `RELIC_MCP_ALLOWED_ORIGINS` | Comma-separated `Origin` allowlist for HTTP. |
@@ -82,8 +131,10 @@ binding the tarball to a specific commit and workflow.
82
131
  ## Protocol
83
132
 
84
133
  MCP revision `2026-07-28`, the stateless one: no handshake, no session, no
85
- `Mcp-Session-Id`. Nothing is retained between calls. The handshake-based
86
- revisions (`2025-11-25` and earlier) are still answered.
134
+ `Mcp-Session-Id`. No protocol state is retained between calls; the one thing
135
+ that does outlive a call is the per-machine publish state file described
136
+ above. The handshake-based revisions (`2025-11-25` and earlier) are still
137
+ answered.
87
138
 
88
139
  Requires Node 18 or newer.
89
140