@agentteams/cli 0.1.75 → 0.1.77

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 (93) hide show
  1. package/.eslintcache +1 -1
  2. package/dist/api/convention.d.ts +11 -0
  3. package/dist/api/convention.d.ts.map +1 -0
  4. package/dist/api/convention.js +26 -0
  5. package/dist/api/convention.js.map +1 -0
  6. package/dist/api/worktree.d.ts +13 -0
  7. package/dist/api/worktree.d.ts.map +1 -0
  8. package/dist/api/worktree.js +8 -0
  9. package/dist/api/worktree.js.map +1 -0
  10. package/dist/commands/convention.d.ts.map +1 -1
  11. package/dist/commands/convention.js +6 -8
  12. package/dist/commands/convention.js.map +1 -1
  13. package/dist/commands/index.d.ts.map +1 -1
  14. package/dist/commands/index.js +4 -19
  15. package/dist/commands/index.js.map +1 -1
  16. package/dist/commands/mcp.d.ts +13 -0
  17. package/dist/commands/mcp.d.ts.map +1 -0
  18. package/dist/commands/mcp.js +13 -0
  19. package/dist/commands/mcp.js.map +1 -0
  20. package/dist/commands/search.d.ts.map +1 -1
  21. package/dist/commands/search.js +8 -35
  22. package/dist/commands/search.js.map +1 -1
  23. package/dist/commands/worktree.d.ts +9 -0
  24. package/dist/commands/worktree.d.ts.map +1 -0
  25. package/dist/commands/worktree.js +119 -0
  26. package/dist/commands/worktree.js.map +1 -0
  27. package/dist/index.js +101 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcp/context.d.ts +15 -0
  30. package/dist/mcp/context.d.ts.map +1 -0
  31. package/dist/mcp/context.js +47 -0
  32. package/dist/mcp/context.js.map +1 -0
  33. package/dist/mcp/resources.d.ts +17 -0
  34. package/dist/mcp/resources.d.ts.map +1 -0
  35. package/dist/mcp/resources.js +50 -0
  36. package/dist/mcp/resources.js.map +1 -0
  37. package/dist/mcp/server.d.ts +20 -0
  38. package/dist/mcp/server.d.ts.map +1 -0
  39. package/dist/mcp/server.js +106 -0
  40. package/dist/mcp/server.js.map +1 -0
  41. package/dist/mcp/tools.d.ts +20 -0
  42. package/dist/mcp/tools.d.ts.map +1 -0
  43. package/dist/mcp/tools.js +172 -0
  44. package/dist/mcp/tools.js.map +1 -0
  45. package/dist/mcp-registration/atomicWrite.d.ts +26 -0
  46. package/dist/mcp-registration/atomicWrite.d.ts.map +1 -0
  47. package/dist/mcp-registration/atomicWrite.js +58 -0
  48. package/dist/mcp-registration/atomicWrite.js.map +1 -0
  49. package/dist/mcp-registration/clients.d.ts +5 -0
  50. package/dist/mcp-registration/clients.d.ts.map +1 -0
  51. package/dist/mcp-registration/clients.js +300 -0
  52. package/dist/mcp-registration/clients.js.map +1 -0
  53. package/dist/mcp-registration/detect.d.ts +23 -0
  54. package/dist/mcp-registration/detect.d.ts.map +1 -0
  55. package/dist/mcp-registration/detect.js +48 -0
  56. package/dist/mcp-registration/detect.js.map +1 -0
  57. package/dist/mcp-registration/index.d.ts +50 -0
  58. package/dist/mcp-registration/index.d.ts.map +1 -0
  59. package/dist/mcp-registration/index.js +205 -0
  60. package/dist/mcp-registration/index.js.map +1 -0
  61. package/dist/mcp-registration/install.d.ts +66 -0
  62. package/dist/mcp-registration/install.d.ts.map +1 -0
  63. package/dist/mcp-registration/install.js +244 -0
  64. package/dist/mcp-registration/install.js.map +1 -0
  65. package/dist/mcp-registration/jsonc.d.ts +44 -0
  66. package/dist/mcp-registration/jsonc.d.ts.map +1 -0
  67. package/dist/mcp-registration/jsonc.js +266 -0
  68. package/dist/mcp-registration/jsonc.js.map +1 -0
  69. package/dist/mcp-registration/render.d.ts +18 -0
  70. package/dist/mcp-registration/render.d.ts.map +1 -0
  71. package/dist/mcp-registration/render.js +91 -0
  72. package/dist/mcp-registration/render.js.map +1 -0
  73. package/dist/mcp-registration/serverSpec.d.ts +31 -0
  74. package/dist/mcp-registration/serverSpec.d.ts.map +1 -0
  75. package/dist/mcp-registration/serverSpec.js +29 -0
  76. package/dist/mcp-registration/serverSpec.js.map +1 -0
  77. package/dist/mcp-registration/types.d.ts +98 -0
  78. package/dist/mcp-registration/types.d.ts.map +1 -0
  79. package/dist/mcp-registration/types.js +12 -0
  80. package/dist/mcp-registration/types.js.map +1 -0
  81. package/dist/mcp-registration/vendorCommand.d.ts +18 -0
  82. package/dist/mcp-registration/vendorCommand.d.ts.map +1 -0
  83. package/dist/mcp-registration/vendorCommand.js +27 -0
  84. package/dist/mcp-registration/vendorCommand.js.map +1 -0
  85. package/dist/utils/apiContext.d.ts +13 -0
  86. package/dist/utils/apiContext.d.ts.map +1 -0
  87. package/dist/utils/apiContext.js +26 -0
  88. package/dist/utils/apiContext.js.map +1 -0
  89. package/dist/utils/searchParams.d.ts +21 -0
  90. package/dist/utils/searchParams.d.ts.map +1 -0
  91. package/dist/utils/searchParams.js +47 -0
  92. package/dist/utils/searchParams.js.map +1 -0
  93. package/package.json +5 -3
