@x-code-cli/core 0.2.10 → 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.
Files changed (258) hide show
  1. package/dist/agent/compression.d.ts +12 -2
  2. package/dist/agent/compression.d.ts.map +1 -1
  3. package/dist/agent/compression.js +51 -2
  4. package/dist/agent/compression.js.map +1 -1
  5. package/dist/agent/file-ingest.js +2 -2
  6. package/dist/agent/file-ingest.js.map +1 -1
  7. package/dist/agent/loop-state.d.ts +3 -2
  8. package/dist/agent/loop-state.d.ts.map +1 -1
  9. package/dist/agent/loop-state.js.map +1 -1
  10. package/dist/agent/loop.d.ts.map +1 -1
  11. package/dist/agent/loop.js +134 -5
  12. package/dist/agent/loop.js.map +1 -1
  13. package/dist/agent/memory-extractor.js +5 -5
  14. package/dist/agent/memory-extractor.js.map +1 -1
  15. package/dist/agent/plan-storage.js +1 -1
  16. package/dist/agent/plan-storage.js.map +1 -1
  17. package/dist/agent/sub-agents/index.d.ts +2 -1
  18. package/dist/agent/sub-agents/index.d.ts.map +1 -1
  19. package/dist/agent/sub-agents/index.js +1 -1
  20. package/dist/agent/sub-agents/index.js.map +1 -1
  21. package/dist/agent/sub-agents/loader.d.ts +13 -3
  22. package/dist/agent/sub-agents/loader.d.ts.map +1 -1
  23. package/dist/agent/sub-agents/loader.js +36 -9
  24. package/dist/agent/sub-agents/loader.js.map +1 -1
  25. package/dist/agent/sub-agents/registry.d.ts +18 -1
  26. package/dist/agent/sub-agents/registry.d.ts.map +1 -1
  27. package/dist/agent/sub-agents/registry.js +38 -5
  28. package/dist/agent/sub-agents/registry.js.map +1 -1
  29. package/dist/agent/sub-agents/runner.d.ts.map +1 -1
  30. package/dist/agent/sub-agents/runner.js +45 -1
  31. package/dist/agent/sub-agents/runner.js.map +1 -1
  32. package/dist/agent/sub-agents/types.d.ts +4 -1
  33. package/dist/agent/sub-agents/types.d.ts.map +1 -1
  34. package/dist/agent/system-prompt.d.ts +21 -0
  35. package/dist/agent/system-prompt.d.ts.map +1 -1
  36. package/dist/agent/system-prompt.js +68 -2
  37. package/dist/agent/system-prompt.js.map +1 -1
  38. package/dist/agent/tool-execution.d.ts.map +1 -1
  39. package/dist/agent/tool-execution.js +220 -1
  40. package/dist/agent/tool-execution.js.map +1 -1
  41. package/dist/commands/index.d.ts +6 -0
  42. package/dist/commands/index.d.ts.map +1 -0
  43. package/dist/commands/index.js +3 -0
  44. package/dist/commands/index.js.map +1 -0
  45. package/dist/commands/loader.d.ts +19 -0
  46. package/dist/commands/loader.d.ts.map +1 -0
  47. package/dist/commands/loader.js +109 -0
  48. package/dist/commands/loader.js.map +1 -0
  49. package/dist/commands/registry.d.ts +44 -0
  50. package/dist/commands/registry.d.ts.map +1 -0
  51. package/dist/commands/registry.js +102 -0
  52. package/dist/commands/registry.js.map +1 -0
  53. package/dist/commands/types.d.ts +23 -0
  54. package/dist/commands/types.d.ts.map +1 -0
  55. package/dist/commands/types.js +26 -0
  56. package/dist/commands/types.js.map +1 -0
  57. package/dist/config/index.d.ts +9 -0
  58. package/dist/config/index.d.ts.map +1 -1
  59. package/dist/config/index.js +12 -10
  60. package/dist/config/index.js.map +1 -1
  61. package/dist/hooks/bus.d.ts +54 -0
  62. package/dist/hooks/bus.d.ts.map +1 -0
  63. package/dist/hooks/bus.js +165 -0
  64. package/dist/hooks/bus.js.map +1 -0
  65. package/dist/hooks/config-schema.d.ts +854 -0
  66. package/dist/hooks/config-schema.d.ts.map +1 -0
  67. package/dist/hooks/config-schema.js +79 -0
  68. package/dist/hooks/config-schema.js.map +1 -0
  69. package/dist/hooks/executor.d.ts +16 -0
  70. package/dist/hooks/executor.d.ts.map +1 -0
  71. package/dist/hooks/executor.js +183 -0
  72. package/dist/hooks/executor.js.map +1 -0
  73. package/dist/hooks/index.d.ts +10 -0
  74. package/dist/hooks/index.d.ts.map +1 -0
  75. package/dist/hooks/index.js +6 -0
  76. package/dist/hooks/index.js.map +1 -0
  77. package/dist/hooks/registry.d.ts +23 -0
  78. package/dist/hooks/registry.d.ts.map +1 -0
  79. package/dist/hooks/registry.js +49 -0
  80. package/dist/hooks/registry.js.map +1 -0
  81. package/dist/hooks/types.d.ts +165 -0
  82. package/dist/hooks/types.d.ts.map +1 -0
  83. package/dist/hooks/types.js +25 -0
  84. package/dist/hooks/types.js.map +1 -0
  85. package/dist/hooks/variables.d.ts +22 -0
  86. package/dist/hooks/variables.d.ts.map +1 -0
  87. package/dist/hooks/variables.js +80 -0
  88. package/dist/hooks/variables.js.map +1 -0
  89. package/dist/index.d.ts +57 -2
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +38 -2
  92. package/dist/index.js.map +1 -1
  93. package/dist/knowledge/auto-memory.d.ts +1 -1
  94. package/dist/knowledge/auto-memory.d.ts.map +1 -1
  95. package/dist/knowledge/auto-memory.js +10 -10
  96. package/dist/knowledge/auto-memory.js.map +1 -1
  97. package/dist/knowledge/loader.js +12 -12
  98. package/dist/knowledge/loader.js.map +1 -1
  99. package/dist/mcp/arg-parser.d.ts +49 -0
  100. package/dist/mcp/arg-parser.d.ts.map +1 -0
  101. package/dist/mcp/arg-parser.js +357 -0
  102. package/dist/mcp/arg-parser.js.map +1 -0
  103. package/dist/mcp/client.d.ts +73 -0
  104. package/dist/mcp/client.d.ts.map +1 -0
  105. package/dist/mcp/client.js +376 -0
  106. package/dist/mcp/client.js.map +1 -0
  107. package/dist/mcp/config-schema.d.ts +64 -0
  108. package/dist/mcp/config-schema.d.ts.map +1 -0
  109. package/dist/mcp/config-schema.js +86 -0
  110. package/dist/mcp/config-schema.js.map +1 -0
  111. package/dist/mcp/config-writer.d.ts +41 -0
  112. package/dist/mcp/config-writer.d.ts.map +1 -0
  113. package/dist/mcp/config-writer.js +138 -0
  114. package/dist/mcp/config-writer.js.map +1 -0
  115. package/dist/mcp/env-safety.d.ts +12 -0
  116. package/dist/mcp/env-safety.d.ts.map +1 -0
  117. package/dist/mcp/env-safety.js +80 -0
  118. package/dist/mcp/env-safety.js.map +1 -0
  119. package/dist/mcp/expand-env.d.ts +14 -0
  120. package/dist/mcp/expand-env.d.ts.map +1 -0
  121. package/dist/mcp/expand-env.js +52 -0
  122. package/dist/mcp/expand-env.js.map +1 -0
  123. package/dist/mcp/loader.d.ts +81 -0
  124. package/dist/mcp/loader.d.ts.map +1 -0
  125. package/dist/mcp/loader.js +223 -0
  126. package/dist/mcp/loader.js.map +1 -0
  127. package/dist/mcp/name-mangling.d.ts +11 -0
  128. package/dist/mcp/name-mangling.d.ts.map +1 -0
  129. package/dist/mcp/name-mangling.js +82 -0
  130. package/dist/mcp/name-mangling.js.map +1 -0
  131. package/dist/mcp/oauth/callback-server.d.ts +25 -0
  132. package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
  133. package/dist/mcp/oauth/callback-server.js +118 -0
  134. package/dist/mcp/oauth/callback-server.js.map +1 -0
  135. package/dist/mcp/oauth/provider.d.ts +80 -0
  136. package/dist/mcp/oauth/provider.d.ts.map +1 -0
  137. package/dist/mcp/oauth/provider.js +292 -0
  138. package/dist/mcp/oauth/provider.js.map +1 -0
  139. package/dist/mcp/oauth/token-storage.d.ts +42 -0
  140. package/dist/mcp/oauth/token-storage.d.ts.map +1 -0
  141. package/dist/mcp/oauth/token-storage.js +121 -0
  142. package/dist/mcp/oauth/token-storage.js.map +1 -0
  143. package/dist/mcp/permissions.d.ts +28 -0
  144. package/dist/mcp/permissions.d.ts.map +1 -0
  145. package/dist/mcp/permissions.js +105 -0
  146. package/dist/mcp/permissions.js.map +1 -0
  147. package/dist/mcp/registry.d.ts +150 -0
  148. package/dist/mcp/registry.d.ts.map +1 -0
  149. package/dist/mcp/registry.js +334 -0
  150. package/dist/mcp/registry.js.map +1 -0
  151. package/dist/mcp/resources.d.ts +7 -0
  152. package/dist/mcp/resources.d.ts.map +1 -0
  153. package/dist/mcp/resources.js +40 -0
  154. package/dist/mcp/resources.js.map +1 -0
  155. package/dist/mcp/tool-bridge.d.ts +16 -0
  156. package/dist/mcp/tool-bridge.d.ts.map +1 -0
  157. package/dist/mcp/tool-bridge.js +56 -0
  158. package/dist/mcp/tool-bridge.js.map +1 -0
  159. package/dist/mcp/trust.d.ts +31 -0
  160. package/dist/mcp/trust.d.ts.map +1 -0
  161. package/dist/mcp/trust.js +103 -0
  162. package/dist/mcp/trust.js.map +1 -0
  163. package/dist/mcp/types.d.ts +73 -0
  164. package/dist/mcp/types.d.ts.map +1 -0
  165. package/dist/mcp/types.js +13 -0
  166. package/dist/mcp/types.js.map +1 -0
  167. package/dist/permissions/index.d.ts +1 -1
  168. package/dist/permissions/index.d.ts.map +1 -1
  169. package/dist/permissions/index.js +10 -4
  170. package/dist/permissions/index.js.map +1 -1
  171. package/dist/permissions/session-store.d.ts +79 -17
  172. package/dist/permissions/session-store.d.ts.map +1 -1
  173. package/dist/permissions/session-store.js +298 -38
  174. package/dist/permissions/session-store.js.map +1 -1
  175. package/dist/plugins/consent.d.ts +87 -0
  176. package/dist/plugins/consent.d.ts.map +1 -0
  177. package/dist/plugins/consent.js +181 -0
  178. package/dist/plugins/consent.js.map +1 -0
  179. package/dist/plugins/enable-state.d.ts +34 -0
  180. package/dist/plugins/enable-state.d.ts.map +1 -0
  181. package/dist/plugins/enable-state.js +159 -0
  182. package/dist/plugins/enable-state.js.map +1 -0
  183. package/dist/plugins/installer.d.ts +64 -0
  184. package/dist/plugins/installer.d.ts.map +1 -0
  185. package/dist/plugins/installer.js +416 -0
  186. package/dist/plugins/installer.js.map +1 -0
  187. package/dist/plugins/integration.d.ts +91 -0
  188. package/dist/plugins/integration.d.ts.map +1 -0
  189. package/dist/plugins/integration.js +233 -0
  190. package/dist/plugins/integration.js.map +1 -0
  191. package/dist/plugins/loader.d.ts +69 -0
  192. package/dist/plugins/loader.d.ts.map +1 -0
  193. package/dist/plugins/loader.js +243 -0
  194. package/dist/plugins/loader.js.map +1 -0
  195. package/dist/plugins/manifest.d.ts +23 -0
  196. package/dist/plugins/manifest.d.ts.map +1 -0
  197. package/dist/plugins/manifest.js +143 -0
  198. package/dist/plugins/manifest.js.map +1 -0
  199. package/dist/plugins/marketplace.d.ts +103 -0
  200. package/dist/plugins/marketplace.d.ts.map +1 -0
  201. package/dist/plugins/marketplace.js +532 -0
  202. package/dist/plugins/marketplace.js.map +1 -0
  203. package/dist/plugins/paths.d.ts +44 -0
  204. package/dist/plugins/paths.d.ts.map +1 -0
  205. package/dist/plugins/paths.js +89 -0
  206. package/dist/plugins/paths.js.map +1 -0
  207. package/dist/plugins/refresh.d.ts +61 -0
  208. package/dist/plugins/refresh.d.ts.map +1 -0
  209. package/dist/plugins/refresh.js +98 -0
  210. package/dist/plugins/refresh.js.map +1 -0
  211. package/dist/plugins/registry.d.ts +40 -0
  212. package/dist/plugins/registry.d.ts.map +1 -0
  213. package/dist/plugins/registry.js +80 -0
  214. package/dist/plugins/registry.js.map +1 -0
  215. package/dist/plugins/types.d.ts +225 -0
  216. package/dist/plugins/types.d.ts.map +1 -0
  217. package/dist/plugins/types.js +16 -0
  218. package/dist/plugins/types.js.map +1 -0
  219. package/dist/plugins/user-config.d.ts +22 -0
  220. package/dist/plugins/user-config.d.ts.map +1 -0
  221. package/dist/plugins/user-config.js +96 -0
  222. package/dist/plugins/user-config.js.map +1 -0
  223. package/dist/skills/loader.d.ts +19 -0
  224. package/dist/skills/loader.d.ts.map +1 -0
  225. package/dist/skills/loader.js +197 -0
  226. package/dist/skills/loader.js.map +1 -0
  227. package/dist/skills/registry.d.ts +74 -0
  228. package/dist/skills/registry.d.ts.map +1 -0
  229. package/dist/skills/registry.js +136 -0
  230. package/dist/skills/registry.js.map +1 -0
  231. package/dist/skills/settings.d.ts +13 -0
  232. package/dist/skills/settings.d.ts.map +1 -0
  233. package/dist/skills/settings.js +100 -0
  234. package/dist/skills/settings.js.map +1 -0
  235. package/dist/tools/activate-skill.d.ts +5 -0
  236. package/dist/tools/activate-skill.d.ts.map +1 -0
  237. package/dist/tools/activate-skill.js +33 -0
  238. package/dist/tools/activate-skill.js.map +1 -0
  239. package/dist/tools/index.d.ts +1 -1
  240. package/dist/tools/shell-utils.d.ts.map +1 -1
  241. package/dist/tools/shell-utils.js +157 -6
  242. package/dist/tools/shell-utils.js.map +1 -1
  243. package/dist/tools/todo-write.d.ts +1 -1
  244. package/dist/tools/web-fetch.d.ts.map +1 -1
  245. package/dist/tools/web-fetch.js +2 -1
  246. package/dist/tools/web-fetch.js.map +1 -1
  247. package/dist/types/index.d.ts +46 -1
  248. package/dist/types/index.d.ts.map +1 -1
  249. package/dist/types/index.js.map +1 -1
  250. package/dist/utils.d.ts +23 -2
  251. package/dist/utils.d.ts.map +1 -1
  252. package/dist/utils.js +76 -20
  253. package/dist/utils.js.map +1 -1
  254. package/dist/version.d.ts +2 -0
  255. package/dist/version.d.ts.map +1 -0
  256. package/dist/version.js +47 -0
  257. package/dist/version.js.map +1 -0
  258. package/package.json +2 -1
