@x-code-cli/core 0.2.9 → 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/dist/agent/compression.d.ts +12 -2
- package/dist/agent/compression.d.ts.map +1 -1
- package/dist/agent/compression.js +51 -2
- package/dist/agent/compression.js.map +1 -1
- package/dist/agent/file-ingest.js +2 -2
- package/dist/agent/file-ingest.js.map +1 -1
- package/dist/agent/loop-state.d.ts +3 -2
- package/dist/agent/loop-state.d.ts.map +1 -1
- package/dist/agent/loop-state.js.map +1 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +140 -9
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-extractor.js +5 -5
- package/dist/agent/memory-extractor.js.map +1 -1
- package/dist/agent/plan-storage.js +1 -1
- package/dist/agent/plan-storage.js.map +1 -1
- package/dist/agent/sub-agents/index.d.ts +2 -1
- package/dist/agent/sub-agents/index.d.ts.map +1 -1
- package/dist/agent/sub-agents/index.js +1 -1
- package/dist/agent/sub-agents/index.js.map +1 -1
- package/dist/agent/sub-agents/loader.d.ts +13 -3
- package/dist/agent/sub-agents/loader.d.ts.map +1 -1
- package/dist/agent/sub-agents/loader.js +36 -9
- package/dist/agent/sub-agents/loader.js.map +1 -1
- package/dist/agent/sub-agents/registry.d.ts +18 -1
- package/dist/agent/sub-agents/registry.d.ts.map +1 -1
- package/dist/agent/sub-agents/registry.js +38 -5
- package/dist/agent/sub-agents/registry.js.map +1 -1
- package/dist/agent/sub-agents/runner.d.ts.map +1 -1
- package/dist/agent/sub-agents/runner.js +45 -1
- package/dist/agent/sub-agents/runner.js.map +1 -1
- package/dist/agent/sub-agents/types.d.ts +4 -1
- package/dist/agent/sub-agents/types.d.ts.map +1 -1
- package/dist/agent/system-prompt.d.ts +21 -0
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +68 -2
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-execution.d.ts.map +1 -1
- package/dist/agent/tool-execution.js +220 -1
- package/dist/agent/tool-execution.js.map +1 -1
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/loader.d.ts +13 -0
- package/dist/commands/loader.d.ts.map +1 -0
- package/dist/commands/loader.js +93 -0
- package/dist/commands/loader.js.map +1 -0
- package/dist/commands/registry.d.ts +44 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +102 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/types.d.ts +23 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +26 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +12 -10
- package/dist/config/index.js.map +1 -1
- package/dist/hooks/bus.d.ts +54 -0
- package/dist/hooks/bus.d.ts.map +1 -0
- package/dist/hooks/bus.js +165 -0
- package/dist/hooks/bus.js.map +1 -0
- package/dist/hooks/config-schema.d.ts +854 -0
- package/dist/hooks/config-schema.d.ts.map +1 -0
- package/dist/hooks/config-schema.js +79 -0
- package/dist/hooks/config-schema.js.map +1 -0
- package/dist/hooks/executor.d.ts +16 -0
- package/dist/hooks/executor.d.ts.map +1 -0
- package/dist/hooks/executor.js +183 -0
- package/dist/hooks/executor.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registry.d.ts +23 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +49 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/types.d.ts +165 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +25 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/hooks/variables.d.ts +22 -0
- package/dist/hooks/variables.d.ts.map +1 -0
- package/dist/hooks/variables.js +80 -0
- package/dist/hooks/variables.js.map +1 -0
- package/dist/index.d.ts +56 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge/auto-memory.d.ts +1 -1
- package/dist/knowledge/auto-memory.d.ts.map +1 -1
- package/dist/knowledge/auto-memory.js +10 -10
- package/dist/knowledge/auto-memory.js.map +1 -1
- package/dist/knowledge/loader.js +12 -12
- package/dist/knowledge/loader.js.map +1 -1
- package/dist/mcp/arg-parser.d.ts +49 -0
- package/dist/mcp/arg-parser.d.ts.map +1 -0
- package/dist/mcp/arg-parser.js +357 -0
- package/dist/mcp/arg-parser.js.map +1 -0
- package/dist/mcp/client.d.ts +73 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +376 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config-schema.d.ts +64 -0
- package/dist/mcp/config-schema.d.ts.map +1 -0
- package/dist/mcp/config-schema.js +86 -0
- package/dist/mcp/config-schema.js.map +1 -0
- package/dist/mcp/config-writer.d.ts +41 -0
- package/dist/mcp/config-writer.d.ts.map +1 -0
- package/dist/mcp/config-writer.js +138 -0
- package/dist/mcp/config-writer.js.map +1 -0
- package/dist/mcp/env-safety.d.ts +12 -0
- package/dist/mcp/env-safety.d.ts.map +1 -0
- package/dist/mcp/env-safety.js +80 -0
- package/dist/mcp/env-safety.js.map +1 -0
- package/dist/mcp/expand-env.d.ts +14 -0
- package/dist/mcp/expand-env.d.ts.map +1 -0
- package/dist/mcp/expand-env.js +52 -0
- package/dist/mcp/expand-env.js.map +1 -0
- package/dist/mcp/loader.d.ts +81 -0
- package/dist/mcp/loader.d.ts.map +1 -0
- package/dist/mcp/loader.js +223 -0
- package/dist/mcp/loader.js.map +1 -0
- package/dist/mcp/name-mangling.d.ts +11 -0
- package/dist/mcp/name-mangling.d.ts.map +1 -0
- package/dist/mcp/name-mangling.js +82 -0
- package/dist/mcp/name-mangling.js.map +1 -0
- package/dist/mcp/oauth/callback-server.d.ts +25 -0
- package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
- package/dist/mcp/oauth/callback-server.js +118 -0
- package/dist/mcp/oauth/callback-server.js.map +1 -0
- package/dist/mcp/oauth/provider.d.ts +80 -0
- package/dist/mcp/oauth/provider.d.ts.map +1 -0
- package/dist/mcp/oauth/provider.js +292 -0
- package/dist/mcp/oauth/provider.js.map +1 -0
- package/dist/mcp/oauth/token-storage.d.ts +42 -0
- package/dist/mcp/oauth/token-storage.d.ts.map +1 -0
- package/dist/mcp/oauth/token-storage.js +121 -0
- package/dist/mcp/oauth/token-storage.js.map +1 -0
- package/dist/mcp/permissions.d.ts +28 -0
- package/dist/mcp/permissions.d.ts.map +1 -0
- package/dist/mcp/permissions.js +105 -0
- package/dist/mcp/permissions.js.map +1 -0
- package/dist/mcp/registry.d.ts +150 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +334 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +7 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +40 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/tool-bridge.d.ts +16 -0
- package/dist/mcp/tool-bridge.d.ts.map +1 -0
- package/dist/mcp/tool-bridge.js +56 -0
- package/dist/mcp/tool-bridge.js.map +1 -0
- package/dist/mcp/trust.d.ts +31 -0
- package/dist/mcp/trust.d.ts.map +1 -0
- package/dist/mcp/trust.js +103 -0
- package/dist/mcp/trust.js.map +1 -0
- package/dist/mcp/types.d.ts +73 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +13 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/permissions/session-store.d.ts +13 -2
- package/dist/permissions/session-store.d.ts.map +1 -1
- package/dist/permissions/session-store.js +264 -62
- package/dist/permissions/session-store.js.map +1 -1
- package/dist/plugins/consent.d.ts +87 -0
- package/dist/plugins/consent.d.ts.map +1 -0
- package/dist/plugins/consent.js +181 -0
- package/dist/plugins/consent.js.map +1 -0
- package/dist/plugins/enable-state.d.ts +34 -0
- package/dist/plugins/enable-state.d.ts.map +1 -0
- package/dist/plugins/enable-state.js +159 -0
- package/dist/plugins/enable-state.js.map +1 -0
- package/dist/plugins/installer.d.ts +64 -0
- package/dist/plugins/installer.d.ts.map +1 -0
- package/dist/plugins/installer.js +416 -0
- package/dist/plugins/installer.js.map +1 -0
- package/dist/plugins/integration.d.ts +91 -0
- package/dist/plugins/integration.d.ts.map +1 -0
- package/dist/plugins/integration.js +233 -0
- package/dist/plugins/integration.js.map +1 -0
- package/dist/plugins/loader.d.ts +69 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +243 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manifest.d.ts +23 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +143 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/marketplace.d.ts +100 -0
- package/dist/plugins/marketplace.d.ts.map +1 -0
- package/dist/plugins/marketplace.js +529 -0
- package/dist/plugins/marketplace.js.map +1 -0
- package/dist/plugins/paths.d.ts +44 -0
- package/dist/plugins/paths.d.ts.map +1 -0
- package/dist/plugins/paths.js +89 -0
- package/dist/plugins/paths.js.map +1 -0
- package/dist/plugins/refresh.d.ts +61 -0
- package/dist/plugins/refresh.d.ts.map +1 -0
- package/dist/plugins/refresh.js +98 -0
- package/dist/plugins/refresh.js.map +1 -0
- package/dist/plugins/registry.d.ts +40 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +80 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/types.d.ts +225 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +16 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/user-config.d.ts +22 -0
- package/dist/plugins/user-config.d.ts.map +1 -0
- package/dist/plugins/user-config.js +96 -0
- package/dist/plugins/user-config.js.map +1 -0
- package/dist/providers/cache-control.d.ts +9 -0
- package/dist/providers/cache-control.d.ts.map +1 -1
- package/dist/providers/cache-control.js +31 -4
- package/dist/providers/cache-control.js.map +1 -1
- package/dist/skills/loader.d.ts +19 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +197 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +74 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +136 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/settings.d.ts +13 -0
- package/dist/skills/settings.d.ts.map +1 -0
- package/dist/skills/settings.js +100 -0
- package/dist/skills/settings.js.map +1 -0
- package/dist/tools/activate-skill.d.ts +5 -0
- package/dist/tools/activate-skill.d.ts.map +1 -0
- package/dist/tools/activate-skill.js +33 -0
- package/dist/tools/activate-skill.js.map +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/todo-write.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +2 -1
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/types/index.d.ts +46 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils.d.ts +23 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +76 -20
- package/dist/utils.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- 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"}
|