@safekb/mcp 0.3.0 → 0.4.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.
Files changed (3) hide show
  1. package/README.md +63 -34
  2. package/dist/safekb-mcp.js +12471 -12200
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -3,62 +3,89 @@
3
3
  Local MCP client for SafeKB (stdio). It proxies the hosted SafeKB tools and adds **sealed** documents
4
4
  and folders: content is encrypted on your machine, and the server stores only ciphertext.
5
5
 
6
- Needs Node 20 or newer.
7
-
8
6
  ## Setup
9
7
 
10
- ```sh
11
- npx -y @safekb/mcp --authorize --url <your SafeKB API URL>
12
- ```
13
-
14
- This opens the browser and prints a **pairing code**. Sign in on the page, choose the spaces, type the
15
- pairing code, and the client saves a service-account token to `~/.config/safekb/mcp.json` (mode 0600).
16
- It then prints the account it was authorized as; check that it is yours. There is no default URL.
8
+ ### Claude Desktop
17
9
 
18
- Last, it chooses where this machine keeps the keys of new seal roots (see [Where secrets are kept](#where-secrets-are-kept)).
19
- With a system keyring that is the choice. Without one, as on most servers, it warns and asks before it
20
- uses key files. `npx -y @safekb/mcp --configure` makes the same choice again without re-authorizing.
21
- A client authorized before this choice existed makes it by itself on its next start when the system
22
- keyring works; only key files need `--configure`, because they need your agreement.
10
+ 1. Download [`safekb.mcpb`](https://safekb.com/download/safekb.mcpb) and open it (or Settings →
11
+ Extensions → Advanced settings → Install Extension…), then click **Install**.
12
+ 2. A SafeKB page opens in your browser. Sign in, choose the spaces, check that the page shows the same
13
+ code as Claude, and click **Confirm**.
23
14
 
24
- How the token gets to the client: the page never sees it. The page hands the client a single-use code
25
- (valid for two minutes), and the client redeems that code itself, proving with a secret it never wrote
26
- anywhere that it is the process that started the flow. The URL in the browser launcher's arguments is
27
- readable by other users of the machine, so it holds nothing that completes the flow; the pairing code
28
- is what ties your sign-in to your terminal. Every authorization creates its own token: authorizing
29
- again never changes the token or the spaces of another client. Revoke one under Settings → service
30
- accounts.
15
+ The tools appear in Claude without a restart. Nothing else is needed: no Node, no config file.
31
16
 
32
- Claude Code:
17
+ ### Claude Code
33
18
 
34
19
  ```sh
35
- claude mcp add safekb -- npx -y @safekb/mcp
20
+ npx -y @safekb/mcp --setup
36
21
  ```
37
22
 
38
- Claude Desktop and Cursor (`mcpServers` in their MCP config file):
23
+ This opens the same page, then registers the server with Claude Code for all your projects
24
+ (`claude mcp add --scope user safekb`). What is already done is left as it is, so it can be run again.
25
+ Needs Node 20 or newer.
26
+
27
+ Over SSH, or anywhere without a browser, the command prints a link instead. Open it on any device, sign
28
+ in and approve; the terminal then shows the account and a code, and you answer `y` when they match what
29
+ your browser shows.
30
+
31
+ ### Other MCP clients (Cursor, …)
39
32
 
40
33
  ```json
41
34
  { "mcpServers": { "safekb": { "command": "npx", "args": ["-y", "@safekb/mcp"] } } }
42
35
  ```
43
36
 
37
+ Started without a token, the client serves one tool, `connect_safekb`, which opens the page and puts
38
+ the SafeKB tools in its place once you have confirmed. `SAFEKB_MCP_NO_BROWSER=1` makes it show the link
39
+ instead of opening a browser.
40
+
41
+ ### A self-hosted SafeKB
42
+
43
+ The default server is `https://api.safekb.com`. For another one run
44
+ `npx -y @safekb/mcp --setup --url <your API URL>` first; the Desktop extension then uses the token that
45
+ command saved.
46
+
47
+ ### How the authorization is protected
48
+
49
+ - The page never sees the token. The client keeps a random secret, the link carries only its SHA-256,
50
+ and the client collects the token itself by presenting the secret to the server it was pointed at.
51
+ - Whoever sees the link could approve it for *their* account, to make your client write into it. So an
52
+ approval is taken only when it is tied to you: it carries the pairing code, or you confirmed it in
53
+ your terminal.
54
+ - The pairing code reaches the page in a file only your user can read (mode 0600), which the browser is
55
+ started with. The browser launcher's arguments, which other users of the machine can read, hold only
56
+ that file's path. This is why you check the code instead of typing it. When the page was opened by
57
+ hand in a client without a terminal, you type the code.
58
+ - Every authorization creates its own token: authorizing again never changes the token or the spaces of
59
+ another client. Revoke one under Settings → service accounts. The token is saved to
60
+ `~/.config/safekb/mcp.json` (mode 0600).
61
+
62
+ ### Where keys go
63
+
64
+ The keys of new seal roots go to the system keyring. On a machine without one (most servers) they are
65
+ kept as files, and the client says so in plain words on the page, in the terminal and in the result of
66
+ every tool that keeps a key this way; see [Where secrets are kept](#where-secrets-are-kept).
67
+ `npx -y @safekb/mcp --configure` makes the choice again, for example after a keyring was installed.
68
+
44
69
  ## Options
45
70
 
46
71
  | Flag | Environment | Meaning |
47
72
  | --- | --- | --- |
48
- | `--url <api url>` | `KB_API_URL` | API base URL. Otherwise the URL saved by `--authorize`. When serving, it must have the origin the token was issued for: the token is never sent anywhere else. |
73
+ | `--setup` | | Authorize, choose the key store and register with Claude Code, in one step. Safe to repeat. |
74
+ | `--url <api url>` | `KB_API_URL` | API base URL. Otherwise the URL in the token file, or `https://api.safekb.com` when authorizing. When serving, it must have the origin the token was issued for: the token is never sent anywhere else. |
49
75
  | `--config <path>` | `SAFEKB_MCP_CONFIG` | Token file. Default `~/.config/safekb/mcp.json`. Use one per project for per-project access. |
50
- | `--keyring <dir>` | `SAFEKB_SEALED_KEYRING` | Directory of sealed key files (`*.json`). Otherwise the one `--configure` chose, if any. |
76
+ | `--keyring <dir>` | `SAFEKB_SEALED_KEYRING` | Directory of sealed key files (`*.json`). Otherwise the one in the store settings, if any. |
51
77
  | `--sealed-only` | | Expose only the sealed tools; the hosted tools are not proxied. |
52
- | `--authorize` | | Authorize in the browser and write the token file, then choose the key store. |
53
- | `--configure` | | Choose where new sealed keys are kept. Writes `stores.json` next to the token file. |
78
+ | `--authorize` | | Authorize again in the browser and replace the token file. |
79
+ | `--configure` | | Choose again where new sealed keys are kept. Writes `stores.json` next to the token file. |
54
80
  | `--sidecar` | | Run the sidecar in this terminal. With `--confirm` it asks before every release of a secret. |
55
81
  | `--sidecar-socket <path>` | `SAFEKB_SIDECAR_SOCKET` | The sidecar's socket. Default `sidecar.sock` next to the token file. |
56
82
  | `--export-keys <file>` | | Write every sealed key this machine keeps to a new passphrase-protected file. See [Moving keys to another machine](#moving-keys-to-another-machine). |
57
83
  | `--import-keys <file>` | | Read such a file and keep its keys on this machine. |
58
84
  | | `SAFEKB_SEALED_IDLE_TTL` | Seconds an unlocked seal root may stay idle. Default 900. `unlock_sealed` can set it per root with `idle_ttl_seconds` (60 to 3600). |
59
85
  | | `SAFEKB_HOSTED_TIMEOUT` | Seconds a hosted tool call may take. Default 300. |
86
+ | | `SAFEKB_MCP_NO_BROWSER` | Set to anything: never start a browser, only show the authorize link. |
60
87
 
61
- The client refuses to start when the token file or a keyring file is readable by group or others,
88
+ With a token file, the client refuses to start when that file or a keyring file is readable by group or others,
62
89
  when `--url` names another origin than the token's, when the hosted endpoint cannot be reached, or
63
90
  when a hosted tool has the name of a sealed tool.
64
91
 
@@ -91,14 +118,16 @@ have it, it stops and asks for `store`.
91
118
  | `system` | a generated key | the operating system's keyring: Keychain (macOS), Credential Manager (Windows), Secret Service (Linux) | encrypted by the system |
92
119
  | `file` | a generated key | a file (mode 0600) in the keyring directory | not encrypted |
93
120
  | `sidecar` | a passphrase you type | the memory of a separate process, for a time you choose | nowhere |
94
- | `default` | | whichever of `system` and `file` `--configure` chose | |
121
+ | `default` | | `system` where the system keyring works, otherwise `file` | |
95
122
 
96
123
  `key_out_path` still writes a key file to a path of your choice, and `passphrase` still takes one as
97
124
  text (which then is in the conversation transcript).
98
125
 
99
- The system keyring is used only where `--configure` found it working. On Linux that means a running
126
+ The choice is made once, on the first start or by `--setup`, and saved in `stores.json`; `--configure`
127
+ makes it again. The system keyring is used only where it was found working. On Linux that means a running
100
128
  Secret Service (GNOME Keyring, KWallet, KeePassXC); the kernel keyring is never used, because it
101
- forgets its content at logout. Keys are kept there with [`@napi-rs/keyring`](https://github.com/Brooooooklyn/keyring-node).
129
+ forgets its content at logout. Where it does not work, keys are kept as files in `keys/` next to the
130
+ token file: readable only by your user, but not encrypted on disk. The client tells you when it does this. Keys are kept there with [`@napi-rs/keyring`](https://github.com/Brooooooklyn/keyring-node).
102
131
 
103
132
  ### The sidecar
104
133
 
@@ -142,7 +171,7 @@ them to another machine, or to back them up:
142
171
 
143
172
  ```sh
144
173
  npx -y @safekb/mcp --export-keys keys.safekb # on the machine that has the keys
145
- npx -y @safekb/mcp --import-keys keys.safekb # on the other machine, after --authorize there
174
+ npx -y @safekb/mcp --import-keys keys.safekb # on the other machine, after --setup there
146
175
  ```
147
176
 
148
177
  - Export asks for a passphrase (typed twice, not shown; 12 or more characters are recommended, a
@@ -150,7 +179,7 @@ npx -y @safekb/mcp --import-keys keys.safekb # on the other machine, after --a
150
179
  with every key of the system keyring and of the key file directory, and the names of their roots.
151
180
  The content is encrypted with AES-256-GCM under a key derived from the passphrase with Argon2id.
152
181
  Without the passphrase the file opens for nobody.
153
- - Import asks for that passphrase and keeps the keys in the store `--configure` chose on that
182
+ - Import asks for that passphrase and keeps the keys in the default store of that
154
183
  machine. A key the machine already keeps is left as it is, so an import can be repeated.
155
184
  - Both need a terminal: the passphrase is never an argument, so it is in no shell history, no process
156
185
  list and no conversation.