fraim-framework 2.0.81 → 2.0.83

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 (33) hide show
  1. package/dist/src/cli/api/get-provider-client.js +41 -0
  2. package/dist/src/cli/api/provider-client.js +107 -0
  3. package/dist/src/cli/commands/add-ide.js +144 -77
  4. package/dist/src/cli/commands/add-provider.js +223 -0
  5. package/dist/src/cli/commands/doctor.js +131 -111
  6. package/dist/src/cli/commands/init-project.js +67 -31
  7. package/dist/src/cli/commands/setup.js +247 -563
  8. package/dist/src/cli/commands/sync.js +2 -2
  9. package/dist/src/cli/commands/test-mcp.js +35 -1
  10. package/dist/src/cli/doctor/check-runner.js +199 -0
  11. package/dist/src/cli/doctor/checks/global-setup-checks.js +220 -0
  12. package/dist/src/cli/doctor/checks/ide-config-checks.js +250 -0
  13. package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +381 -0
  14. package/dist/src/cli/doctor/checks/project-setup-checks.js +282 -0
  15. package/dist/src/cli/doctor/checks/scripts-checks.js +157 -0
  16. package/dist/src/cli/doctor/checks/workflow-checks.js +247 -0
  17. package/dist/src/cli/doctor/reporters/console-reporter.js +96 -0
  18. package/dist/src/cli/doctor/reporters/json-reporter.js +11 -0
  19. package/dist/src/cli/doctor/types.js +6 -0
  20. package/dist/src/cli/fraim.js +44 -3
  21. package/dist/src/cli/mcp/ide-formats.js +243 -0
  22. package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
  23. package/dist/src/cli/mcp/mcp-server-registry.js +159 -0
  24. package/dist/src/cli/mcp/types.js +3 -0
  25. package/dist/src/cli/providers/local-provider-registry.js +145 -0
  26. package/dist/src/cli/providers/provider-registry.js +230 -0
  27. package/dist/src/cli/setup/auto-mcp-setup.js +56 -118
  28. package/dist/src/cli/setup/mcp-config-generator.js +64 -321
  29. package/dist/src/cli/setup/provider-prompts.js +300 -0
  30. package/dist/src/cli/utils/remote-sync.js +22 -2
  31. package/package.json +4 -2
  32. package/dist/src/cli/commands/install.js +0 -86
  33. package/dist/src/cli/setup/token-validator.js +0 -57
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateMCPConfig = exports.generateWindsurfMCPServers = exports.generateVSCodeMCPServers = exports.generateCodexMCPServers = exports.generateKiroMCPServers = exports.generateClaudeCodeMCPServers = exports.generateClaudeMCPServers = exports.generateStandardMCPServers = exports.mergeTomlMCPServers = exports.extractTomlMcpServerBlock = void 0;
4
- const GITHUB_MCP_URL = 'https://api.githubcopilot.com/mcp/';
5
- const GITLAB_MCP_URL = 'https://gitlab.com/api/v4/mcp';
4
+ const mcp_server_builder_1 = require("../mcp/mcp-server-builder");
5
+ const ide_formats_1 = require("../mcp/ide-formats");
6
6
  const normalizeTokens = (tokenInput) => {
7
7
  if (!tokenInput)
8
8
  return {};
@@ -11,7 +11,6 @@ const normalizeTokens = (tokenInput) => {
11
11
  }
12
12
  return tokenInput;
13
13
  };
14
- const escapeTomlString = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
15
14
  const findTomlServerBlockRange = (content, server) => {
16
15
  const lines = content.split(/\r?\n/);
17
16
  const serverSection = `mcp_servers.${server}`;
@@ -92,356 +91,100 @@ const mergeTomlMCPServers = (existingContent, generatedContent, servers) => {
92
91
  };
93
92
  };
94
93
  exports.mergeTomlMCPServers = mergeTomlMCPServers;
