fa-mcp-sdk 0.4.76 → 0.4.79

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 (198) hide show
  1. package/README.md +319 -314
  2. package/bin/fa-mcp.js +85 -68
  3. package/cli-template/.claude/agents/javascript-pro.md +276 -276
  4. package/cli-template/.claude/settings.json +50 -50
  5. package/cli-template/.claude/skills/upgrade-guide/SKILL.md +2 -1
  6. package/cli-template/.oxfmtrc.json +41 -0
  7. package/cli-template/.oxlintrc.json +120 -0
  8. package/cli-template/CLAUDE.md +358 -355
  9. package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +132 -132
  10. package/cli-template/FA-MCP-SDK-DOC/01-getting-started.md +146 -146
  11. package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +431 -431
  12. package/cli-template/FA-MCP-SDK-DOC/02-2-prompts-and-resources.md +201 -201
  13. package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +384 -384
  14. package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +412 -412
  15. package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +196 -196
  16. package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +163 -163
  17. package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +127 -127
  18. package/cli-template/jest.config.js +27 -30
  19. package/cli-template/package.json +10 -5
  20. package/cli-template/prompt-example-new-MCP.md +101 -101
  21. package/cli-template/readme-docs/SKILLS.md +1 -1
  22. package/cli-template/tsconfig.json +58 -58
  23. package/cli-template/update.cjs +41 -38
  24. package/config/custom-environment-variables.yaml +63 -63
  25. package/config/development.yaml +4 -4
  26. package/config/production.yaml +4 -4
  27. package/config/test.yaml +26 -26
  28. package/dist/core/_types_/TNtlm.d.ts.map +1 -1
  29. package/dist/core/_types_/active-directory-config.d.ts.map +1 -1
  30. package/dist/core/_types_/config.d.ts.map +1 -1
  31. package/dist/core/_types_/types.d.ts.map +1 -1
  32. package/dist/core/ad/group-checker.d.ts.map +1 -1
  33. package/dist/core/ad/group-checker.js.map +1 -1
  34. package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
  35. package/dist/core/agent-tester/agent-tester-router.js +6 -6
  36. package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
  37. package/dist/core/agent-tester/check-llm.d.ts.map +1 -1
  38. package/dist/core/agent-tester/check-llm.js.map +1 -1
  39. package/dist/core/agent-tester/services/SummaryMemory.d.ts.map +1 -1
  40. package/dist/core/agent-tester/services/SummaryMemory.js +3 -9
  41. package/dist/core/agent-tester/services/SummaryMemory.js.map +1 -1
  42. package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
  43. package/dist/core/agent-tester/services/TesterAgentService.js +25 -27
  44. package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
  45. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
  46. package/dist/core/agent-tester/services/TesterMcpClientService.js +26 -25
  47. package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
  48. package/dist/core/auth/admin-auth.d.ts.map +1 -1
  49. package/dist/core/auth/admin-auth.js +5 -5
  50. package/dist/core/auth/admin-auth.js.map +1 -1
  51. package/dist/core/auth/agent-tester-auth.d.ts.map +1 -1
  52. package/dist/core/auth/agent-tester-auth.js +1 -6
  53. package/dist/core/auth/agent-tester-auth.js.map +1 -1
  54. package/dist/core/auth/basic.d.ts.map +1 -1
  55. package/dist/core/auth/basic.js.map +1 -1
  56. package/dist/core/auth/ip-check.d.ts.map +1 -1
  57. package/dist/core/auth/ip-check.js +1 -1
  58. package/dist/core/auth/ip-check.js.map +1 -1
  59. package/dist/core/auth/jwt.d.ts.map +1 -1
  60. package/dist/core/auth/jwt.js +1 -1
  61. package/dist/core/auth/jwt.js.map +1 -1
  62. package/dist/core/auth/middleware.d.ts.map +1 -1
  63. package/dist/core/auth/middleware.js +9 -6
  64. package/dist/core/auth/middleware.js.map +1 -1
  65. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  66. package/dist/core/auth/multi-auth.js +6 -6
  67. package/dist/core/auth/multi-auth.js.map +1 -1
  68. package/dist/core/auth/revocation.d.ts.map +1 -1
  69. package/dist/core/auth/revocation.js +2 -6
  70. package/dist/core/auth/revocation.js.map +1 -1
  71. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.d.ts.map +1 -1
  72. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js +2 -2
  73. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js.map +1 -1
  74. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js +1 -1
  75. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js.map +1 -1
  76. package/dist/core/auth/token-generator/ntlm/ntlm-integration.d.ts.map +1 -1
  77. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js +4 -2
  78. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js.map +1 -1
  79. package/dist/core/auth/token-generator/server.d.ts.map +1 -1
  80. package/dist/core/auth/token-generator/server.js.map +1 -1
  81. package/dist/core/bootstrap/init-config.d.ts.map +1 -1
  82. package/dist/core/bootstrap/init-config.js +2 -2
  83. package/dist/core/bootstrap/init-config.js.map +1 -1
  84. package/dist/core/bootstrap/startup-info.d.ts.map +1 -1
  85. package/dist/core/bootstrap/startup-info.js +3 -7
  86. package/dist/core/bootstrap/startup-info.js.map +1 -1
  87. package/dist/core/cache/cache.d.ts.map +1 -1
  88. package/dist/core/cache/cache.js +2 -2
  89. package/dist/core/cache/cache.js.map +1 -1
  90. package/dist/core/consul/deregister.d.ts.map +1 -1
  91. package/dist/core/consul/deregister.js.map +1 -1
  92. package/dist/core/consul/get-consul-api.d.ts.map +1 -1
  93. package/dist/core/consul/get-consul-api.js +1 -2
  94. package/dist/core/consul/get-consul-api.js.map +1 -1
  95. package/dist/core/db/pg-db.d.ts.map +1 -1
  96. package/dist/core/db/pg-db.js +3 -3
  97. package/dist/core/db/pg-db.js.map +1 -1
  98. package/dist/core/debug.d.ts.map +1 -1
  99. package/dist/core/debug.js.map +1 -1
  100. package/dist/core/errors/BaseMcpError.d.ts.map +1 -1
  101. package/dist/core/errors/BaseMcpError.js.map +1 -1
  102. package/dist/core/errors/ValidationError.d.ts.map +1 -1
  103. package/dist/core/errors/ValidationError.js.map +1 -1
  104. package/dist/core/errors/errors.d.ts.map +1 -1
  105. package/dist/core/errors/errors.js +1 -1
  106. package/dist/core/errors/errors.js.map +1 -1
  107. package/dist/core/index.d.ts +6 -6
  108. package/dist/core/index.d.ts.map +1 -1
  109. package/dist/core/index.js +5 -5
  110. package/dist/core/index.js.map +1 -1
  111. package/dist/core/init-mcp-server.d.ts.map +1 -1
  112. package/dist/core/init-mcp-server.js.map +1 -1
  113. package/dist/core/logger.d.ts.map +1 -1
  114. package/dist/core/logger.js +1 -1
  115. package/dist/core/logger.js.map +1 -1
  116. package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
  117. package/dist/core/mcp/create-mcp-server.js +1 -1
  118. package/dist/core/mcp/create-mcp-server.js.map +1 -1
  119. package/dist/core/mcp/prompts.d.ts.map +1 -1
  120. package/dist/core/mcp/prompts.js.map +1 -1
  121. package/dist/core/mcp/readme-assembler.d.ts.map +1 -1
  122. package/dist/core/mcp/readme-assembler.js +3 -1
  123. package/dist/core/mcp/readme-assembler.js.map +1 -1
  124. package/dist/core/mcp/resources.d.ts.map +1 -1
  125. package/dist/core/mcp/resources.js.map +1 -1
  126. package/dist/core/mcp/server-stdio.d.ts.map +1 -1
  127. package/dist/core/utils/formatToolResult.d.ts.map +1 -1
  128. package/dist/core/utils/formatToolResult.js.map +1 -1
  129. package/dist/core/utils/port-checker.d.ts.map +1 -1
  130. package/dist/core/utils/port-checker.js.map +1 -1
  131. package/dist/core/utils/rate-limit.d.ts.map +1 -1
  132. package/dist/core/utils/rate-limit.js +2 -8
  133. package/dist/core/utils/rate-limit.js.map +1 -1
  134. package/dist/core/utils/testing/BaseMcpClient.d.ts.map +1 -1
  135. package/dist/core/utils/testing/BaseMcpClient.js.map +1 -1
  136. package/dist/core/utils/testing/McpHttpClient.d.ts.map +1 -1
  137. package/dist/core/utils/testing/McpHttpClient.js +2 -2
  138. package/dist/core/utils/testing/McpHttpClient.js.map +1 -1
  139. package/dist/core/utils/testing/McpSseClient.d.ts.map +1 -1
  140. package/dist/core/utils/testing/McpSseClient.js +3 -8
  141. package/dist/core/utils/testing/McpSseClient.js.map +1 -1
  142. package/dist/core/utils/testing/McpStdioClient.d.ts.map +1 -1
  143. package/dist/core/utils/testing/McpStdioClient.js.map +1 -1
  144. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -1
  145. package/dist/core/utils/testing/McpStreamableHttpClient.js +7 -8
  146. package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -1
  147. package/dist/core/utils/utils.d.ts.map +1 -1
  148. package/dist/core/utils/utils.js +3 -5
  149. package/dist/core/utils/utils.js.map +1 -1
  150. package/dist/core/web/admin-router.d.ts.map +1 -1
  151. package/dist/core/web/admin-router.js +3 -3
  152. package/dist/core/web/admin-router.js.map +1 -1
  153. package/dist/core/web/cors.d.ts.map +1 -1
  154. package/dist/core/web/cors.js.map +1 -1
  155. package/dist/core/web/favicon-svg.d.ts.map +1 -1
  156. package/dist/core/web/favicon-svg.js +1 -5
  157. package/dist/core/web/favicon-svg.js.map +1 -1
  158. package/dist/core/web/home-api.d.ts.map +1 -1
  159. package/dist/core/web/home-api.js +7 -8
  160. package/dist/core/web/home-api.js.map +1 -1
  161. package/dist/core/web/openapi.d.ts.map +1 -1
  162. package/dist/core/web/openapi.js +1 -3
  163. package/dist/core/web/openapi.js.map +1 -1
  164. package/dist/core/web/server-http.d.ts.map +1 -1
  165. package/dist/core/web/server-http.js +4 -4
  166. package/dist/core/web/server-http.js.map +1 -1
  167. package/dist/core/web/static/agent-tester/index.html +323 -323
  168. package/dist/core/web/static/agent-tester/script.js +311 -200
  169. package/dist/core/web/static/agent-tester/styles.css +1840 -1840
  170. package/dist/core/web/static/home/index.html +220 -220
  171. package/dist/core/web/static/home/script.js +72 -43
  172. package/dist/core/web/static/styles.css +927 -927
  173. package/dist/core/web/static/token-gen/index.html +136 -136
  174. package/dist/core/web/static/token-gen/script.js +58 -56
  175. package/dist/core/web/svg-icons.d.ts.map +1 -1
  176. package/dist/core/web/svg-icons.js +1 -5
  177. package/dist/core/web/svg-icons.js.map +1 -1
  178. package/package.json +10 -5
  179. package/{cli-template/.claude/hooks/eslint-fix.cjs → scripts/cc-hook-oxlint-oxfmt-fix.cjs} +109 -100
  180. package/scripts/generate-jwt.js +5 -9
  181. package/scripts/kill-port.js +5 -2
  182. package/scripts/npm/run.js +1 -2
  183. package/scripts/remove-nul.js +1 -1
  184. package/scripts/update-sdk.js +36 -14
  185. package/src/template/api/router.ts +3 -3
  186. package/src/template/prompts/agent-brief.ts +0 -1
  187. package/src/template/start.ts +3 -8
  188. package/src/template/tools/handle-tool-call.ts +3 -3
  189. package/src/template/tools/tools.ts +3 -7
  190. package/src/tests/jest-simple-reporter.js +1 -1
  191. package/src/tests/mcp/sse/mcp-sse-client-handling.md +111 -111
  192. package/src/tests/mcp/sse/test-sse-npm-package.js +2 -3
  193. package/src/tests/mcp/test-cases.js +6 -7
  194. package/src/tests/mcp/test-http.js +2 -2
  195. package/src/tests/mcp/test-sse.js +9 -7
  196. package/src/tests/mcp/test-stdio.js +12 -8
  197. package/src/tests/utils.ts +4 -3
  198. package/cli-template/eslint.config.js +0 -27
