mcpocket 0.4.0 → 0.4.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.
package/README.md CHANGED
@@ -1,358 +1,412 @@
1
- <p align="center">
2
- <img src="https://img.shields.io/npm/v/mcpocket?color=blue&label=npm" alt="npm version" />
3
- <img src="https://img.shields.io/node/v/mcpocket" alt="node version" />
4
- <img src="https://img.shields.io/github/license/davidsmorais/carry-on" alt="license" />
5
- </p>
6
-
7
- <p align="center">
8
- <img src="./logo.png" alt="mcpocket logo" width="200" />
9
- </p>
10
-
11
- # mcpocket
12
-
13
- > Your AI setup. Every pocket. ✨
14
-
15
- **mcpocket** syncs your Claude Code agents, skills, plugins, and MCP server configurations across machines — so your full AI loadout follows you everywhere, like magic.
16
-
17
- ---
18
-
19
- ## The Problem
20
-
21
- You install 8 MCP servers, configure your Claude Code plugins, and build up a library of agents on your Linux workstation. Then you switch to your Windows laptop and… nothing. You start from scratch. Again.
22
-
23
- **mcpocket** fixes that with two commands: `push` from your source machine, `pull` on any other.
24
-
25
- ## Features
26
-
27
- - **Multi-client sync** — Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, and Antigravity configs in one shot
28
- - **Two storage backends** — private GitHub repo (full git history) or lightweight GitHub Gist
29
- - **Provider-scoped sync** — target one or more providers with flags like `--copilot-cli` or `--opencode`
30
- - **End-to-end encryption** — secrets in MCP `env`, `headers`, and `http_headers` are encrypted with AES-256-GCM using a passphrase you choose
31
- - **Cross-platform paths** — Windows ↔ Linux ↔ macOS paths round-trip seamlessly
32
- - **Additive pull** — pulling merges remote servers into your local config without overwriting anything
33
- - **De-duplicated file sync** — push/pull mirror synced files so stale agent, skill, and plugin files don't pile up
34
- - **Zero dependencies on external services** — only GitHub and Git
35
-
36
- ---
37
-
38
- ## Install
39
-
40
- ```bash
41
- npm install -g mcpocket
42
- ```
43
-
44
- Or with pnpm / yarn:
45
-
46
- ```bash
47
- pnpm add -g mcpocket
48
- # or
49
- yarn global add mcpocket
50
- ```
51
-
52
- ## Quick Start
53
-
54
- ```bash
55
- # 1. Initialize (once per machine)
56
- mcpocket init
57
-
58
- # 2. Push your setup to the cloud
59
- mcpocket push
60
-
61
- # 3. Pull on a new machine
62
- mcpocket pull
63
-
64
- # 4. Clean up stale synced files if needed
65
- mcpocket de-dupe
66
-
67
- # 5. Check sync status
68
- mcpocket status
69
- ```
70
-
71
- ---
72
-
73
- ## Commands
74
-
75
- ### `mcpocket init`
76
-
77
- Interactive setup wizard. Links your GitHub account, chooses a storage backend, and creates the remote pocket.
78
-
79
- ```
80
- $ mcpocket init
81
-
82
- ✦ First, let's link your GitHub account.
83
- Required scopes: repo (full control of private repositories)
84
-
85
- 🔑 GitHub token: ****
86
-
87
- ✦ Authenticated as davidsmorais — nice to meet you!
88
-
89
- Where should mcpocket store your config?
90
- [1] GitHub repo (private repo, full git history)
91
- [2] GitHub gist (lighter, no git clone needed)
92
-
93
- Pick one [1/2]: 1
94
- ```
95
-
96
- **Storage options:**
97
-
98
- | Option | Backend | Requires Git? | History |
99
- |---|---|---|---|
100
- | `1` — Repo | Private `mcpocket-sync` repo | Yes | Full git log |
101
- | `2` — Gist | Private GitHub Gist | No | Gist revisions |
102
-
103
- Requires a [GitHub personal access token](https://github.com/settings/tokens/new) with **`repo`** scope (for repo mode) or **`gist`** scope (for gist mode).
104
-
105
- ### `mcpocket push`
106
-
107
- Reads MCP configs, plugin manifests, agents, and skills from the current machine. Encrypts secrets with a passphrase you choose, then uploads to your private pocket.
108
-
109
- ```bash
110
- mcpocket push
111
- ```
112
-
113
- Target specific providers by passing one or more flags:
114
-
115
- ```bash
116
- mcpocket push --copilot-cli
117
- mcpocket push --cursor --codex
118
- ```
119
-
120
- When provider flags are present, they scope the whole command:
121
-
122
- - Only the selected providers' MCP configs are read and packed into `mcp-config.json`
123
- - Claude home assets (`~/.claude/plugins`, `~/.claude/agents`, `~/.claude/skills`) are only synced when `--claude-code` is included
124
-
125
- - In **repo mode**: commits and pushes to your private GitHub repo.
126
- - In **gist mode**: uploads files to your private GitHub Gist (directory structure is flattened with `__` separators).
127
-
128
- ### `mcpocket pull`
129
-
130
- Downloads your config from the remote pocket, decrypts secrets with your passphrase, and writes everything to the appropriate client config files:
131
-
132
- ```bash
133
- mcpocket pull
134
- ```
135
-
136
- You can also pull into only the providers you want:
137
-
138
- ```bash
139
- mcpocket pull --opencode
140
- mcpocket pull --cursor --copilot-cli
141
- ```
142
-
143
- With provider flags, pull only writes MCP servers to those selected providers. Claude home assets are only restored when `--claude-code` is included.
144
-
145
- | Client | Config file |
146
- |---|---|
147
- | Claude Desktop | `claude_desktop_config.json` |
148
- | Claude Code | `~/.claude/settings.json` |
149
- | OpenCode | `~/.config/opencode/config.json` |
150
- | Copilot CLI | VS Code/Copilot user `mcp.json` |
151
- | Cursor | `~/.cursor/mcp.json` |
152
- | Codex | `~/.codex/config.toml` |
153
- | Antigravity | `~/.gemini/antigravity/mcp_config.json` |
154
-
155
- Pull is **additive** — it adds servers that exist remotely but not locally, without overwriting your existing local config. Restart Claude Desktop after pulling to apply MCP changes.
156
-
157
- For synced files, pull also removes stale agent and skill files that were previously synced but no longer exist in your pocket.
158
-
159
- ### `mcpocket de-dupe`
160
-
161
- Refreshes the pocket, mirrors the current synced files, removes stale duplicates on both sides, and writes the cleaned result back to your configured backend.
162
-
163
- ```bash
164
- mcpocket de-dupe
165
- ```
166
-
167
- Use this if you already have duplicate or renamed agent/skill/plugin files from earlier syncs. In normal use, `push` and `pull` now keep these folders de-duplicated automatically.
168
-
169
- ### `mcpocket status`
170
-
171
- Shows a diff of what's synced, what's local-only, and what's remote-only:
172
-
173
- ```bash
174
- mcpocket status
175
- ```
176
-
177
- ```
178
- ── MCP Servers ──
179
-
180
- Synced:
181
- ✓ filesystem
182
- ✓ github
183
-
184
- Local only (run push):
185
- ↑ sqlite
186
-
187
- In pocket, not here (run pull):
188
- ↓ postgres
189
- ```
190
-
191
- ---
192
-
193
- ## What Gets Synced
194
-
195
- | Category | Source | Details |
196
- |---|---|---|
197
- | MCP server configs | Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, Antigravity | Merged across all selected providers |
198
- | Plugin manifests | `~/.claude/plugins/` | `installed_plugins.json`, `blocklist.json`, `known_marketplaces.json` |
199
- | Agents | `~/.claude/agents/` | All `*.md` files, recursively |
200
- | Skills | `~/.claude/skills/` | All files, recursively (excluding `node_modules`) |
201
-
202
- If you do not pass provider flags, `push` and `pull` operate on every supported provider. If you do pass flags, only those providers participate in the command.
203
-
204
- ### Never Synced
205
-
206
- - `.credentials.json`
207
- - `plugins/cache/`
208
- - Sessions and telemetry data
209
- - Your GitHub token (stays in local `~/.mcpocket/config.json`)
210
-
211
- ---
212
-
213
- ## Security
214
-
215
- | Concern | How mcpocket handles it |
216
- |---|---|
217
- | API keys & tokens | Encrypted with **AES-256-GCM** (via `scrypt` key derivation) before leaving your machine |
218
- | Passphrase storage | **Never stored** — you enter it on every push/pull |
219
- | Remote storage | Always **private** (private repo or secret gist) |
220
- | Local config | `~/.mcpocket/config.json` is `chmod 600` on Linux/macOS |
221
- | Git auth | Token is injected at runtime into HTTPS URLs, never persisted in git config |
222
- | Error output | Git errors are sanitized to strip tokens before display |
223
-
224
- ### Encryption Format
225
-
226
- Encrypted values are stored as:
227
-
228
- ```
229
- ENCRYPTED:<iv_hex>:<salt_hex>:<authTag_hex>:<ciphertext_hex>
230
- ```
231
-
232
- Each value uses a unique random salt and IV, so identical plaintext values produce different ciphertexts.
233
-
234
- ---
235
-
236
- ## Path Handling
237
-
238
- mcpocket normalizes paths for portability:
239
-
240
- | Direction | Transformation |
241
- |---|---|
242
- | Push | `/home/user/...` or `C:\Users\user\...` → `~/...` |
243
- | Pull | `~/...` → platform-native absolute path |
244
- | Commands | `.cmd` / `.exe` extensions stripped on push, restored on pull (Windows) |
245
-
246
- This means a config pushed from Linux works on Windows and vice versa.
247
-
248
- ---
249
-
250
- ## Configuration
251
-
252
- mcpocket stores its own config at `~/.mcpocket/config.json`:
253
-
254
- ```jsonc
255
- {
256
- "githubToken": "ghp_...",
257
- "storageType": "repo", // "repo" or "gist"
258
- // Repo mode:
259
- "repoFullName": "user/mcpocket-sync",
260
- "repoCloneUrl": "https://github.com/user/mcpocket-sync.git",
261
- "repoHtmlUrl": "https://github.com/user/mcpocket-sync",
262
- // Gist mode:
263
- "gistId": "abc123...",
264
- "gistUrl": "https://gist.github.com/abc123..."
265
- }
266
- ```
267
-
268
- The local repo clone (used as a staging area) lives at `~/.mcpocket/repo/`.
269
-
270
- ---
271
-
272
- ## Requirements
273
-
274
- - **Node.js** 18+
275
- - **Git** in PATH (repo mode only — gist mode doesn't need git)
276
- - A **GitHub account** with a personal access token
277
-
278
- ---
279
-
280
- ## Project Structure
281
-
282
- ```
283
- src/
284
- cli.ts # Entry point, Commander setup
285
- config.ts # Config read/write, storage type definitions
286
- clients/
287
- claude-desktop.ts # Claude Desktop config reader/writer
288
- claude-code.ts # Claude Code settings reader/writer
289
- opencode.ts # OpenCode config reader/writer
290
- types.ts # Shared MCP server type definitions
291
- commands/
292
- init.ts # Interactive setup wizard
293
- push.ts # Push local config to remote
294
- pull.ts # Pull remote config to local
295
- status.ts # Diff local vs. remote
296
- storage/
297
- github.ts # GitHub repo CRUD + git operations
298
- gist.ts # GitHub Gist CRUD + file flattening
299
- sync/
300
- agents.ts # Agent file sync logic
301
- mcp.ts # MCP server merge, pack/unpack, encrypt/decrypt
302
- plugins.ts # Plugin manifest sync logic
303
- skills.ts # Skills file sync logic
304
- utils/
305
- crypto.ts # AES-256-GCM encrypt/decrypt helpers
306
- paths.ts # Cross-platform path normalization
307
- prompt.ts # Interactive CLI input helpers
308
- sparkle.ts # CLI banners, spinners, and personality
309
- ```
310
-
311
- ---
312
-
313
- ## Troubleshooting
314
-
315
- ### "mcpocket is not initialized"
316
-
317
- Run `mcpocket init` first to set up your GitHub connection and storage backend.
318
-
319
- ### "Decryption failed — wrong passphrase"
320
-
321
- The passphrase you entered doesn't match the one used during `mcpocket push`. Passphrases are never stored — you need to remember the one you used.
322
-
323
- ### Push says "Nothing changed"
324
-
325
- Your local config matches what's already in the remote pocket. No commit/upload needed.
326
-
327
- ### MCP servers not appearing after pull
328
-
329
- Restart Claude Desktop to reload MCP server configurations. Claude Code and OpenCode pick up changes automatically.
330
-
331
- ### Git errors on push/pull (repo mode)
332
-
333
- Make sure `git` is installed and in your PATH. If you see auth errors, your GitHub token may have expired — run `mcpocket init` to re-authenticate.
334
-
335
- ---
336
-
337
- ## Contributing
338
-
339
- Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/davidsmorais/carry-on).
340
-
341
- ```bash
342
- git clone https://github.com/davidsmorais/carry-on.git
343
- cd carry-on
344
- pnpm install
345
- pnpm build
346
- ```
347
-
348
- ---
349
-
350
- ## Author
351
-
352
- **David Morais** [david@davidmorais.com](mailto:david@davidmorais.com)
353
-
354
- - GitHub: [@davidsmorais](https://github.com/davidsmorais)
355
-
356
- ## License
357
-
358
- [MIT](LICENSE) © David Morais
1
+ <p align="center">
2
+ <img src="https://img.shields.io/npm/v/mcpocket?color=blue&label=npm" alt="npm version" />
3
+ <img src="https://img.shields.io/node/v/mcpocket" alt="node version" />
4
+ <img src="https://img.shields.io/github/license/davidsmorais/carry-on" alt="license" />
5
+ </p>
6
+
7
+ <p align="center">
8
+ <img src="./logo.png" alt="mcpocket logo" width="200" />
9
+ </p>
10
+
11
+ # mcpocket
12
+
13
+ > Your AI setup. Every pocket. ✨
14
+
15
+ **mcpocket** syncs your Claude Code agents, skills, plugins, and MCP server configurations across machines — so your full AI loadout follows you everywhere, like magic.
16
+
17
+ ---
18
+
19
+ ## The Problem
20
+
21
+ You install 8 MCP servers, configure your Claude Code plugins, and build up a library of agents on your Linux workstation. Then you switch to your Windows laptop and… nothing. You start from scratch. Again.
22
+
23
+ **mcpocket** fixes that with two commands: `push` from your source machine, `pull` on any other.
24
+
25
+ ## Features
26
+
27
+ - **Multi-client sync** — Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, and Antigravity configs in one shot
28
+ - **Two storage backends** — private GitHub repo (full git history) or lightweight GitHub Gist
29
+ - **Provider-scoped sync** — target one or more providers with flags like `--copilot-cli` or `--opencode`
30
+ - **End-to-end encryption** — secrets in MCP `env`, `headers`, and `http_headers` are encrypted with AES-256-GCM using a passphrase you choose
31
+ - **Cross-platform paths** — Windows ↔ Linux ↔ macOS paths round-trip seamlessly
32
+ - **Additive pull** — pulling merges remote servers into your local config without overwriting anything
33
+ - **De-duplicated file sync** — push/pull mirror synced files so stale agent, skill, and plugin files don't pile up
34
+ - **Zero dependencies on external services** — only GitHub and Git
35
+
36
+ ---
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ npm install -g mcpocket
42
+ ```
43
+
44
+ Or with pnpm / yarn:
45
+
46
+ ```bash
47
+ pnpm add -g mcpocket
48
+ # or
49
+ yarn global add mcpocket
50
+ ```
51
+
52
+ ## Quick Start
53
+
54
+ ```bash
55
+ # 1. Initialize (once per machine)
56
+ mcpocket init
57
+
58
+ # 2. Push your setup to the cloud
59
+ mcpocket push
60
+
61
+ # 3. Pull on a new machine
62
+ mcpocket pull
63
+
64
+ # 4. Clean up pocket files interactively
65
+ mcpocket cleanup
66
+
67
+ # 5. Clean up using patterns from your config (local only, no remote sync)
68
+ mcpocket cleanup --local
69
+
70
+ # 6. Clean up stale synced files if needed
71
+ mcpocket de-dupe
72
+
73
+ # 7. Check sync status
74
+ mcpocket status
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Commands
80
+
81
+ ### `mcpocket init`
82
+
83
+ Interactive setup wizard. Links your GitHub account, chooses a storage backend, and creates the remote pocket.
84
+
85
+ ```
86
+ $ mcpocket init
87
+
88
+ ✦ First, let's link your GitHub account.
89
+ Required scopes: repo (full control of private repositories)
90
+
91
+ 🔑 GitHub token: ****
92
+
93
+ Authenticated as davidsmorais — nice to meet you!
94
+
95
+ ✦ Where should mcpocket store your config?
96
+ [1] GitHub repo (private repo, full git history)
97
+ [2] GitHub gist (lighter, no git clone needed)
98
+
99
+ Pick one [1/2]: 1
100
+ ```
101
+
102
+ **Storage options:**
103
+
104
+ | Option | Backend | Requires Git? | History |
105
+ |---|---|---|---|
106
+ | `1` — Repo | Private `mcpocket-sync` repo | Yes | Full git log |
107
+ | `2` Gist | Private GitHub Gist | No | Gist revisions |
108
+
109
+ Requires a [GitHub personal access token](https://github.com/settings/tokens/new) with **`repo`** scope (for repo mode) or **`gist`** scope (for gist mode).
110
+
111
+ ### `mcpocket push`
112
+
113
+ Reads MCP configs, plugin manifests, agents, and skills from the current machine. Encrypts secrets with a passphrase you choose, then uploads to your private pocket.
114
+
115
+ ```bash
116
+ mcpocket push
117
+ ```
118
+
119
+ Target specific providers by passing one or more flags:
120
+
121
+ ```bash
122
+ mcpocket push --copilot-cli
123
+ mcpocket push --cursor --codex
124
+ ```
125
+
126
+ When provider flags are present, they scope the whole command:
127
+
128
+ - Only the selected providers' MCP configs are read and packed into `mcp-config.json`
129
+ - Claude home assets (`~/.claude/plugins`, `~/.claude/agents`, `~/.claude/skills`) are only synced when `--claude-code` is included
130
+
131
+ - In **repo mode**: commits and pushes to your private GitHub repo.
132
+ - In **gist mode**: uploads files to your private GitHub Gist (directory structure is flattened with `__` separators).
133
+
134
+ ### `mcpocket pull`
135
+
136
+ Downloads your config from the remote pocket, decrypts secrets with your passphrase, and writes everything to the appropriate client config files:
137
+
138
+ ```bash
139
+ mcpocket pull
140
+ ```
141
+
142
+ You can also pull into only the providers you want:
143
+
144
+ ```bash
145
+ mcpocket pull --opencode
146
+ mcpocket pull --cursor --copilot-cli
147
+ ```
148
+
149
+ With provider flags, pull only writes MCP servers to those selected providers. Claude home assets are only restored when `--claude-code` is included.
150
+
151
+ | Client | Config file |
152
+ |---|---|
153
+ | Claude Desktop | `claude_desktop_config.json` |
154
+ | Claude Code | `~/.claude/settings.json` |
155
+ | OpenCode | `~/.config/opencode/config.json` |
156
+ | Copilot CLI | VS Code/Copilot user `mcp.json` |
157
+ | Cursor | `~/.cursor/mcp.json` |
158
+ | Codex | `~/.codex/config.toml` |
159
+ | Antigravity | `~/.gemini/antigravity/mcp_config.json` |
160
+
161
+ Pull is **additive** it adds servers that exist remotely but not locally, without overwriting your existing local config. Restart Claude Desktop after pulling to apply MCP changes.
162
+
163
+ For synced files, pull also removes stale agent and skill files that were previously synced but no longer exist in your pocket.
164
+
165
+ ### `mcpocket de-dupe`
166
+
167
+ Refreshes the pocket, mirrors the current synced files, removes stale duplicates on both sides, and writes the cleaned result back to your configured backend.
168
+
169
+ ```bash
170
+ mcpocket de-dupe
171
+ ```
172
+
173
+ Use this if you already have duplicate or renamed agent/skill/plugin files from earlier syncs. In normal use, `push` and `pull` now keep these folders de-duplicated automatically.
174
+
175
+ ### `mcpocket cleanup`
176
+
177
+ Pulls your pocket from the remote, lets you interactively choose which files to keep, deletes the rest, then pushes the updated pocket back.
178
+
179
+ ```bash
180
+ mcpocket cleanup
181
+ ```
182
+
183
+ You will be presented with a numbered list of every file in your pocket and can enter comma-separated indices to select which ones to keep (pressing Enter keeps everything). After confirming, the unselected files are deleted and the pocket is pushed back to the remote.
184
+
185
+ **Options:**
186
+
187
+ | Flag | Description |
188
+ |---|---|
189
+ | `-l, --local` | Operate on the local pocket only — no pull/push; use patterns from `mcpocket.json` |
190
+ | `--dry-run` | Preview which files would be deleted without making any changes |
191
+ | `-y, --yes` | Skip the confirmation prompt |
192
+
193
+ #### Local-only cleanup (`--local`)
194
+
195
+ When running with `--local`, mcpocket reads `cleanupInclude` / `cleanupExclude` pattern arrays from `~/.mcpocket/config.json`:
196
+
197
+ ```jsonc
198
+ {
199
+ // ... other config ...
200
+ "cleanupInclude": ["agents/", "skills/"], // whitelist: only keep these
201
+ "cleanupExclude": ["skills/nested/**"] // blacklist: also remove these
202
+ }
203
+ ```
204
+
205
+ Pattern semantics:
206
+ - `cleanupInclude`: only files matching **at least one** include pattern are kept. Omit or leave empty to include everything.
207
+ - `cleanupExclude`: files matching any exclude pattern are removed (applied after include filtering).
208
+ - `dir/` is shorthand for `dir/**` (matches all files inside that directory).
209
+ - `*` matches any characters within a single path segment; `**` matches across segments.
210
+
211
+ If no patterns are configured, `--local` falls back to the same interactive selection UI as the remote mode.
212
+
213
+ ```bash
214
+ mcpocket cleanup --local
215
+ mcpocket cleanup --local --dry-run # preview without deleting
216
+ mcpocket cleanup --local --yes # skip confirmation
217
+ ```
218
+
219
+ ### `mcpocket status`
220
+
221
+ Shows a diff of what's synced, what's local-only, and what's remote-only:
222
+
223
+ ```bash
224
+ mcpocket status
225
+ ```
226
+
227
+ ```
228
+ ── MCP Servers ──
229
+
230
+ Synced:
231
+ ✓ filesystem
232
+ github
233
+
234
+ Local only (run push):
235
+ ↑ sqlite
236
+
237
+ In pocket, not here (run pull):
238
+ postgres
239
+ ```
240
+
241
+ ---
242
+
243
+ ## What Gets Synced
244
+
245
+ | Category | Source | Details |
246
+ |---|---|---|
247
+ | MCP server configs | Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, Antigravity | Merged across all selected providers |
248
+ | Plugin manifests | `~/.claude/plugins/` | `installed_plugins.json`, `blocklist.json`, `known_marketplaces.json` |
249
+ | Agents | `~/.claude/agents/` | All `*.md` files, recursively |
250
+ | Skills | `~/.claude/skills/` | All files, recursively (excluding `node_modules`) |
251
+
252
+ If you do not pass provider flags, `push` and `pull` operate on every supported provider. If you do pass flags, only those providers participate in the command.
253
+
254
+ ### Never Synced
255
+
256
+ - `.credentials.json`
257
+ - `plugins/cache/`
258
+ - Sessions and telemetry data
259
+ - Your GitHub token (stays in local `~/.mcpocket/config.json`)
260
+
261
+ ---
262
+
263
+ ## Security
264
+
265
+ | Concern | How mcpocket handles it |
266
+ |---|---|
267
+ | API keys & tokens | Encrypted with **AES-256-GCM** (via `scrypt` key derivation) before leaving your machine |
268
+ | Passphrase storage | **Never stored** you enter it on every push/pull |
269
+ | Remote storage | Always **private** (private repo or secret gist) |
270
+ | Local config | `~/.mcpocket/config.json` is `chmod 600` on Linux/macOS |
271
+ | Git auth | Token is injected at runtime into HTTPS URLs, never persisted in git config |
272
+ | Error output | Git errors are sanitized to strip tokens before display |
273
+
274
+ ### Encryption Format
275
+
276
+ Encrypted values are stored as:
277
+
278
+ ```
279
+ ENCRYPTED:<iv_hex>:<salt_hex>:<authTag_hex>:<ciphertext_hex>
280
+ ```
281
+
282
+ Each value uses a unique random salt and IV, so identical plaintext values produce different ciphertexts.
283
+
284
+ ---
285
+
286
+ ## Path Handling
287
+
288
+ mcpocket normalizes paths for portability:
289
+
290
+ | Direction | Transformation |
291
+ |---|---|
292
+ | Push | `/home/user/...` or `C:\Users\user\...` → `~/...` |
293
+ | Pull | `~/...` platform-native absolute path |
294
+ | Commands | `.cmd` / `.exe` extensions stripped on push, restored on pull (Windows) |
295
+
296
+ This means a config pushed from Linux works on Windows and vice versa.
297
+
298
+ ---
299
+
300
+ ## Configuration
301
+
302
+ mcpocket stores its own config at `~/.mcpocket/config.json`:
303
+
304
+ ```jsonc
305
+ {
306
+ "githubToken": "ghp_...",
307
+ "storageType": "repo", // "repo" or "gist"
308
+ // Repo mode:
309
+ "repoFullName": "user/mcpocket-sync",
310
+ "repoCloneUrl": "https://github.com/user/mcpocket-sync.git",
311
+ "repoHtmlUrl": "https://github.com/user/mcpocket-sync",
312
+ // Gist mode:
313
+ "gistId": "abc123...",
314
+ "gistUrl": "https://gist.github.com/abc123...",
315
+ // Cleanup patterns (used by `mcpocket cleanup --local`):
316
+ "cleanupInclude": ["agents/", "skills/"], // whitelist: only keep these
317
+ "cleanupExclude": ["skills/nested/**"] // blacklist: also remove these
318
+ }
319
+ ```
320
+
321
+ The local repo clone (used as a staging area) lives at `~/.mcpocket/repo/`.
322
+
323
+ ---
324
+
325
+ ## Requirements
326
+
327
+ - **Node.js** 18+
328
+ - **Git** in PATH (repo mode only — gist mode doesn't need git)
329
+ - A **GitHub account** with a personal access token
330
+
331
+ ---
332
+
333
+ ## Project Structure
334
+
335
+ ```
336
+ src/
337
+ cli.ts # Entry point, Commander setup
338
+ config.ts # Config read/write, storage type definitions
339
+ clients/
340
+ claude-desktop.ts # Claude Desktop config reader/writer
341
+ claude-code.ts # Claude Code settings reader/writer
342
+ opencode.ts # OpenCode config reader/writer
343
+ types.ts # Shared MCP server type definitions
344
+ commands/
345
+ cleanup.ts # Interactive/pattern-based pocket cleanup
346
+ init.ts # Interactive setup wizard
347
+ push.ts # Push local config to remote
348
+ pull.ts # Pull remote config to local
349
+ status.ts # Diff local vs. remote
350
+ storage/
351
+ github.ts # GitHub repo CRUD + git operations
352
+ gist.ts # GitHub Gist CRUD + file flattening
353
+ sync/
354
+ agents.ts # Agent file sync logic
355
+ mcp.ts # MCP server merge, pack/unpack, encrypt/decrypt
356
+ plugins.ts # Plugin manifest sync logic
357
+ skills.ts # Skills file sync logic
358
+ utils/
359
+ crypto.ts # AES-256-GCM encrypt/decrypt helpers
360
+ paths.ts # Cross-platform path normalization
361
+ prompt.ts # Interactive CLI input helpers
362
+ sparkle.ts # CLI banners, spinners, and personality
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Troubleshooting
368
+
369
+ ### "mcpocket is not initialized"
370
+
371
+ Run `mcpocket init` first to set up your GitHub connection and storage backend.
372
+
373
+ ### "Decryption failed — wrong passphrase"
374
+
375
+ The passphrase you entered doesn't match the one used during `mcpocket push`. Passphrases are never stored — you need to remember the one you used.
376
+
377
+ ### Push says "Nothing changed"
378
+
379
+ Your local config matches what's already in the remote pocket. No commit/upload needed.
380
+
381
+ ### MCP servers not appearing after pull
382
+
383
+ Restart Claude Desktop to reload MCP server configurations. Claude Code and OpenCode pick up changes automatically.
384
+
385
+ ### Git errors on push/pull (repo mode)
386
+
387
+ Make sure `git` is installed and in your PATH. If you see auth errors, your GitHub token may have expired — run `mcpocket init` to re-authenticate.
388
+
389
+ ---
390
+
391
+ ## Contributing
392
+
393
+ Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/davidsmorais/carry-on).
394
+
395
+ ```bash
396
+ git clone https://github.com/davidsmorais/carry-on.git
397
+ cd carry-on
398
+ pnpm install
399
+ pnpm build
400
+ ```
401
+
402
+ ---
403
+
404
+ ## Author
405
+
406
+ **David Morais** — [david@davidmorais.com](mailto:david@davidmorais.com)
407
+
408
+ - GitHub: [@davidsmorais](https://github.com/davidsmorais)
409
+
410
+ ## License
411
+
412
+ [MIT](LICENSE) © David Morais