95
- const generateStandardMCPServers = (fraimKey, tokenInput, jiraConfig) => {
96
- const tokens = normalizeTokens(tokenInput);
97
- const servers = {
98
- git: {
99
- command: "npx",
100
- args: ["-y", "@cyanheads/git-mcp-server"]
101
- },
102
- playwright: {
103
- command: "npx",
104
- args: ["-y", "@playwright/mcp"]
105
- },
106
- fraim: {
107
- command: "fraim-mcp",
108
- env: {
109
- FRAIM_API_KEY: fraimKey,
110
- FRAIM_REMOTE_URL: "https://fraim.wellnessatwork.me"
111
- }
94
+ // Helper function to add all provider servers with their configs
95
+ const addProviderServers = async (builder, tokens, providerConfigs) => {
96
+ for (const [providerId, token] of Object.entries(tokens)) {
97
+ if (token) {
98
+ // Get provider-specific config if it exists
99
+ const config = providerConfigs?.[providerId];
100
+ await builder.addProvider(providerId, token, config);
112
101
  }
113
- };
114
- if (tokens.github) {
115
- servers.github = {
116
- serverUrl: GITHUB_MCP_URL,
117
- headers: {
118
- Authorization: `Bearer ${tokens.github}`
119
- }
120
- };
121
- }
122
- if (tokens.gitlab) {
123
- servers.gitlab = {
124
- serverUrl: GITLAB_MCP_URL,
125
- headers: {
126
- Authorization: `Bearer ${tokens.gitlab}`
127
- }
128
- };
129
- }
130
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
131
- servers.jira = {
132
- command: "uvx",
133
- args: ["mcp-atlassian"],
134
- env: {
135
- JIRA_URL: jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`,
136
- JIRA_USERNAME: jiraConfig.email,
137
- JIRA_API_TOKEN: tokens.jira
138
- }
139
- };
140
102
  }
141
- return { mcpServers: servers };
103
+ };
104
+ const generateStandardMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
105
+ const tokens = normalizeTokens(tokenInput);
106
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
107
+ builder.addBaseServers(fraimKey);
108
+ // Dynamically add provider servers based on available tokens
109
+ await addProviderServers(builder, tokens, providerConfigs);
110
+ const format = (0, ide_formats_1.getIDEFormat)('standard');
111
+ return format.transform(builder.getServers());
142
112
  };
143
113
  exports.generateStandardMCPServers = generateStandardMCPServers;
144
- const generateClaudeMCPServers = (fraimKey, tokenInput, jiraConfig) => {
145
- const servers = {
146
- git: {
147
- command: "npx",
148
- args: ["-y", "@cyanheads/git-mcp-server"]
149
- },
150
- playwright: {
151
- command: "npx",
152
- args: ["-y", "@playwright/mcp"]
153
- },
154
- fraim: {
155
- command: "fraim-mcp",
156
- env: {
157
- FRAIM_API_KEY: fraimKey,
158
- FRAIM_REMOTE_URL: "https://fraim.wellnessatwork.me"
159
- }
160
- }
161
- };
114
+ const generateClaudeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
115
+ const tokens = normalizeTokens(tokenInput);
116
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
117
+ builder.addBaseServers(fraimKey);
162
118
  // Claude Desktop does not support HTTPS MCP servers (GitHub, GitLab, Jira)
163
119
  // These cause Claude Desktop to break on boot
164
120
  // See: https://github.com/mathursrus/FRAIM/issues/132
165
- return { mcpServers: servers };
121
+ // The ClaudeFormat adapter will filter out HTTP servers
122
+ await addProviderServers(builder, tokens, providerConfigs);
123
+ const format = (0, ide_formats_1.getIDEFormat)('claude');
124
+ return format.transform(builder.getServers());
166
125
  };
167
126
  exports.generateClaudeMCPServers = generateClaudeMCPServers;
168
- const generateClaudeCodeMCPServers = (fraimKey, tokenInput, jiraConfig) => {
127
+ const generateClaudeCodeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
169
128
  const tokens = normalizeTokens(tokenInput);
170
- const servers = {
171
- git: {
172
- command: "npx",
173
- args: ["-y", "@cyanheads/git-mcp-server"]
174
- },
175
- playwright: {
176
- command: "npx",
177
- args: ["-y", "@playwright/mcp"]
178
- },
179
- fraim: {
180
- command: "fraim-mcp",
181
- env: {
182
- FRAIM_API_KEY: fraimKey,
183
- FRAIM_REMOTE_URL: "https://fraim.wellnessatwork.me"
184
- }
185
- }
186
- };
187
- // Claude Code supports HTTPS MCP servers (uses same format as VSCode)
188
- if (tokens.github) {
189
- servers.github = {
190
- type: "http",
191
- url: GITHUB_MCP_URL,
192
- headers: {
193
- Authorization: `Bearer ${tokens.github}`
194
- }
195
- };
196
- }
197
- if (tokens.gitlab) {
198
- servers.gitlab = {
199
- type: "http",
200
- url: GITLAB_MCP_URL,
201
- headers: {
202
- Authorization: `Bearer ${tokens.gitlab}`
203
- }
204
- };
205
- }
206
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
207
- servers.jira = {
208
- command: "uvx",
209
- args: ["mcp-atlassian"],
210
- env: {
211
- JIRA_URL: jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`,
212
- JIRA_USERNAME: jiraConfig.email,
213
- JIRA_API_TOKEN: tokens.jira
214
- }
215
- };
216
- }
217
- return { mcpServers: servers };
129
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
130
+ builder.addBaseServers(fraimKey);
131
+ await addProviderServers(builder, tokens, providerConfigs);
132
+ const format = (0, ide_formats_1.getIDEFormat)('claude-code');
133
+ return format.transform(builder.getServers());
218
134
  };
219
135
  exports.generateClaudeCodeMCPServers = generateClaudeCodeMCPServers;
220
- const generateKiroMCPServers = (fraimKey, tokenInput, jiraConfig) => {
136
+ const generateKiroMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
221
137
  const tokens = normalizeTokens(tokenInput);
222
- const servers = {
223
- git: {
224
- command: "npx",
225
- args: ["-y", "@cyanheads/git-mcp-server"]
226
- },
227
- playwright: {
228
- command: "npx",
229
- args: ["-y", "@playwright/mcp"]
230
- },
231
- fraim: {
232
- command: "fraim-mcp",
233
- env: {
234
- FRAIM_API_KEY: fraimKey,
235
- FRAIM_REMOTE_URL: "https://fraim.wellnessatwork.me"
236
- }
237
- }
238
- };
239
- if (tokens.github) {
240
- servers.github = {
241
- url: GITHUB_MCP_URL,
242
- headers: {
243
- Authorization: `Bearer ${tokens.github}`
244
- }
245
- };
246
- }
247
- if (tokens.gitlab) {
248
- servers.gitlab = {
249
- url: GITLAB_MCP_URL,
250
- headers: {
251
- Authorization: `Bearer ${tokens.gitlab}`
252
- }
253
- };
254
- }
255
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
256
- servers.jira = {
257
- command: "uvx",
258
- args: ["mcp-atlassian"],
259
- env: {
260
- JIRA_URL: jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`,
261
- JIRA_USERNAME: jiraConfig.email,
262
- JIRA_API_TOKEN: tokens.jira
263
- }
264
- };
265
- }
266
- return { mcpServers: servers };
138
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
139
+ builder.addBaseServers(fraimKey);
140
+ await addProviderServers(builder, tokens, providerConfigs);
141
+ const format = (0, ide_formats_1.getIDEFormat)('kiro');
142
+ return format.transform(builder.getServers());
267
143
  };
268
144
  exports.generateKiroMCPServers = generateKiroMCPServers;
269
- const generateCodexMCPServers = (fraimKey, tokenInput, jiraConfig) => {
145
+ const generateCodexMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
270
146
  const tokens = normalizeTokens(tokenInput);
271
- const escapedFraimKey = escapeTomlString(fraimKey);
272
- let config = `
273
- [mcp_servers.git]
274
- command = "npx"
275
- args = ["-y", "@cyanheads/git-mcp-server"]
276
- `;
277
- if (tokens.github) {
278
- const escapedGithubToken = escapeTomlString(tokens.github);
279
- config += `
280
- [mcp_servers.github]
281
- url = "${GITHUB_MCP_URL}"
282
- http_headers = { Authorization = "Bearer ${escapedGithubToken}" }
283
- `;
284
- }
285
- if (tokens.gitlab) {
286
- const escapedGitLabToken = escapeTomlString(tokens.gitlab);
287
- config += `
288
- [mcp_servers.gitlab]
289
- url = "${GITLAB_MCP_URL}"
290
- http_headers = { Authorization = "Bearer ${escapedGitLabToken}" }
291
- `;
292
- }
293
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
294
- const escapedJiraToken = escapeTomlString(tokens.jira);
295
- const escapedJiraUrl = escapeTomlString(jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`);
296
- const escapedJiraEmail = escapeTomlString(jiraConfig.email);
297
- config += `
298
- [mcp_servers.jira]
299
- command = "uvx"
300
- args = ["mcp-atlassian"]
301
-
302
- [mcp_servers.jira.env]
303
- JIRA_URL = "${escapedJiraUrl}"
304
- JIRA_USERNAME = "${escapedJiraEmail}"
305
- JIRA_API_TOKEN = "${escapedJiraToken}"
306
- `;
307
- }
308
- config += `
309
- [mcp_servers.playwright]
310
- command = "npx"
311
- args = ["-y", "@playwright/mcp"]
312
-
313
- [mcp_servers.fraim]
314
- command = "fraim-mcp"
315
-
316
- [mcp_servers.fraim.env]
317
- FRAIM_API_KEY = "${escapedFraimKey}"
318
- FRAIM_REMOTE_URL = "https://fraim.wellnessatwork.me"
319
- `;
320
- return config;
147
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
148
+ builder.addBaseServers(fraimKey);
149
+ await addProviderServers(builder, tokens, providerConfigs);
150
+ const format = (0, ide_formats_1.getIDEFormat)('codex');
151
+ return format.transform(builder.getServers());
321
152
  };
322
153
  exports.generateCodexMCPServers = generateCodexMCPServers;
323
- const generateVSCodeMCPServers = (fraimKey, tokenInput, jiraConfig) => {
154
+ const generateVSCodeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
324
155
  const tokens = normalizeTokens(tokenInput);
325
- const servers = {
326
- git: {
327
- type: 'stdio',
328
- command: 'npx',
329
- args: ['-y', '@cyanheads/git-mcp-server']
330
- },
331
- playwright: {
332
- type: 'stdio',
333
- command: 'npx',
334
- args: ['-y', '@playwright/mcp']
335
- },
336
- fraim: {
337
- type: 'stdio',
338
- command: 'fraim-mcp',
339
- env: {
340
- FRAIM_API_KEY: fraimKey,
341
- FRAIM_REMOTE_URL: 'https://fraim.wellnessatwork.me'
342
- }
343
- }
344
- };
345
- if (tokens.github) {
346
- servers.github = {
347
- type: 'http',
348
- url: GITHUB_MCP_URL,
349
- headers: {
350
- Authorization: `Bearer ${tokens.github}`
351
- }
352
- };
353
- }
354
- if (tokens.gitlab) {
355
- servers.gitlab = {
356
- type: 'http',
357
- url: GITLAB_MCP_URL,
358
- headers: {
359
- Authorization: `Bearer ${tokens.gitlab}`
360
- }
361
- };
362
- }
363
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
364
- servers.jira = {
365
- type: 'stdio',
366
- command: 'uvx',
367
- args: ['mcp-atlassian'],
368
- env: {
369
- JIRA_URL: jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`,
370
- JIRA_USERNAME: jiraConfig.email,
371
- JIRA_API_TOKEN: tokens.jira
372
- }
373
- };
374
- }
375
- return { servers };
156
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
157
+ builder.addBaseServers(fraimKey);
158
+ await addProviderServers(builder, tokens, providerConfigs);
159
+ const format = (0, ide_formats_1.getIDEFormat)('vscode');
160
+ return format.transform(builder.getServers());
376
161
  };
377
162
  exports.generateVSCodeMCPServers = generateVSCodeMCPServers;
378
- const generateWindsurfMCPServers = (fraimKey, tokenInput, jiraConfig) => {
163
+ const generateWindsurfMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
379
164
  const tokens = normalizeTokens(tokenInput);
380
- const servers = {
381
- git: {
382
- command: "npx",
383
- args: ["-y", "@cyanheads/git-mcp-server"]
384
- },
385
- playwright: {
386
- command: "npx",
387
- args: ["-y", "@playwright/mcp"]
388
- },
389
- fraim: {
390
- command: "fraim-mcp",
391
- env: {
392
- FRAIM_API_KEY: fraimKey,
393
- FRAIM_REMOTE_URL: "https://fraim.wellnessatwork.me"
394
- }
395
- }
396
- };
397
- if (tokens.github) {
398
- servers.github = {
399
- command: "npx",
400
- args: ["-y", "@modelcontextprotocol/server-fetch", GITHUB_MCP_URL],
401
- env: {
402
- GITHUB_TOKEN: tokens.github
403
- }
404
- };
405
- }
406
- if (tokens.gitlab) {
407
- servers.gitlab = {
408
- command: 'npx',
409
- args: ['-y', '@modelcontextprotocol/server-fetch', GITLAB_MCP_URL],
410
- env: {
411
- GITLAB_TOKEN: tokens.gitlab
412
- }
413
- };
414
- }
415
- if (tokens.jira && jiraConfig?.baseUrl && jiraConfig?.email) {
416
- servers.jira = {
417
- command: 'uvx',
418
- args: ['mcp-atlassian'],
419
- env: {
420
- JIRA_URL: jiraConfig.baseUrl.startsWith('http') ? jiraConfig.baseUrl : `https://${jiraConfig.baseUrl}`,
421
- JIRA_USERNAME: jiraConfig.email,
422
- JIRA_API_TOKEN: tokens.jira
423
- }
424
- };
425
- }
426
- return { mcpServers: servers };
165
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
166
+ builder.addBaseServers(fraimKey);
167
+ await addProviderServers(builder, tokens, providerConfigs);
168
+ const format = (0, ide_formats_1.getIDEFormat)('windsurf');
169
+ return format.transform(builder.getServers());
427
170
  };
428
171
  exports.generateWindsurfMCPServers = generateWindsurfMCPServers;
429
- const generateMCPConfig = (configType, fraimKey, tokenInput, jiraConfig) => {
172
+ const generateMCPConfig = async (configType, fraimKey, tokenInput, providerConfigs) => {
430
173
  switch (configType) {
431
174
  case 'standard':
432
- return (0, exports.generateStandardMCPServers)(fraimKey, tokenInput, jiraConfig);
175
+ return await (0, exports.generateStandardMCPServers)(fraimKey, tokenInput, providerConfigs);
433
176
  case 'claude':
434
- return (0, exports.generateClaudeMCPServers)(fraimKey, tokenInput, jiraConfig);
177
+ return await (0, exports.generateClaudeMCPServers)(fraimKey, tokenInput, providerConfigs);
435
178
  case 'claude-code':
436
- return (0, exports.generateClaudeCodeMCPServers)(fraimKey, tokenInput, jiraConfig);
179
+ return await (0, exports.generateClaudeCodeMCPServers)(fraimKey, tokenInput, providerConfigs);
437
180
  case 'kiro':
438
- return (0, exports.generateKiroMCPServers)(fraimKey, tokenInput, jiraConfig);
181
+ return await (0, exports.generateKiroMCPServers)(fraimKey, tokenInput, providerConfigs);
439
182
  case 'vscode':
440
- return (0, exports.generateVSCodeMCPServers)(fraimKey, tokenInput, jiraConfig);
183
+ return await (0, exports.generateVSCodeMCPServers)(fraimKey, tokenInput, providerConfigs);
441
184
  case 'codex':
442
- return (0, exports.generateCodexMCPServers)(fraimKey, tokenInput, jiraConfig);
185
+ return await (0, exports.generateCodexMCPServers)(fraimKey, tokenInput, providerConfigs);
443
186
  case 'windsurf':
444
- return (0, exports.generateWindsurfMCPServers)(fraimKey, tokenInput, jiraConfig);
187
+ return await (0, exports.generateWindsurfMCPServers)(fraimKey, tokenInput, providerConfigs);
445
188
  default:
446
189
  throw new Error(`Unsupported config type: ${configType}`);
447
190
  }