package/bin/fa-mcp.js CHANGED
@@ -34,8 +34,8 @@ const pjContent = fss.readFileSync(path.join(PROJ_ROOT, 'package.json'));
34
34
  const faMcpSdkVersion = JSON.parse(pjContent).version;
35
35
 
36
36
  // Print version and exit on -V or --version
37
- const argv = process.argv.slice(2);
38
- if (argv.includes('-V') || argv.includes('--version')) {
37
+ const argv = new Set(process.argv.slice(2));
38
+ if (argv.has('-V') || argv.has('--version')) {
39
39
  console.log(faMcpSdkVersion);
40
40
  process.exit(0);
41
41
  }
@@ -63,27 +63,30 @@ const getAsk = () => {
63
63
  output: process.stdout,
64
64
  });
65
65
 
66
- const yn_ = (prompt, defaultAnswer = 'y') => new Promise((resolve) => {
67
- rl.question(prompt, (v) => {
68
- resolve((trim(v) || defaultAnswer).toLowerCase());
66
+ const yn_ = (prompt, defaultAnswer = 'y') =>
67
+ new Promise((resolve) => {
68
+ rl.question(prompt, (v) => {
69
+ resolve((trim(v) || defaultAnswer).toLowerCase());
70
+ });
69
71
  });
70
- });
71
72
 
72
73
  return {
73
74
  close: rl.close.bind(rl),
74
75
 
75
- question: (prompt) => new Promise(resolve => {
76
- rl.question(prompt, resolve);
77
- }),
78
-
79
- optional: (title, paramName, defaultValue, example = undefined) => new Promise(resolve => {
80
- const defaultText = formatDefaultValue(defaultValue);
81
- example = example ? ` (example: ${example})` : '';
82
- const prompt = `${title}${hp(paramName)}${defaultText}${example}${OPTIONAL}: `;
83
- rl.question(prompt, (v) => {
84
- resolve(trim(v) || trim(defaultValue));
85
- });
86
- }),
76
+ question: (prompt) =>
77
+ new Promise((resolve) => {
78
+ rl.question(prompt, resolve);
79
+ }),
80
+
81
+ optional: (title, paramName, defaultValue, example = undefined) =>
82
+ new Promise((resolve) => {
83
+ const defaultText = formatDefaultValue(defaultValue);
84
+ example = example ? ` (example: ${example})` : '';
85
+ const prompt = `${title}${hp(paramName)}${defaultText}${example}${OPTIONAL}: `;
86
+ rl.question(prompt, (v) => {
87
+ resolve(trim(v) || trim(defaultValue));
88
+ });
89
+ }),
87
90
 
88
91
  yn: async (title, paramName, defaultValue = 'false') => {
89
92
  const isTrue = /^(true|y)$/i.test(trim(defaultValue));
@@ -127,7 +130,7 @@ const parseConfigFile = (filePath, content) => {
127
130
  }
128
131
  }
129
132
  } catch (error) {
130
- throw new Error(`Failed to parse configuration file ${filePath}: ${error.message}`);
133
+ throw new Error(`Failed to parse configuration file ${filePath}: ${error.message}`, { cause: error });
131
134
  }
132
135
  };
133
136
 
@@ -153,7 +156,7 @@ const removeIfExists = async (targetPath, relPath, options = {}) => {
153
156
  };
154
157
 
155
158
  class MCPGenerator {
156
- constructor () {
159
+ constructor() {
157
160
  this.lastConfigPath = null;
158
161
  this.requiredParams = [
159
162
  {
@@ -343,11 +346,11 @@ certificate's public and private keys`,
343
346
  ];
344
347
  }
345
348
 
346
- createConfigProxy (config) {
349
+ createConfigProxy(config) {
347
350
  const self = this; // Capture this in closure
348
351
 
349
352
  return new Proxy(config, {
350
- set (target, prop, value, receiver) {
353
+ set(target, prop, value, receiver) {
351
354
  // Check if the value is actually changing
352
355
  const currentValue = target[prop];
353
356
  if (currentValue === value) {
@@ -358,15 +361,14 @@ certificate's public and private keys`,
358
361
  // Save to file asynchronously without blocking — only if project path is known
359
362
  const { lastConfigPath } = self;
360
363
  if (lastConfigPath) {
361
- fs.writeFile(lastConfigPath, JSON.stringify(target, null, 2), 'utf8')
362
- .catch(error => console.warn(`⚠️ Warning: Could not save config to file ${lastConfigPath}:`, error.message));
364
+ fs.writeFile(lastConfigPath, JSON.stringify(target, null, 2), 'utf8').catch((error) => console.warn(`⚠️ Warning: Could not save config to file ${lastConfigPath}:`, error.message));
363
365
  }
364
366
  return result;
365
367
  },
366
368
  });
367
369
  }
368
370
 
369
- async setLastConfigPath (projectAbsPath, config) {
371
+ async setLastConfigPath(projectAbsPath, config) {
370
372
  const tp = path.resolve(projectAbsPath);
371
373
  try {
372
374
  await fs.mkdir(tp, { recursive: true });
@@ -384,7 +386,7 @@ certificate's public and private keys`,
384
386
  }
385
387
  }
386
388
 
387
- async collectConfigData (config, isRetry = false) {
389
+ async collectConfigData(config, isRetry = false) {
388
390
  const ask = getAsk();
389
391
  // Collect required parameters
390
392
  for (const param of this.requiredParams) {
@@ -647,7 +649,7 @@ certificate's public and private keys`,
647
649
  ask.close();
648
650
  }
649
651
 
650
- async confirmConfiguration (config) {
652
+ async confirmConfiguration(config) {
651
653
  console.log('\n📋 Configuration Summary:');
652
654
  console.log('========================');
653
655
 
@@ -680,10 +682,9 @@ certificate's public and private keys`,
680
682
  return confirmed;
681
683
  }
682
684
 
683
- async collectConfiguration () {
685
+ async collectConfiguration() {
684
686
  const config = {};
685
- const configFile = process.argv.find((arg) => arg.endsWith('.json') || arg.endsWith('.yaml') || arg.endsWith('.yml')) ||
686
- process.argv.find((arg) => arg.startsWith('--config='))?.split('=')[1];
687
+ const configFile = process.argv.find((arg) => arg.endsWith('.json') || arg.endsWith('.yaml') || arg.endsWith('.yml')) || process.argv.find((arg) => arg.startsWith('--config='))?.split('=')[1];
687
688
 
688
689
  if (configFile) {
689
690
  try {
@@ -723,7 +724,7 @@ certificate's public and private keys`,
723
724
  confirmed = await this.confirmConfiguration(config);
724
725
 
725
726
  if (!confirmed) {
726
- console.log('\n🔄 Let\'s re-enter the configuration:\n');
727
+ console.log("\n🔄 Let's re-enter the configuration:\n");
727
728
  isRetry = true;
728
729
  }
729
730
  }
@@ -731,7 +732,7 @@ certificate's public and private keys`,
731
732
  return config;
732
733
  }
733
734
 
734
- async getTargetPath (config = {}) {
735
+ async getTargetPath(config = {}) {
735
736
  const ask = getAsk();
736
737
 
737
738
  let tp = process.cwd();
@@ -778,14 +779,14 @@ certificate's public and private keys`,
778
779
  console.error(errMsg);
779
780
  process.exit(1);
780
781
  }
781
- throw new Error(`Cannot access directory: ${error.message}`);
782
+ throw new Error(`Cannot access directory: ${error.message}`, { cause: error });
782
783
  }
783
784
 
784
785
  ask.close();
785
786
  return tp;
786
787
  }
787
788
 
788
- async copyDirectory (source, target) {
789
+ async copyDirectory(source, target) {
789
790
  const entries = await fs.readdir(source, { withFileTypes: true });
790
791
  if (!fss.existsSync(target)) {
791
792
  await fs.mkdir(target, { recursive: true });
@@ -808,11 +809,9 @@ certificate's public and private keys`,
808
809
  }
809
810
  }
810
811
 
811
- async handlePackageJson (content, config) {
812
+ async handlePackageJson(content, config) {
812
813
  try {
813
- content = content
814
- .replace(/"project\.name"/g, '"{{project.name}}"')
815
- .replace(/"node \.\.\/scripts/g, '"node ./scripts');
814
+ content = content.replace(/"project\.name"/g, '"{{project.name}}"').replace(/"node \.\.\/scripts/g, '"node ./scripts');
816
815
  // First replace all template parameters in the content string
817
816
  let updatedContent = content;
818
817
  for (const [param, value] of Object.entries(config)) {
@@ -830,7 +829,9 @@ certificate's public and private keys`,
830
829
  if (!authorName && !authorEmail) {
831
830
  delete packageJson.author;
832
831
  } else {
833
- if (!packageJson.author) {packageJson.author = {};}
832
+ if (!packageJson.author) {
833
+ packageJson.author = {};
834
+ }
834
835
  if (authorName) {
835
836
  packageJson.author.name = authorName;
836
837
  }
@@ -851,11 +852,11 @@ certificate's public and private keys`,
851
852
 
852
853
  return JSON.stringify(packageJson, null, 2);
853
854
  } catch (error) {
854
- throw new Error(`Error processing package.json: ${error.message}`);
855
+ throw new Error(`Error processing package.json: ${error.message}`, { cause: error });
855
856
  }
856
857
  }
857
858
 
858
- async getAllFiles (dir, skipRootDirs) {
859
+ async getAllFiles(dir, skipRootDirs) {
859
860
  const files = [];
860
861
  const entries = await fs.readdir(dir, { withFileTypes: true });
861
862
 
@@ -866,7 +867,7 @@ certificate's public and private keys`,
866
867
  const fullPath = path.join(dir, entry.name);
867
868
 
868
869
  if (entry.isDirectory()) {
869
- files.push(...await this.getAllFiles(fullPath));
870
+ files.push(...(await this.getAllFiles(fullPath)));
870
871
  } else {
871
872
  files.push(fullPath);
872
873
  }
@@ -875,7 +876,7 @@ certificate's public and private keys`,
875
876
  return files;
876
877
  }
877
878
 
878
- async transformTargetFile (config, targetRelPath, transformFn) {
879
+ async transformTargetFile(config, targetRelPath, transformFn) {
879
880
  const targetPath = config.projectAbsPath;
880
881
  const targetFullPath = path.join(targetPath, targetRelPath);
881
882
  const content = await fs.readFile(targetFullPath, 'utf8');
@@ -883,10 +884,10 @@ certificate's public and private keys`,
883
884
  await fs.writeFile(targetFullPath, transformedContent, 'utf8');
884
885
  }
885
886
 
886
- async replaceTemplateParameters (config) {
887
+ async replaceTemplateParameters(config) {
887
888
  const targetPath = config.projectAbsPath;
888
889
  const files = await this.getAllFiles(targetPath, ALLOWED_FILES);
889
- const importRe = /'[^']+\/core\/index.js'/ig;
890
+ const importRe = /'[^']+\/core\/index.js'/gi;
890
891
  for (const filePath of files) {
891
892
  let content = await fs.readFile(filePath, 'utf8');
892
893
  let modified = false;
@@ -905,7 +906,7 @@ certificate's public and private keys`,
905
906
  }
906
907
  }
907
908
  if (importRe.test(content)) {
908
- content = content.replace(importRe, '\'fa-mcp-sdk\'');
909
+ content = content.replace(importRe, "'fa-mcp-sdk'");
909
910
  modified = true;
910
911
  }
911
912
  }
@@ -926,24 +927,46 @@ certificate's public and private keys`,
926
927
  await this.transformTargetFile(config, '.env', (c) => c.replace(/^(NODE_CONSUL_ENV)=([^\r\n]*)/m, '#$1=$2'));
927
928
  }
928
929
  if (config['claude.isBypassPermissions'] === 'true') {
929
- const c1 = ['sudo cp', 'sudo', 'bash', 'chmod', 'curl', 'dir', 'echo', 'git', 'find', 'grep', 'jest',
930
- 'mkdir', 'node', 'npm install', 'npm run', 'npm test', 'npm', 'npx', 'pkill', 'set', 'playwright', 'powershell',
931
- 'rm', 'taskkill', 'tasklist', 'timeout', 'turbo run', 'wc'];
930
+ const c1 = [
931
+ 'sudo cp',
932
+ 'sudo',
933
+ 'bash',
934
+ 'chmod',
935
+ 'curl',
936
+ 'dir',
937
+ 'echo',
938
+ 'git',
939
+ 'find',
940
+ 'grep',
941
+ 'jest',
942
+ 'mkdir',
943
+ 'node',
944
+ 'npm install',
945
+ 'npm run',
946
+ 'npm test',
947
+ 'npm',
948
+ 'npx',
949
+ 'pkill',
950
+ 'set',
951
+ 'playwright',
952
+ 'powershell',
953
+ 'rm',
954
+ 'taskkill',
955
+ 'tasklist',
956
+ 'timeout',
957
+ 'turbo run',
958
+ 'wc',
959
+ ];
932
960
  const c2 = ['jobs', 'npm start', 'unset http_proxy'];
933
961
  const c3 = ['./config/local.yaml', './node_modules/fa-mcp-sdk/config/_local.yaml'];
934
962
  const i = ' '.repeat(8);
935
- const allowBashLines = [
936
- ...c1.map((c) => `${i}"Bash(${c}:*)",`),
937
- ...c2.map((c) => `${i}"Bash(${c})",`),
938
- ...c3.map((c) => `${i}"Read(${c})",`),
939
- ].join('\n');
940
- const transformFn = (c) => c.replace('"acceptEdits"', '"bypassPermissions"')
941
- .replace(/"allow": \[\s+"Edit",/, `"allow": [\n${allowBashLines}\n${i}"Edit",`);
963
+ const allowBashLines = [...c1.map((c) => `${i}"Bash(${c}:*)",`), ...c2.map((c) => `${i}"Bash(${c})",`), ...c3.map((c) => `${i}"Read(${c})",`)].join('\n');
964
+ const transformFn = (c) => c.replace('"acceptEdits"', '"bypassPermissions"').replace(/"allow": \[\s+"Edit",/, `"allow": [\n${allowBashLines}\n${i}"Edit",`);
942
965
  await this.transformTargetFile(config, '.claude/settings.json', transformFn);
943
966
  }
944
967
  }
945
968
 
946
- async createProject (config) {
969
+ async createProject(config) {
947
970
  const targetPath = config.projectAbsPath;
948
971
  // Copy template files
949
972
  await this.copyDirectory(path.join(PROJ_ROOT, 'cli-template'), targetPath);
@@ -996,7 +1019,6 @@ certificate's public and private keys`,
996
1019
  const localYamlExamplePath = path.join(targetPath, 'config', '_local.yaml');
997
1020
  const localYamlPath = path.join(targetPath, 'config', 'local.yaml');
998
1021
  try {
999
-
1000
1022
  localYamlExampleContent = await fs.readFile(localYamlExamplePath, 'utf8');
1001
1023
  } catch (error) {
1002
1024
  console.log('⚠️ Warning: Could not process config/_local.yaml file:', error.message);
@@ -1030,7 +1052,7 @@ certificate's public and private keys`,
1030
1052
  }
1031
1053
  }
1032
1054
  if (!config['consul.agent.reg.host']) {
1033
- localYamlModifiedContent = localYamlModifiedContent.replace(/(\n +)host: '[^']*'( # The host of the consul agent)/, '$1# host: \'\'$2');
1055
+ localYamlModifiedContent = localYamlModifiedContent.replace(/(\n +)host: '[^']*'( # The host of the consul agent)/, "$1# host: ''$2");
1034
1056
  }
1035
1057
 
1036
1058
  await fs.writeFile(localYamlPath, localYamlModifiedContent, 'utf8');
@@ -1039,16 +1061,12 @@ certificate's public and private keys`,
1039
1061
  console.log('⚠️ Warning: Could not create config/_local.yaml file:', error.message);
1040
1062
  }
1041
1063
  }
1042
- const pathsToRemove = [
1043
- { rel: 'package-lock.json' },
1044
- ];
1064
+ const pathsToRemove = [{ rel: 'package-lock.json' }];
1045
1065
 
1046
- await Promise.all(
1047
- pathsToRemove.map(({ rel, options }) => removeIfExists(targetPath, rel, options)),
1048
- );
1066
+ await Promise.all(pathsToRemove.map(({ rel, options }) => removeIfExists(targetPath, rel, options)));
1049
1067
  }
1050
1068
 
1051
- async run () {
1069
+ async run() {
1052
1070
  console.log('MCP Server Template Generator');
1053
1071
  console.log('==================================\n');
1054
1072
 
@@ -1067,7 +1085,6 @@ certificate's public and private keys`,
1067
1085
  console.log(' npm start');
1068
1086
 
1069
1087
  process.exit(0);
1070
-
1071
1088
  } catch (error) {
1072
1089
  if (error.message && !(error.stack || '').includes(String(error.message))) {
1073
1090
  console.error('\n❌ Error:', error.message);
@@ -1078,7 +1095,7 @@ certificate's public and private keys`,
1078
1095
  }
1079
1096
  }
1080
1097
 
1081
- function escapeRegExp (string) {
1098
+ function escapeRegExp(string) {
1082
1099
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1083
1100
  }
1084
1101