@@ -0,0 +1,357 @@
1
+ /** Names allowed in `mcpServers.<name>`. Tightened relative to the runtime
2
+ * name-mangling sanitizer because *config entry point* is a better place
3
+ * to refuse weird names — surprising sanitisation post-add ("I typed
4
+ * `my server!` and got `my_server___xxx`") is worse than a clear
5
+ * rejection. Length 32 leaves headroom for the `{server}__{tool}`
6
+ * format to stay well under the model-side 64-char tool name limit. */
7
+ const NAME_RE = /^[a-zA-Z0-9_-]{1,32}$/;
8
+ // ── Top-level entry points ─────────────────────────────────────────────────
9
+ /** Parse args for `/mcp add [...flags] <name> <command-or-url> [args...]`. */
10
+ export function parseAdd(rawArg) {
11
+ const tokRes = tokenize(rawArg);
12
+ if (!tokRes.ok)
13
+ return tokRes;
14
+ const tokens = tokRes.tokens;
15
+ // First pass: pull flags off the front. Stop at the first non-flag token
16
+ // (which becomes the server name); the `--` separator hard-stops flag
17
+ // parsing and is then dropped — everything after is positional.
18
+ let isHttp = false;
19
+ let scope = 'user';
20
+ let timeout;
21
+ const envEntries = [];
22
+ const headerEntries = [];
23
+ let i = 0;
24
+ let sawDoubleDash = false;
25
+ while (i < tokens.length) {
26
+ const t = tokens[i];
27
+ if (!t.startsWith('-'))
28
+ break; // first positional
29
+ if (t === '--') {
30
+ sawDoubleDash = true;
31
+ i++;
32
+ break;
33
+ }
34
+ if (t === '--http' || t === '--transport') {
35
+ // --http is our shorthand; --transport <name> is Claude/Gemini syntax
36
+ // (we accept only http here; sse is intentionally not supported per
37
+ // the design doc — MCP spec deprecated SSE in 2025-03).
38
+ if (t === '--transport') {
39
+ const next = tokens[i + 1];
40
+ if (next !== 'http') {
41
+ return err(`--transport only supports "http" (got ${next ?? '(missing)'}); use --http directly or omit for stdio`);
42
+ }
43
+ i += 2;
44
+ }
45
+ else {
46
+ i++;
47
+ }
48
+ isHttp = true;
49
+ continue;
50
+ }
51
+ if (t === '--scope') {
52
+ const v = tokens[i + 1];
53
+ if (v !== 'user' && v !== 'project') {
54
+ return err(`--scope requires "user" or "project" (got ${v ?? '(missing)'})`);
55
+ }
56
+ scope = v;
57
+ i += 2;
58
+ continue;
59
+ }
60
+ if (t === '--env') {
61
+ const v = tokens[i + 1];
62
+ if (typeof v !== 'string')
63
+ return err('--env requires a KEY=VALUE argument');
64
+ const eq = v.indexOf('=');
65
+ if (eq <= 0)
66
+ return err(`--env expects KEY=VALUE (got ${v})`);
67
+ envEntries.push([v.slice(0, eq), v.slice(eq + 1)]);
68
+ i += 2;
69
+ continue;
70
+ }
71
+ if (t === '--header') {
72
+ const v = tokens[i + 1];
73
+ if (typeof v !== 'string')
74
+ return err('--header requires a "Key: value" argument');
75
+ // Header format: "Key: Value" (RFC 7230 style). Be permissive with
76
+ // whitespace around the colon to match user habit.
77
+ const colon = v.indexOf(':');
78
+ if (colon <= 0)
79
+ return err(`--header expects "Key: Value" (got ${v})`);
80
+ headerEntries.push([v.slice(0, colon).trim(), v.slice(colon + 1).trim()]);
81
+ i += 2;
82
+ continue;
83
+ }
84
+ if (t === '--timeout') {
85
+ const v = tokens[i + 1];
86
+ if (typeof v !== 'string')
87
+ return err('--timeout requires a number (ms)');
88
+ const n = Number(v);
89
+ if (!Number.isInteger(n) || n <= 0)
90
+ return err(`--timeout requires a positive integer (got ${v})`);
91
+ timeout = n;
92
+ i += 2;
93
+ continue;
94
+ }
95
+ return err(`Unknown flag: ${t}`);
96
+ }
97
+ // Positional args. After the (optional) `--`, everything left is name +
98
+ // command/url + the rest. Stdio: tokens[i] = name, tokens[i+1] = command,
99
+ // tokens[i+2..] = args. HTTP: tokens[i] = name, tokens[i+1] = url, nothing
100
+ // after.
101
+ //
102
+ // Users coming from Claude Code muscle-memory write `add <name> -- <cmd>`
103
+ // with the separator AFTER the name. Our flag loop already stops at the
104
+ // first non-flag (the name), so any `--` lands at positional[1]. Drop it
105
+ // — it's cosmetic, the actual command follows.
106
+ let positional = tokens.slice(i);
107
+ if (positional[1] === '--') {
108
+ positional = [positional[0], ...positional.slice(2)];
109
+ }
110
+ if (positional.length < 2) {
111
+ return err(isHttp
112
+ ? 'Usage: /mcp add --http [--scope user|project] [--header "K: V"]... [--timeout N] <name> <url>'
113
+ : 'Usage: /mcp add [--scope user|project] [--env K=V]... [--timeout N] <name> <command> [args...]');
114
+ }
115
+ const name = positional[0];
116
+ if (!NAME_RE.test(name)) {
117
+ return err(`Invalid server name "${name}". Must match ${NAME_RE.source}.`);
118
+ }
119
+ if (isHttp) {
120
+ if (positional.length > 2) {
121
+ return err('HTTP servers take only <name> <url> — no extra positional args');
122
+ }
123
+ if (envEntries.length > 0)
124
+ return err('--env is only valid for stdio servers');
125
+ const url = positional[1];
126
+ if (!isValidUrl(url))
127
+ return err(`Invalid URL: ${url}`);
128
+ const config = {
129
+ url,
130
+ ...(headerEntries.length > 0 ? { headers: Object.fromEntries(headerEntries) } : {}),
131
+ ...(timeout !== undefined ? { timeout } : {}),
132
+ };
133
+ return ok({ kind: 'add', name, scope, config });
134
+ }
135
+ // stdio. `--` is allowed but optional. Some users will write
136
+ // `/mcp add fs npx -y @pkg/foo /tmp`, others `/mcp add fs -- npx -y ...`.
137
+ // Both reach this branch identically — we already stripped `--` upstream.
138
+ void sawDoubleDash;
139
+ if (headerEntries.length > 0)
140
+ return err('--header is only valid for HTTP servers (--http)');
141
+ const command = positional[1];
142
+ const args = positional.slice(2);
143
+ const config = {
144
+ command,
145
+ ...(args.length > 0 ? { args } : {}),
146
+ ...(envEntries.length > 0 ? { env: Object.fromEntries(envEntries) } : {}),
147
+ ...(timeout !== undefined ? { timeout } : {}),
148
+ };
149
+ return ok({ kind: 'add', name, scope, config });
150
+ }
151
+ /** Parse args for `/mcp add-json [--scope ...] <name> '<json>'`.
152
+ * The JSON blob is whatever the schema accepts — same validation runs
153
+ * on the loader side, so passing parseServerConfig here keeps errors
154
+ * uniform between "wrote it via CLI" and "edited the file by hand". */
155
+ export function parseAddJson(rawArg) {
156
+ // add-json uniquely benefits from KEEPING the JSON literal intact rather
157
+ // than running it through the shell tokeniser (which would mangle nested
158
+ // quotes). Strategy: pull flags + name off the front via tokenize on the
159
+ // *prefix* up to where the JSON begins, then take the JSON as the
160
+ // suffix verbatim. We find the JSON start by looking for the first `{`
161
+ // after the name token.
162
+ const trimmed = rawArg.trim();
163
+ if (!trimmed) {
164
+ return err("Usage: /mcp add-json [--scope user|project] <name> '<json>'");
165
+ }
166
+ // Walk through tokens until we either run out of flags/name OR hit a
167
+ // token starting with `{`. The JSON blob may have been entered single-
168
+ // quoted to the slash command — in that case the tokeniser strips the
169
+ // quotes and we get a clean object string. If unquoted, the user
170
+ // shouldn't have nested whitespace anyway, so a single token suffices.
171
+ const tokRes = tokenize(trimmed);
172
+ if (!tokRes.ok)
173
+ return tokRes;
174
+ const tokens = tokRes.tokens;
175
+ let scope = 'user';
176
+ let i = 0;
177
+ while (i < tokens.length) {
178
+ const t = tokens[i];
179
+ if (t === '--scope') {
180
+ const v = tokens[i + 1];
181
+ if (v !== 'user' && v !== 'project') {
182
+ return err(`--scope requires "user" or "project" (got ${v ?? '(missing)'})`);
183
+ }
184
+ scope = v;
185
+ i += 2;
186
+ continue;
187
+ }
188
+ if (!t.startsWith('-'))
189
+ break;
190
+ return err(`Unknown flag for add-json: ${t}`);
191
+ }
192
+ if (i >= tokens.length) {
193
+ return err("Usage: /mcp add-json [--scope user|project] <name> '<json>'");
194
+ }
195
+ const name = tokens[i];
196
+ if (!NAME_RE.test(name)) {
197
+ return err(`Invalid server name "${name}". Must match ${NAME_RE.source}.`);
198
+ }
199
+ i++;
200
+ // The JSON might have been split across tokens if the user didn't quote
201
+ // it. Concatenate the remainder with single spaces; JSON parsing tolerates
202
+ // any whitespace between tokens so this round-trips fine in practice.
203
+ if (i >= tokens.length) {
204
+ return err(`Missing JSON body for "${name}". Wrap it in single quotes: '{...}'`);
205
+ }
206
+ const jsonBlob = tokens.slice(i).join(' ').trim();
207
+ let parsed;
208
+ try {
209
+ parsed = JSON.parse(jsonBlob);
210
+ }
211
+ catch (e) {
212
+ return err(`Invalid JSON: ${e instanceof Error ? e.message : String(e)}`);
213
+ }
214
+ // We validate via the same zod schema the loader uses, but we keep the
215
+ // dependency in the writer layer to avoid a circular import here — so
216
+ // signal "needs validation" by returning the parsed object as
217
+ // McpServerConfig and letting the caller validate. The writer DOES
218
+ // validate before writing (see config-writer.ts).
219
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
220
+ return err('JSON body must be an object');
221
+ }
222
+ return ok({ kind: 'add-json', name, scope, config: parsed });
223
+ }
224
+ /** Parse args for `/mcp remove [--scope ...] <name>`. */
225
+ export function parseRemove(rawArg) {
226
+ const tokRes = tokenize(rawArg);
227
+ if (!tokRes.ok)
228
+ return tokRes;
229
+ const tokens = tokRes.tokens;
230
+ if (tokens.length === 0) {
231
+ return err('Usage: /mcp remove [--scope user|project] <name>');
232
+ }
233
+ let scope;
234
+ let i = 0;
235
+ while (i < tokens.length) {
236
+ const t = tokens[i];
237
+ if (t === '--scope') {
238
+ const v = tokens[i + 1];
239
+ if (v !== 'user' && v !== 'project') {
240
+ return err(`--scope requires "user" or "project" (got ${v ?? '(missing)'})`);
241
+ }
242
+ scope = v;
243
+ i += 2;
244
+ continue;
245
+ }
246
+ if (!t.startsWith('-'))
247
+ break;
248
+ return err(`Unknown flag for remove: ${t}`);
249
+ }
250
+ if (i >= tokens.length) {
251
+ return err('Usage: /mcp remove [--scope user|project] <name>');
252
+ }
253
+ if (i + 1 < tokens.length) {
254
+ return err(`/mcp remove takes exactly one name (got extra: ${tokens.slice(i + 1).join(' ')})`);
255
+ }
256
+ const name = tokens[i];
257
+ if (!NAME_RE.test(name)) {
258
+ return err(`Invalid server name "${name}". Must match ${NAME_RE.source}.`);
259
+ }
260
+ return ok({ kind: 'remove', name, scope });
261
+ }
262
+ // ── Internals ──────────────────────────────────────────────────────────────
263
+ function ok(command) {
264
+ return { ok: true, command };
265
+ }
266
+ function err(message) {
267
+ return { ok: false, error: message };
268
+ }
269
+ /** Minimal POSIX-ish tokeniser. Supports "..."/'...' quoting and
270
+ * backslash-escape of any single char. Quotes are stripped from the
271
+ * output; escapes drop the backslash. Returns a tagged result so the
272
+ * caller can surface "unclosed quote" without throwing. */
273
+ export function tokenize(input) {
274
+ const tokens = [];
275
+ let i = 0;
276
+ const n = input.length;
277
+ while (i < n) {
278
+ // Skip whitespace between tokens.
279
+ while (i < n && /\s/.test(input[i]))
280
+ i++;
281
+ if (i >= n)
282
+ break;
283
+ let token = '';
284
+ let quote = null;
285
+ let inToken = true;
286
+ while (i < n && inToken) {
287
+ const c = input[i];
288
+ if (quote) {
289
+ if (c === '\\' && quote === '"' && i + 1 < n) {
290
+ // Inside double quotes, allow backslash escape for " and \.
291
+ const next = input[i + 1];
292
+ if (next === '"' || next === '\\') {
293
+ token += next;
294
+ i += 2;
295
+ continue;
296
+ }
297
+ // Otherwise keep the backslash literal — POSIX behaviour.
298
+ token += c;
299
+ i++;
300
+ continue;
301
+ }
302
+ if (c === quote) {
303
+ quote = null;
304
+ i++;
305
+ continue;
306
+ }
307
+ token += c;
308
+ i++;
309
+ continue;
310
+ }
311
+ // Unquoted.
312
+ if (c === '"' || c === "'") {
313
+ quote = c;
314
+ i++;
315
+ continue;
316
+ }
317
+ if (c === '\\' && i + 1 < n) {
318
+ // Only escape whitespace, quotes, and backslash itself. Anything
319
+ // else passes through with the backslash intact so Windows paths
320
+ // like `D:\res\x-code-cli\tmp` survive — eating those backslashes
321
+ // would silently corrupt the path and the user wouldn't notice
322
+ // until the MCP server failed to access the directory.
323
+ const next = input[i + 1];
324
+ if (next === ' ' || next === '\t' || next === '"' || next === "'" || next === '\\') {
325
+ token += next;
326
+ i += 2;
327
+ continue;
328
+ }
329
+ // Backslash followed by anything else: keep both chars literal.
330
+ token += c;
331
+ i++;
332
+ continue;
333
+ }
334
+ if (/\s/.test(c)) {
335
+ inToken = false;
336
+ break;
337
+ }
338
+ token += c;
339
+ i++;
340
+ }
341
+ if (quote) {
342
+ return { ok: false, error: `Unclosed ${quote} quote` };
343
+ }
344
+ tokens.push(token);
345
+ }
346
+ return { ok: true, tokens };
347
+ }
348
+ function isValidUrl(s) {
349
+ try {
350
+ const u = new URL(s);
351
+ return u.protocol === 'http:' || u.protocol === 'https:';
352
+ }
353
+ catch {
354
+ return false;
355
+ }
356
+ }
357
+ //# sourceMappingURL=arg-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arg-parser.js","sourceRoot":"","sources":["../../src/mcp/arg-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { type OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
2
+ import { type McpCallResult, type McpResourceEntry, type McpServerConfig } from './types.js';
3
+ export interface ConnectInfo {
4
+ toolCount: number;
5
+ resourceCount: number;
6
+ }
7
+ export declare class McpClient {
8
+ readonly serverName: string;
9
+ private readonly config;
10
+ /** Optional OAuth provider for HTTP servers. Stdio servers ignore this. */
11
+ private readonly authProvider?;
12
+ /** SDK client. Only present after a successful connect. */
13
+ private client;
14
+ /** SDK transport. Owned by us so we can `close()` it cleanly. */
15
+ private transport;
16
+ /** Rolling tail of stderr (stdio servers only). */
17
+ private stderrTail;
18
+ /** Cached results from the last connect, served to the registry. */
19
+ private cachedTools;
20
+ private cachedResources;
21
+ constructor(serverName: string, config: McpServerConfig,
22
+ /** Optional OAuth provider for HTTP servers. Stdio servers ignore this. */
23
+ authProvider?: OAuthClientProvider | undefined);
24
+ /** Spawn / dial the server and complete the MCP initialize handshake.
25
+ * On success, populates internal tool + resource caches. On failure,
26
+ * cleans up the transport (no zombie subprocess) and re-throws. */
27
+ connect(): Promise<ConnectInfo>;
28
+ /** Tools discovered at connect time. Stable for the connection lifetime;
29
+ * refresh by calling connect() again on a fresh McpClient. */
30
+ tools(): ReadonlyArray<{
31
+ name: string;
32
+ description?: string;
33
+ inputSchema: Record<string, unknown>;
34
+ }>;
35
+ resources(): ReadonlyArray<McpResourceEntry>;
36
+ /** Connect with a full interactive OAuth round-trip.
37
+ *
38
+ * The MCP SDK's StreamableHTTP transport handles auth lazily: a fresh
39
+ * connect with no stored token calls `authProvider.redirectToAuthorization`
40
+ * and then throws `UnauthorizedError` because the token-exchange step
41
+ * has to wait for the user. The caller is expected to wait for the
42
+ * redirect callback to land, hand the authorization code to
43
+ * `transport.finishAuth(code)`, then retry connect — at which point
44
+ * tokens are saved and the next attempt succeeds.
45
+ *
46
+ * We encapsulate that dance here so that the `/mcp auth` handler can
47
+ * opt into "drive OAuth to completion" without knowing about
48
+ * `finishAuth`. The default `connect()` path keeps the OAuth provider
49
+ * PASSIVE — `redirectToAuthorization` is a no-op until we flip
50
+ * `setInteractive(true)` here, so CLI boot doesn't accidentally pop a
51
+ * browser window for servers in `needs_auth`. */
52
+ connectWithOAuth(hooks?: {
53
+ onBrowserOpen?: (url: string) => void;
54
+ }): Promise<ConnectInfo>;
55
+ /** The actual two-phase connect: attempt-1 fires redirect, then we
56
+ * wait for the user, finish the auth, attempt-2 lands a real
57
+ * session. Both attempts share `cachedTools` / `cachedResources`. */
58
+ private runOAuthDance;
59
+ callTool(name: string, args: unknown, signal?: AbortSignal): Promise<McpCallResult>;
60
+ readResource(uri: string, signal?: AbortSignal): Promise<{
61
+ text: string;
62
+ mimeType?: string;
63
+ }>;
64
+ /** Snapshot the last N stderr lines for diagnostics. Empty for HTTP. */
65
+ stderr(): string;
66
+ close(): Promise<void>;
67
+ private buildTransport;
68
+ private safeClose;
69
+ /** Attach stderr tail (if any) to a connect error so /mcp list shows
70
+ * something more useful than "Connection closed". */
71
+ private enrichError;
72
+ }
73
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,mBAAmB,EAAqB,MAAM,0CAA0C,CAAA;AAWtG,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAGrB,MAAM,YAAY,CAAA;AAgBnB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,qBAAa,SAAS;aAYF,UAAU,EAAE,MAAM;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAdhC,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAsB;IACpC,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAAyB;IAC1C,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAe;IACjC,oEAAoE;IACpE,OAAO,CAAC,WAAW,CAA0F;IAC7G,OAAO,CAAC,eAAe,CAAyB;gBAG9B,UAAU,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe;IACxC,2EAA2E;IAC1D,YAAY,CAAC,EAAE,mBAAmB,YAAA;IAGrD;;wEAEoE;IAC9D,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;IAkErC;mEAC+D;IAC/D,KAAK,IAAI,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAIpG,SAAS,IAAI,aAAa,CAAC,gBAAgB,CAAC;IAI5C;;;;;;;;;;;;;;;sDAekD;IAC5C,gBAAgB,CAAC,KAAK,GAAE;QAAE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IA+CnG;;0EAEsE;YACxD,aAAa;IAmCrB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAUnF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBnG,wEAAwE;IACxE,MAAM,IAAI,MAAM;IAIV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,OAAO,CAAC,cAAc;YAqCR,SAAS;IAmBvB;0DACsD;IACtD,OAAO,CAAC,WAAW;CAQpB"}