relic-mcp 0.2.0 → 0.3.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +59 -8
- package/dist/relic-mcp.js +444 -49
- package/mcp-servers.json +3 -3
- package/package.json +1 -1
- package/skills/relic/SKILL.md +43 -9
- package/src/http.ts +7 -3
- package/src/install.ts +13 -0
- package/src/installer.ts +7 -7
- package/src/publish.ts +139 -31
- package/src/republish.ts +182 -0
- package/src/server.ts +315 -8
- package/src/state.ts +185 -0
|
@@ -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.
|
|
13
|
+
"version": "0.3.0",
|
|
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.
|
|
24
|
+
"version": "0.3.0"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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://
|
|
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://
|
|
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
|
|
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`.
|
|
86
|
-
|
|
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
|
|