@@ -0,0 +1,300 @@
1
+ import { join } from 'node:path';
2
+ /**
3
+ * Registry of the eight AgentTeams runner engines that can host an MCP client.
4
+ *
5
+ * Every entry below was verified on 2026-07-25 against the vendor's public docs
6
+ * *and* against a local install (`<tool> mcp add --help`, plus a two-run
7
+ * idempotency check where the tool ships a registration command). The
8
+ * `verifiedAt` / `docsUrl` fields exist so a future contract drift is traceable
9
+ * to the day the claim was made.
10
+ *
11
+ * Deliberate exclusions: Orca is a worktree runner environment, not an MCP
12
+ * client (register the agents it launches instead), and `GEMINI` is a
13
+ * deprecated runner type.
14
+ *
15
+ * `runnerType` mirrors `packages/core-constants`'s `RUNNER_TYPES`. The public
16
+ * CLI is published from a `cli/`-only subtree split, so that private package
17
+ * cannot be a runtime dependency; a monorepo-only drift test asserts the two
18
+ * key sets stay identical instead.
19
+ */
20
+ function xdgConfigHome(context) {
21
+ const override = context.env.XDG_CONFIG_HOME;
22
+ return override && override.length > 0 ? override : join(context.homeDir, '.config');
23
+ }
24
+ function kimiHome(context) {
25
+ const override = context.env.KIMI_CODE_HOME;
26
+ return override && override.length > 0 ? override : join(context.homeDir, '.kimi-code');
27
+ }
28
+ function codexHome(context) {
29
+ const override = context.env.CODEX_HOME;
30
+ return override && override.length > 0 ? override : join(context.homeDir, '.codex');
31
+ }
32
+ function copilotHome(context) {
33
+ const override = context.env.COPILOT_HOME;
34
+ return override && override.length > 0 ? override : join(context.homeDir, '.copilot');
35
+ }
36
+ function envFlags(spec, flag) {
37
+ return Object.entries(spec.env).flatMap(([key, value]) => [flag, `${key}=${value}`]);
38
+ }
39
+ const ALREADY_REGISTERED = [/already exists/i];
40
+ export const MCP_CLIENTS = [
41
+ {
42
+ id: 'claude-code',
43
+ runnerType: 'CLAUDE_CODE',
44
+ label: 'Claude Code',
45
+ executables: ['claude'],
46
+ secretReference: 'dollarBraces',
47
+ configSignals: (context) => [join(context.homeDir, '.claude.json'), join(context.homeDir, '.claude')],
48
+ docsUrl: 'https://code.claude.com/docs/en/mcp',
49
+ verifiedAt: '2026-07-25',
50
+ scopes: {
51
+ user: {
52
+ configPath: (context) => join(context.homeDir, '.claude.json'),
53
+ format: 'json',
54
+ containerKey: 'mcpServers',
55
+ entryShape: 'stdio',
56
+ strategy: 'jsonMerge',
57
+ },
58
+ project: {
59
+ configPath: (context) => join(context.cwd, '.mcp.json'),
60
+ format: 'json',
61
+ containerKey: 'mcpServers',
62
+ entryShape: 'stdio',
63
+ strategy: 'vendorCommand',
64
+ vendor: {
65
+ buildArgs: (spec, name) => [
66
+ 'mcp',
67
+ 'add',
68
+ name,
69
+ '--scope',
70
+ 'project',
71
+ ...envFlags(spec, '-e'),
72
+ '--',
73
+ spec.command,
74
+ ...spec.args,
75
+ ],
76
+ rerunBehavior: 'refuse',
77
+ alreadyRegisteredPatterns: ALREADY_REGISTERED,
78
+ },
79
+ },
80
+ },
81
+ },
82
+ {
83
+ id: 'codex',
84
+ runnerType: 'CODEX',
85
+ label: 'Codex',
86
+ executables: ['codex'],
87
+ secretReference: 'codexEnvVars',
88
+ configSignals: (context) => [join(codexHome(context), 'config.toml'), codexHome(context)],
89
+ docsUrl: 'https://developers.openai.com/codex/mcp',
90
+ verifiedAt: '2026-07-25',
91
+ scopes: {
92
+ user: {
93
+ configPath: (context) => join(codexHome(context), 'config.toml'),
94
+ format: 'toml',
95
+ strategy: 'configOnly',
96
+ configOnlyReason: 'Codex inherits secrets through `env_vars`, but `codex mcp add --env` accepts values only through argv. The CLI therefore prints a safe TOML snippet instead of exposing the API key in the process list.',
97
+ },
98
+ project: {
99
+ configPath: (context) => join(context.cwd, '.codex', 'config.toml'),
100
+ format: 'toml',
101
+ strategy: 'configOnly',
102
+ configOnlyReason: 'Codex project config is TOML and `codex mcp add` only targets the user config. The CLI has no comment-preserving TOML editor, so rewriting the file would drop your comments and key order.',
103
+ },
104
+ },
105
+ },
106
+ {
107
+ id: 'copilot-cli',
108
+ runnerType: 'COPILOT_CLI',
109
+ label: 'GitHub Copilot CLI',
110
+ executables: ['copilot'],
111
+ secretReference: 'dollarBraces',
112
+ configSignals: (context) => [join(copilotHome(context), 'mcp-config.json'), copilotHome(context)],
113
+ docsUrl: 'https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers',
114
+ verifiedAt: '2026-07-25',
115
+ scopes: {
116
+ user: {
117
+ configPath: (context) => join(copilotHome(context), 'mcp-config.json'),
118
+ format: 'json',
119
+ containerKey: 'mcpServers',
120
+ entryShape: 'stdio',
121
+ strategy: 'jsonMerge',
122
+ },
123
+ project: {
124
+ configPath: (context) => join(context.cwd, '.mcp.json'),
125
+ format: 'json',
126
+ containerKey: 'mcpServers',
127
+ entryShape: 'stdio',
128
+ strategy: 'jsonMerge',
129
+ },
130
+ },
131
+ },
132
+ {
133
+ id: 'opencode',
134
+ runnerType: 'OPENCODE',
135
+ label: 'OpenCode',
136
+ executables: ['opencode'],
137
+ secretReference: 'opencodeEnv',
138
+ configSignals: (context) => [
139
+ join(xdgConfigHome(context), 'opencode', 'opencode.jsonc'),
140
+ join(xdgConfigHome(context), 'opencode', 'opencode.json'),
141
+ join(xdgConfigHome(context), 'opencode'),
142
+ ],
143
+ docsUrl: 'https://opencode.ai/docs/mcp-servers',
144
+ verifiedAt: '2026-07-25',
145
+ scopes: {
146
+ user: {
147
+ configPath: (context) => join(xdgConfigHome(context), 'opencode', 'opencode.jsonc'),
148
+ format: 'jsonc',
149
+ containerKey: 'mcp',
150
+ entryShape: 'opencode',
151
+ strategy: 'jsonMerge',
152
+ },
153
+ project: {
154
+ configPath: (context) => join(context.cwd, 'opencode.json'),
155
+ format: 'json',
156
+ containerKey: 'mcp',
157
+ entryShape: 'opencode',
158
+ strategy: 'jsonMerge',
159
+ },
160
+ },
161
+ },
162
+ {
163
+ id: 'amp',
164
+ runnerType: 'AMP',
165
+ label: 'Amp',
166
+ executables: ['amp'],
167
+ secretReference: 'dollarBraces',
168
+ configSignals: (context) => [
169
+ join(xdgConfigHome(context), 'amp', 'settings.json'),
170
+ join(xdgConfigHome(context), 'amp'),
171
+ ],
172
+ docsUrl: 'https://ampcode.com/manual',
173
+ verifiedAt: '2026-07-25',
174
+ scopes: {
175
+ user: {
176
+ configPath: (context) => join(xdgConfigHome(context), 'amp', 'settings.json'),
177
+ format: 'json',
178
+ containerKey: 'amp.mcpServers',
179
+ entryShape: 'plain',
180
+ strategy: 'jsonMerge',
181
+ },
182
+ project: {
183
+ configPath: (context) => join(context.cwd, '.amp', 'settings.json'),
184
+ format: 'json',
185
+ containerKey: 'amp.mcpServers',
186
+ entryShape: 'plain',
187
+ strategy: 'vendorCommand',
188
+ vendor: {
189
+ buildArgs: (spec, name) => [
190
+ 'mcp',
191
+ 'add',
192
+ name,
193
+ '--workspace',
194
+ ...envFlags(spec, '--env'),
195
+ '--',
196
+ spec.command,
197
+ ...spec.args,
198
+ ],
199
+ rerunBehavior: 'refuse',
200
+ alreadyRegisteredPatterns: ALREADY_REGISTERED,
201
+ },
202
+ },
203
+ },
204
+ },
205
+ {
206
+ id: 'cursor-cli',
207
+ runnerType: 'CURSOR_CLI',
208
+ label: 'Cursor CLI',
209
+ executables: ['cursor-agent'],
210
+ secretReference: 'dollarBraces',
211
+ configSignals: (context) => [join(context.homeDir, '.cursor', 'mcp.json'), join(context.homeDir, '.cursor')],
212
+ docsUrl: 'https://docs.cursor.com/context/model-context-protocol',
213
+ verifiedAt: '2026-07-25',
214
+ scopes: {
215
+ // Verified 2026.07.16: `cursor-agent mcp` exposes only login/list/enable/
216
+ // disable — there is no `add`, so the config file is the only contract.
217
+ user: {
218
+ configPath: (context) => join(context.homeDir, '.cursor', 'mcp.json'),
219
+ format: 'json',
220
+ containerKey: 'mcpServers',
221
+ entryShape: 'plain',
222
+ strategy: 'jsonMerge',
223
+ },
224
+ project: {
225
+ configPath: (context) => join(context.cwd, '.cursor', 'mcp.json'),
226
+ format: 'json',
227
+ containerKey: 'mcpServers',
228
+ entryShape: 'plain',
229
+ strategy: 'jsonMerge',
230
+ },
231
+ },
232
+ },
233
+ {
234
+ id: 'kimi-cli',
235
+ runnerType: 'KIMI_CLI',
236
+ label: 'Kimi CLI',
237
+ executables: ['kimi'],
238
+ secretReference: 'dollarBraces',
239
+ extraBinDirs: (context) => [join(kimiHome(context), 'bin')],
240
+ configSignals: (context) => [join(kimiHome(context), 'mcp.json'), kimiHome(context)],
241
+ docsUrl: 'https://www.kimi.com/code/docs/en/kimi-code-cli/customization/mcp.html',
242
+ verifiedAt: '2026-07-25',
243
+ scopes: {
244
+ // Verified 0.29.0: kimi-code exposes no `mcp` subcommand at all; it loads
245
+ // `<KIMI_CODE_HOME>/mcp.json` and `<cwd>/.kimi-code/mcp.json` directly.
246
+ user: {
247
+ configPath: (context) => join(kimiHome(context), 'mcp.json'),
248
+ format: 'json',
249
+ containerKey: 'mcpServers',
250
+ entryShape: 'plain',
251
+ strategy: 'jsonMerge',
252
+ },
253
+ project: {
254
+ configPath: (context) => join(context.cwd, '.kimi-code', 'mcp.json'),
255
+ format: 'json',
256
+ containerKey: 'mcpServers',
257
+ entryShape: 'plain',
258
+ strategy: 'jsonMerge',
259
+ },
260
+ },
261
+ },
262
+ {
263
+ id: 'antigravity',
264
+ runnerType: 'ANTIGRAVITY',
265
+ label: 'Antigravity',
266
+ executables: ['agy', 'antigravity'],
267
+ secretReference: 'dollarBraces',
268
+ configSignals: (context) => [
269
+ join(context.homeDir, '.gemini', 'config', 'mcp_config.json'),
270
+ join(context.homeDir, '.gemini', 'antigravity'),
271
+ ],
272
+ docsUrl: 'https://antigravity.google/docs/mcp',
273
+ verifiedAt: '2026-07-25',
274
+ scopes: {
275
+ // Verified 1.1.2: the `agy` CLI has no `mcp` subcommand; `mcp_config.json`
276
+ // with an `mcpServers` map is the documented contract.
277
+ user: {
278
+ configPath: (context) => join(context.homeDir, '.gemini', 'config', 'mcp_config.json'),
279
+ format: 'json',
280
+ containerKey: 'mcpServers',
281
+ entryShape: 'plain',
282
+ strategy: 'jsonMerge',
283
+ },
284
+ project: {
285
+ configPath: (context) => join(context.cwd, '.agents', 'mcp_config.json'),
286
+ format: 'json',
287
+ containerKey: 'mcpServers',
288
+ entryShape: 'plain',
289
+ strategy: 'jsonMerge',
290
+ },
291
+ },
292
+ },
293
+ ];
294
+ export function findClient(clientId) {
295
+ return MCP_CLIENTS.find((client) => client.id === clientId);
296
+ }
297
+ export function listClientIds() {
298
+ return MCP_CLIENTS.map((client) => client.id);
299
+ }
300
+ //# sourceMappingURL=clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/mcp-registration/clients.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { DetectionSignal, McpPathContext } from './types.js';
2
+ /**
3
+ * CLI-local client detection.
4
+ *
5
+ * The daemon has its own executable resolver, but the public CLI is published
6
+ * from a `cli/`-only subtree split and cannot import `daemon/src/executable.ts`.
7
+ * The lookup is kept injectable so tests drive it with a fake PATH and a
8
+ * temporary HOME rather than the developer's real machine.
9
+ */
10
+ export interface DetectionDependencies {
11
+ context: McpPathContext;
12
+ fileExists?: (path: string) => boolean;
13
+ /** Windows resolves executables through PATHEXT; the default mirrors that. */
14
+ executableSuffixes?: string[];
15
+ }
16
+ /**
17
+ * Config traces and an executable are independent signals: a client counts as a
18
+ * candidate when either one is present. Reporting *which* signal fired is what
19
+ * lets a user tell "installed but never configured" apart from "config left
20
+ * behind by an uninstall".
21
+ */
22
+ export declare function detectClients(dependencies: DetectionDependencies): DetectionSignal[];
23
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/mcp-registration/detect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAuB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvF;;;;;;;GAOG;AAEH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AA2BD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,qBAAqB,GAAG,eAAe,EAAE,CAsBpF"}
@@ -0,0 +1,48 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { delimiter, join } from 'node:path';
3
+ import { MCP_CLIENTS } from './clients.js';
4
+ function defaultSuffixes(platform) {
5
+ return platform === 'win32' ? ['', '.cmd', '.exe', '.bat', '.ps1'] : [''];
6
+ }
7
+ function resolveExecutable(client, dependencies) {
8
+ const { context, fileExists } = dependencies;
9
+ const suffixes = dependencies.executableSuffixes ?? defaultSuffixes(process.platform);
10
+ const pathDirs = (context.env.PATH ?? '').split(delimiter).filter((entry) => entry.length > 0);
11
+ const extraDirs = client.extraBinDirs ? client.extraBinDirs(context) : [];
12
+ for (const directory of [...pathDirs, ...extraDirs]) {
13
+ for (const executable of client.executables) {
14
+ for (const suffix of suffixes) {
15
+ const candidate = join(directory, `${executable}${suffix}`);
16
+ if (fileExists(candidate))
17
+ return candidate;
18
+ }
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Config traces and an executable are independent signals: a client counts as a
25
+ * candidate when either one is present. Reporting *which* signal fired is what
26
+ * lets a user tell "installed but never configured" apart from "config left
27
+ * behind by an uninstall".
28
+ */
29
+ export function detectClients(dependencies) {
30
+ const fileExists = dependencies.fileExists ?? existsSync;
31
+ const resolved = { ...dependencies, fileExists };
32
+ return MCP_CLIENTS.map((client) => {
33
+ const configPaths = client.configSignals(dependencies.context).filter((path) => fileExists(path));
34
+ const executablePath = resolveExecutable(client, resolved);
35
+ const hasConfig = configPaths.length > 0;
36
+ const hasExecutable = executablePath !== null;
37
+ const evidence = hasConfig && hasExecutable ? 'both' : hasConfig ? 'configured' : hasExecutable ? 'executable' : 'none';
38
+ return {
39
+ clientId: client.id,
40
+ label: client.label,
41
+ evidence,
42
+ executablePath,
43
+ configPaths,
44
+ detected: hasConfig || hasExecutable,
45
+ };
46
+ });
47
+ }
48
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/mcp-registration/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAmB3C,SAAS,eAAe,CAAC,QAAgB;IACvC,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,iBAAiB,CACxB,MAA2B,EAC3B,YAAyF;IAEzF,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC;IAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,kBAAkB,IAAI,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/F,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1E,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;QACpD,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5C,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,UAAU,GAAG,MAAM,EAAE,CAAC,CAAC;gBAC5D,IAAI,UAAU,CAAC,SAAS,CAAC;oBAAE,OAAO,SAAS,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,YAAmC;IAC/D,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,IAAI,UAAU,CAAC;IACzD,MAAM,QAAQ,GAAG,EAAE,GAAG,YAAY,EAAE,UAAU,EAAE,CAAC;IAEjD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAChC,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAClG,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,cAAc,KAAK,IAAI,CAAC;QAC9C,MAAM,QAAQ,GACZ,SAAS,IAAI,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;QAEzG,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ;YACR,cAAc;YACd,WAAW;YACX,QAAQ,EAAE,SAAS,IAAI,aAAa;SACrC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { DetectionDependencies } from './detect.js';
2
+ import { type McpCredentials } from './serverSpec.js';
3
+ import type { McpPathContext } from './types.js';
4
+ import type { VendorRunner } from './vendorCommand.js';
5
+ export { MCP_CLIENTS, findClient, listClientIds } from './clients.js';
6
+ export { detectClients } from './detect.js';
7
+ export { buildBatchPlan, installClient, resolveInstallExitCode, runBatchInstall } from './install.js';
8
+ export { renderConfigSnippet, renderVendorCommandLine, redactSecrets } from './render.js';
9
+ export { buildServerSpec, MCP_SERVER_NAME, CREDENTIAL_ENV_KEYS } from './serverSpec.js';
10
+ export type { McpCredentials } from './serverSpec.js';
11
+ export * from './types.js';
12
+ declare const MCP_CLIENT_ID_LIST: ("claude-code" | "codex" | "copilot-cli" | "opencode" | "amp" | "cursor-cli" | "kimi-cli" | "antigravity")[];
13
+ export { MCP_CLIENT_ID_LIST };
14
+ export interface McpRegistrationCommandOptions {
15
+ client?: string;
16
+ scope?: string;
17
+ serverEntry?: string;
18
+ yes?: boolean;
19
+ apiKey?: string;
20
+ apiUrl?: string;
21
+ projectId?: string;
22
+ teamId?: string;
23
+ }
24
+ /** Injection seams so tests drive a temporary HOME/cwd and a fake vendor CLI. */
25
+ export interface McpRegistrationDependencies {
26
+ context?: Partial<McpPathContext>;
27
+ credentials?: McpCredentials;
28
+ vendorRunner?: VendorRunner;
29
+ detectionDependencies?: Omit<DetectionDependencies, 'context'>;
30
+ }
31
+ export interface CommandOutput {
32
+ text: string;
33
+ json: unknown;
34
+ exitCode: number;
35
+ }
36
+ /**
37
+ * `config` is the escape hatch: it renders the exact fragment each client
38
+ * expects and never touches a file, a vendor CLI or the network. The API key is
39
+ * always emitted with the target client's environment-reference contract so
40
+ * the output stays safe to paste into a terminal, an issue or a code review.
41
+ */
42
+ export declare function runMcpConfigCommand(options: McpRegistrationCommandOptions, dependencies?: McpRegistrationDependencies): CommandOutput;
43
+ /**
44
+ * `install` has two modes:
45
+ * - `--client <id>`: apply a single client/scope (project scope allowed here).
46
+ * - no `--client`: detect local clients and print the plan. Only `--yes` turns
47
+ * that plan into writes, and only at user scope.
48
+ */
49
+ export declare function runMcpInstallCommand(options: McpRegistrationCommandOptions, dependencies?: McpRegistrationDependencies): CommandOutput;
50
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp-registration/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAoC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,KAAK,EAA8B,cAAc,EAAY,MAAM,YAAY,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACxF,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,cAAc,YAAY,CAAC;AAE3B,QAAA,MAAM,kBAAkB,8GAAkB,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,qBAAqB,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwCD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,6BAA6B,EACtC,YAAY,CAAC,EAAE,2BAA2B,GACzC,aAAa,CA2Cf;AAyBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,6BAA6B,EACtC,YAAY,CAAC,EAAE,2BAA2B,GACzC,aAAa,CA0Ff"}
@@ -0,0 +1,205 @@
1
+ import { homedir } from 'node:os';
2
+ import { getConfigurationNotFoundMessage, loadConfig } from '../utils/config.js';
3
+ import { buildConfigOverrides } from '../utils/apiContext.js';
4
+ import { findClient, listClientIds } from './clients.js';
5
+ import { buildBatchPlan, installClient, resolveInstallExitCode, runBatchInstall } from './install.js';
6
+ import { renderConfigSnippet, renderVendorCommandLine } from './render.js';
7
+ import { buildServerSpec, MCP_SERVER_NAME } from './serverSpec.js';
8
+ export { MCP_CLIENTS, findClient, listClientIds } from './clients.js';
9
+ export { detectClients } from './detect.js';
10
+ export { buildBatchPlan, installClient, resolveInstallExitCode, runBatchInstall } from './install.js';
11
+ export { renderConfigSnippet, renderVendorCommandLine, redactSecrets } from './render.js';
12
+ export { buildServerSpec, MCP_SERVER_NAME, CREDENTIAL_ENV_KEYS } from './serverSpec.js';
13
+ export * from './types.js';
14
+ const MCP_CLIENT_ID_LIST = listClientIds();
15
+ export { MCP_CLIENT_ID_LIST };
16
+ function resolveCredentials(options, dependencies) {
17
+ if (dependencies?.credentials)
18
+ return dependencies.credentials;
19
+ const config = loadConfig(buildConfigOverrides(options));
20
+ if (!config)
21
+ throw new Error(getConfigurationNotFoundMessage());
22
+ return {
23
+ apiKey: config.apiKey,
24
+ projectId: config.projectId,
25
+ teamId: config.teamId,
26
+ apiUrl: config.apiUrl,
27
+ };
28
+ }
29
+ function resolvePathContext(overrides) {
30
+ return {
31
+ homeDir: overrides?.homeDir ?? homedir(),
32
+ cwd: overrides?.cwd ?? process.cwd(),
33
+ env: overrides?.env ?? process.env,
34
+ };
35
+ }
36
+ function parseScope(value) {
37
+ if (value === undefined || value === null || value === '')
38
+ return 'user';
39
+ if (value === 'user' || value === 'project')
40
+ return value;
41
+ throw new Error(`Unsupported scope: ${String(value)}. Use "user" or "project".`);
42
+ }
43
+ function parseClientId(value) {
44
+ const client = findClient(value);
45
+ if (!client) {
46
+ throw new Error(`Unknown client: ${value}. Supported clients: ${MCP_CLIENT_ID_LIST.join(', ')}.`);
47
+ }
48
+ return client.id;
49
+ }
50
+ /**
51
+ * `config` is the escape hatch: it renders the exact fragment each client
52
+ * expects and never touches a file, a vendor CLI or the network. The API key is
53
+ * always emitted with the target client's environment-reference contract so
54
+ * the output stays safe to paste into a terminal, an issue or a code review.
55
+ */
56
+ export function runMcpConfigCommand(options, dependencies) {
57
+ const credentials = resolveCredentials(options, dependencies);
58
+ const context = resolvePathContext(dependencies?.context);
59
+ const scope = parseScope(options.scope);
60
+ const clientIds = options.client ? [parseClientId(options.client)] : MCP_CLIENT_ID_LIST;
61
+ const spec = buildServerSpec({ credentials, secretMode: 'reference', serverEntry: options.serverEntry });
62
+ const sections = clientIds.map((clientId) => {
63
+ const client = findClient(clientId);
64
+ if (!client)
65
+ throw new Error(`Unknown client: ${clientId}`);
66
+ const definition = client.scopes[scope];
67
+ return {
68
+ clientId,
69
+ label: client.label,
70
+ scope,
71
+ configPath: definition.configPath(context),
72
+ format: definition.format,
73
+ strategy: definition.strategy,
74
+ docsUrl: client.docsUrl,
75
+ verifiedAt: client.verifiedAt,
76
+ snippet: renderConfigSnippet(client, scope, spec, MCP_SERVER_NAME),
77
+ vendorCommand: renderVendorCommandLine(client, scope, spec, MCP_SERVER_NAME),
78
+ configOnlyReason: definition.configOnlyReason ?? null,
79
+ };
80
+ });
81
+ const lines = [
82
+ `AgentTeams MCP config (${scope} scope) — project ${credentials.projectId}, team ${credentials.teamId}`,
83
+ 'The API key is rendered with the selected client’s environment-reference syntax. Export AGENTTEAMS_API_KEY before the client starts.',
84
+ ];
85
+ for (const section of sections) {
86
+ lines.push('');
87
+ lines.push(`## ${section.label} (${section.clientId})`);
88
+ lines.push(`File: ${section.configPath}`);
89
+ if (section.configOnlyReason)
90
+ lines.push(`Note: ${section.configOnlyReason}`);
91
+ if (section.vendorCommand)
92
+ lines.push(`Command: ${section.vendorCommand}`);
93
+ lines.push(section.snippet);
94
+ lines.push(`Docs: ${section.docsUrl} (verified ${section.verifiedAt})`);
95
+ }
96
+ return { text: lines.join('\n'), json: { scope, clients: sections }, exitCode: 0 };
97
+ }
98
+ function formatDetectionEvidence(entry) {
99
+ if (entry.evidence === 'none')
100
+ return 'not detected';
101
+ const parts = [];
102
+ if (entry.executablePath)
103
+ parts.push(`executable ${entry.executablePath}`);
104
+ if (entry.configPaths.length > 0)
105
+ parts.push(`config ${entry.configPaths[0]}`);
106
+ return `${entry.evidence} (${parts.join(', ')})`;
107
+ }
108
+ function renderResultLine(result) {
109
+ return `- ${result.clientId} [${result.outcome}] ${result.detail}`;
110
+ }
111
+ function summarize(results) {
112
+ return {
113
+ applied: results.filter((r) => r.outcome === 'INSTALLED' || r.outcome === 'ALREADY_REGISTERED').length,
114
+ skipped: results.filter((r) => r.outcome === 'SKIPPED_CONFIG_ONLY' || r.outcome === 'SKIPPED_NOT_DETECTED').length,
115
+ failed: results.filter((r) => r.outcome === 'FAILED').length,
116
+ };
117
+ }
118
+ const USER_SCOPE_BINDING_WARNING = 'Warning: a user-scope registration is machine-wide. If this client already has an "agentteams" server pointing at a different AgentTeams project, applying this plan re-points it.';
119
+ /**
120
+ * `install` has two modes:
121
+ * - `--client <id>`: apply a single client/scope (project scope allowed here).
122
+ * - no `--client`: detect local clients and print the plan. Only `--yes` turns
123
+ * that plan into writes, and only at user scope.
124
+ */
125
+ export function runMcpInstallCommand(options, dependencies) {
126
+ const credentials = resolveCredentials(options, dependencies);
127
+ const context = resolvePathContext(dependencies?.context);
128
+ const scope = parseScope(options.scope);
129
+ if (options.client) {
130
+ const client = findClient(parseClientId(options.client));
131
+ if (!client)
132
+ throw new Error(`Unknown client: ${options.client}`);
133
+ const result = installClient({
134
+ client,
135
+ scope,
136
+ credentials,
137
+ context,
138
+ serverEntry: options.serverEntry,
139
+ vendorRunner: dependencies?.vendorRunner,
140
+ });
141
+ const lines = [
142
+ `AgentTeams MCP install — ${client.label} (${scope} scope)`,
143
+ `Project ${credentials.projectId}, team ${credentials.teamId}`,
144
+ ];
145
+ if (scope === 'user')
146
+ lines.push(USER_SCOPE_BINDING_WARNING);
147
+ lines.push(renderResultLine(result));
148
+ if (result.backupPath)
149
+ lines.push(`Backup: ${result.backupPath}`);
150
+ if (result.manualSnippet) {
151
+ lines.push('Manual fallback:');
152
+ lines.push(result.manualSnippet);
153
+ }
154
+ return {
155
+ text: lines.join('\n'),
156
+ json: { scope, results: [result], summary: summarize([result]) },
157
+ exitCode: resolveInstallExitCode([result]),
158
+ };
159
+ }
160
+ if (scope === 'project') {
161
+ throw new Error('Batch install does not support --scope project: project files are repository state and must be chosen per client. Re-run with --client <id> --scope project.');
162
+ }
163
+ if (!options.yes) {
164
+ const plan = buildBatchPlan({
165
+ context,
166
+ credentials,
167
+ detectionDependencies: dependencies?.detectionDependencies,
168
+ });
169
+ const lines = [
170
+ 'AgentTeams MCP install — dry run (no files were changed)',
171
+ `Plan: register "${MCP_SERVER_NAME}" at user scope for project ${plan.binding.projectId}, team ${plan.binding.teamId}`,
172
+ USER_SCOPE_BINDING_WARNING,
173
+ '',
174
+ ];
175
+ for (const entry of plan.entries) {
176
+ lines.push(`- ${entry.clientId} [${entry.applicable ? 'will apply' : 'skip'}] ${formatDetectionEvidence(entry)}`);
177
+ lines.push(` target: ${entry.targetPath} via ${entry.strategy}`);
178
+ if (entry.reason)
179
+ lines.push(` reason: ${entry.reason}`);
180
+ }
181
+ lines.push('');
182
+ lines.push('Re-run with --yes to apply, or use `agentteams mcp config --client <id>` for a manual snippet.');
183
+ return { text: lines.join('\n'), json: { scope: 'user', dryRun: true, plan }, exitCode: 0 };
184
+ }
185
+ const { plan, results } = runBatchInstall({
186
+ context,
187
+ credentials,
188
+ serverEntry: options.serverEntry,
189
+ vendorRunner: dependencies?.vendorRunner,
190
+ detectionDependencies: dependencies?.detectionDependencies,
191
+ });
192
+ const summary = summarize(results);
193
+ const lines = [
194
+ `AgentTeams MCP install — applied at user scope for project ${plan.binding.projectId}, team ${plan.binding.teamId}`,
195
+ ...results.map(renderResultLine),
196
+ '',
197
+ `Summary: ${summary.applied} registered, ${summary.skipped} skipped, ${summary.failed} failed.`,
198
+ ];
199
+ return {
200
+ text: lines.join('\n'),
201
+ json: { scope: 'user', dryRun: false, plan, results, summary },
202
+ exitCode: resolveInstallExitCode(results),
203
+ };
204
+ }
205
+ //# sourceMappingURL=index.js.map