fa-mcp-sdk 0.4.76 → 0.4.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 (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
@@ -1,163 +1,163 @@
1
- # Utilities, Errors, and Logging
2
-
3
- ## Error Classes
4
-
5
- ```typescript
6
- import { BaseMcpError, ToolExecutionError, ValidationError, ServerError } from 'fa-mcp-sdk';
7
-
8
- throw new ValidationError('Input validation failed');
9
- throw new ToolExecutionError('my_tool', 'Execution failed');
10
- throw new ServerError('Database connection failed', { key: 'value' });
11
-
12
- // Custom error
13
- class MyError extends BaseMcpError {
14
- constructor(msg: string) { super(msg, 'MY_ERROR'); }
15
- }
16
- ```
17
-
18
- **ServerError**: `code: 'SERVER_ERROR'`, `httpStatus: 500`
19
-
20
- ## Error Utilities
21
-
22
- ```typescript
23
- import { createJsonRpcErrorResponse, toError, toStr, addErrorMessage } from 'fa-mcp-sdk';
24
-
25
- // Create JSON-RPC error response
26
- const response = createJsonRpcErrorResponse(error, 'request-123');
27
-
28
- // Safe error conversion
29
- const err = toError(anything); // → Error object
30
- const msg = toStr(anything); // → string message
31
-
32
- // Add context to error
33
- addErrorMessage(error, 'Operation failed');
34
- // error.message = 'Operation failed. Original message'
35
- ```
36
-
37
- ## Constants
38
-
39
- ```typescript
40
- import { ROOT_PROJECT_DIR } from 'fa-mcp-sdk';
41
-
42
- const configPath = path.join(ROOT_PROJECT_DIR, 'config', 'default.yaml');
43
- ```
44
-
45
- ## General Utilities
46
-
47
- ```typescript
48
- import { trim, isMainModule, isObject, isNonEmptyObject, ppj, encodeSvgForDataUri, getAsset } from 'fa-mcp-sdk';
49
-
50
- trim(' hello '); // 'hello'
51
- trim(null); // ''
52
- isMainModule(import.meta.url); // true if main entry
53
- isObject({}); // true
54
- isObject([]); // false
55
- isNonEmptyObject({}); // false
56
- isNonEmptyObject({ k: undefined }); // false
57
- ppj({ user: 'john' }); // Pretty JSON string
58
-
59
- const encoded = encodeSvgForDataUri(svgContent);
60
- const logo = getAsset('logo.svg'); // From src/asset/
61
- ```
62
-
63
- ## HTTP Utilities
64
-
65
- ```typescript
66
- import { normalizeHeaders } from 'fa-mcp-sdk';
67
-
68
- // Normalizes to lowercase, joins arrays with ', '
69
- const normalized = normalizeHeaders({
70
- 'Authorization': 'Bearer token',
71
- 'Accept-Language': ['en', 'ru']
72
- });
73
- // { 'authorization': 'Bearer token', 'accept-language': 'en, ru' }
74
- ```
75
-
76
- ## Tool Utilities
77
-
78
- ```typescript
79
- import { getTools, formatToolResult, getJsonFromResult, asTextContent, asJson } from 'fa-mcp-sdk';
80
-
81
- const tools = await getTools(); // Get registered tools
82
-
83
- // Format based on appConfig.mcp.tools.answerAs
84
- const result = formatToolResult({ message: 'Done', data: {} });
85
-
86
- // Returns structuredContent or JSON from text depending on appConfig.mcp.tools.answerAs
87
- const original = getJsonFromResult<T>(result);
88
-
89
- // Direct formatting helpers (ignore tools.answerAs config):
90
- asTextContent('Hello'); // { content: [{ type: 'text', text: 'Hello' }] }
91
- asJson({ status: 'ok' }); // { structuredContent: { status: 'ok' } }
92
- ```
93
-
94
- ### When to Use Which
95
-
96
- - **`formatToolResult()`** — Primary choice in tool handlers. Respects `appConfig.mcp.tools.answerAs` config.
97
- - **`asTextContent()` / `asJson()`** — Direct formatting, ignores `tools.answerAs`. Use when specific format needed.
98
- - **`getJsonFromResult()`** — Inverse of `formatToolResult()`. Extracts JSON from either format. Use in tests.
99
-
100
- ## Network Utilities
101
-
102
- ```typescript
103
- import { isPortAvailable, checkPortAvailability } from 'fa-mcp-sdk';
104
-
105
- const available = await isPortAvailable(3000, 'localhost');
106
-
107
- // Throws/exits if port busy
108
- await checkPortAvailability(3000, 'localhost', true);
109
- ```
110
-
111
- ## Logging
112
-
113
- ```typescript
114
- import { logger, fileLogger, Logger } from 'fa-mcp-sdk';
115
-
116
- logger.info('Server started');
117
- logger.warn('Warning');
118
- logger.error('Error', error);
119
-
120
- fileLogger.info('To file');
121
- await fileLogger.asyncFinish(); // Flush before shutdown
122
-
123
- // Logger type for typing custom logger references
124
- const myLogger: Logger = logger;
125
- ```
126
-
127
- **`Logger`** — The logger type from 'af-logger-ts' is used to type variables and function parameters.
128
-
129
- ## Event System
130
-
131
- ```typescript
132
- import { eventEmitter } from 'fa-mcp-sdk';
133
-
134
- eventEmitter.on('server:started', (data) => console.log(data));
135
- eventEmitter.emit('custom:event', { data: 'example' });
136
- ```
137
-
138
- ## Consul Integration
139
-
140
- ```typescript
141
- import { getConsulAPI, accessPointUpdater, deregisterServiceFromConsul } from 'fa-mcp-sdk';
142
-
143
- const consul = await getConsulAPI();
144
- const services = await consul.catalog.service.list();
145
-
146
- // accessPointUpdater is started/stopped by the SDK automatically — see 03-configuration.md → "Access Points".
147
- // The start()/stop() hooks below are exposed only for tests and diagnostics.
148
- accessPointUpdater.start();
149
- accessPointUpdater.stop();
150
-
151
- await deregisterServiceFromConsul();
152
- ```
153
-
154
- ## Graceful Shutdown
155
-
156
- ```typescript
157
- import { gracefulShutdown } from 'fa-mcp-sdk';
158
-
159
- // Handles: Consul deregistration, DB close, log flush, etc.
160
- process.on('SIGUSR2', () => gracefulShutdown('SIGUSR2', 0));
161
-
162
- // SDK auto-registers SIGINT/SIGTERM handlers
163
- ```
1
+ # Utilities, Errors, and Logging
2
+
3
+ ## Error Classes
4
+
5
+ ```typescript
6
+ import { BaseMcpError, ToolExecutionError, ValidationError, ServerError } from 'fa-mcp-sdk';
7
+
8
+ throw new ValidationError('Input validation failed');
9
+ throw new ToolExecutionError('my_tool', 'Execution failed');
10
+ throw new ServerError('Database connection failed', { key: 'value' });
11
+
12
+ // Custom error
13
+ class MyError extends BaseMcpError {
14
+ constructor(msg: string) { super(msg, 'MY_ERROR'); }
15
+ }
16
+ ```
17
+
18
+ **ServerError**: `code: 'SERVER_ERROR'`, `httpStatus: 500`
19
+
20
+ ## Error Utilities
21
+
22
+ ```typescript
23
+ import { createJsonRpcErrorResponse, toError, toStr, addErrorMessage } from 'fa-mcp-sdk';
24
+
25
+ // Create JSON-RPC error response
26
+ const response = createJsonRpcErrorResponse(error, 'request-123');
27
+
28
+ // Safe error conversion
29
+ const err = toError(anything); // → Error object
30
+ const msg = toStr(anything); // → string message
31
+
32
+ // Add context to error
33
+ addErrorMessage(error, 'Operation failed');
34
+ // error.message = 'Operation failed. Original message'
35
+ ```
36
+
37
+ ## Constants
38
+
39
+ ```typescript
40
+ import { ROOT_PROJECT_DIR } from 'fa-mcp-sdk';
41
+
42
+ const configPath = path.join(ROOT_PROJECT_DIR, 'config', 'default.yaml');
43
+ ```
44
+
45
+ ## General Utilities
46
+
47
+ ```typescript
48
+ import { trim, isMainModule, isObject, isNonEmptyObject, ppj, encodeSvgForDataUri, getAsset } from 'fa-mcp-sdk';
49
+
50
+ trim(' hello '); // 'hello'
51
+ trim(null); // ''
52
+ isMainModule(import.meta.url); // true if main entry
53
+ isObject({}); // true
54
+ isObject([]); // false
55
+ isNonEmptyObject({}); // false
56
+ isNonEmptyObject({ k: undefined }); // false
57
+ ppj({ user: 'john' }); // Pretty JSON string
58
+
59
+ const encoded = encodeSvgForDataUri(svgContent);
60
+ const logo = getAsset('logo.svg'); // From src/asset/
61
+ ```
62
+
63
+ ## HTTP Utilities
64
+
65
+ ```typescript
66
+ import { normalizeHeaders } from 'fa-mcp-sdk';
67
+
68
+ // Normalizes to lowercase, joins arrays with ', '
69
+ const normalized = normalizeHeaders({
70
+ 'Authorization': 'Bearer token',
71
+ 'Accept-Language': ['en', 'ru']
72
+ });
73
+ // { 'authorization': 'Bearer token', 'accept-language': 'en, ru' }
74
+ ```
75
+
76
+ ## Tool Utilities
77
+
78
+ ```typescript
79
+ import { getTools, formatToolResult, getJsonFromResult, asTextContent, asJson } from 'fa-mcp-sdk';
80
+
81
+ const tools = await getTools(); // Get registered tools
82
+
83
+ // Format based on appConfig.mcp.tools.answerAs
84
+ const result = formatToolResult({ message: 'Done', data: {} });
85
+
86
+ // Returns structuredContent or JSON from text depending on appConfig.mcp.tools.answerAs
87
+ const original = getJsonFromResult<T>(result);
88
+
89
+ // Direct formatting helpers (ignore tools.answerAs config):
90
+ asTextContent('Hello'); // { content: [{ type: 'text', text: 'Hello' }] }
91
+ asJson({ status: 'ok' }); // { structuredContent: { status: 'ok' } }
92
+ ```
93
+
94
+ ### When to Use Which
95
+
96
+ - **`formatToolResult()`** — Primary choice in tool handlers. Respects `appConfig.mcp.tools.answerAs` config.
97
+ - **`asTextContent()` / `asJson()`** — Direct formatting, ignores `tools.answerAs`. Use when specific format needed.
98
+ - **`getJsonFromResult()`** — Inverse of `formatToolResult()`. Extracts JSON from either format. Use in tests.
99
+
100
+ ## Network Utilities
101
+
102
+ ```typescript
103
+ import { isPortAvailable, checkPortAvailability } from 'fa-mcp-sdk';
104
+
105
+ const available = await isPortAvailable(3000, 'localhost');
106
+
107
+ // Throws/exits if port busy
108
+ await checkPortAvailability(3000, 'localhost', true);
109
+ ```
110
+
111
+ ## Logging
112
+
113
+ ```typescript
114
+ import { logger, fileLogger, Logger } from 'fa-mcp-sdk';
115
+
116
+ logger.info('Server started');
117
+ logger.warn('Warning');
118
+ logger.error('Error', error);
119
+
120
+ fileLogger.info('To file');
121
+ await fileLogger.asyncFinish(); // Flush before shutdown
122
+
123
+ // Logger type for typing custom logger references
124
+ const myLogger: Logger = logger;
125
+ ```
126
+
127
+ **`Logger`** — The logger type from 'af-logger-ts' is used to type variables and function parameters.
128
+
129
+ ## Event System
130
+
131
+ ```typescript
132
+ import { eventEmitter } from 'fa-mcp-sdk';
133
+
134
+ eventEmitter.on('server:started', (data) => console.log(data));
135
+ eventEmitter.emit('custom:event', { data: 'example' });
136
+ ```
137
+
138
+ ## Consul Integration
139
+
140
+ ```typescript
141
+ import { getConsulAPI, accessPointUpdater, deregisterServiceFromConsul } from 'fa-mcp-sdk';
142
+
143
+ const consul = await getConsulAPI();
144
+ const services = await consul.catalog.service.list();
145
+
146
+ // accessPointUpdater is started/stopped by the SDK automatically — see 03-configuration.md → "Access Points".
147
+ // The start()/stop() hooks below are exposed only for tests and diagnostics.
148
+ accessPointUpdater.start();
149
+ accessPointUpdater.stop();
150
+
151
+ await deregisterServiceFromConsul();
152
+ ```
153
+
154
+ ## Graceful Shutdown
155
+
156
+ ```typescript
157
+ import { gracefulShutdown } from 'fa-mcp-sdk';
158
+
159
+ // Handles: Consul deregistration, DB close, log flush, etc.
160
+ process.on('SIGUSR2', () => gracefulShutdown('SIGUSR2', 0));
161
+
162
+ // SDK auto-registers SIGINT/SIGTERM handlers
163
+ ```
@@ -1,127 +1,127 @@
1
- # Testing and Operations
2
-
3
- ## Test Clients
4
-
5
- ### STDIO Transport
6
-
7
- ```typescript
8
- import { McpStdioClient } from 'fa-mcp-sdk';
9
- import { spawn } from 'child_process';
10
-
11
- const proc = spawn('node', ['dist/start.js', 'stdio'], {
12
- stdio: ['pipe', 'pipe', 'pipe'],
13
- env: { ...process.env, NODE_ENV: 'test' },
14
- });
15
-
16
- const client = new McpStdioClient(proc);
17
- const result = await client.callTool('my_tool', { query: 'test' });
18
- const prompt = await client.getPrompt('agent_brief');
19
- ```
20
-
21
- ### HTTP Transport
22
-
23
- ```typescript
24
- import { McpHttpClient } from 'fa-mcp-sdk';
25
-
26
- const client = new McpHttpClient('http://localhost:3000');
27
- const result = await client.callTool('my_tool', { query: 'test' }, {
28
- 'Authorization': 'Bearer token'
29
- });
30
- ```
31
-
32
- ### SSE Transport
33
-
34
- ```typescript
35
- import { McpSseClient } from 'fa-mcp-sdk';
36
-
37
- const client = new McpSseClient('http://localhost:3000');
38
- const result = await client.callTool('my_tool', { query: 'test' });
39
- ```
40
-
41
- ### Streamable HTTP (MCP 2025)
42
-
43
- ```typescript
44
- import { McpStreamableHttpClient } from 'fa-mcp-sdk';
45
-
46
- const client = new McpStreamableHttpClient('http://localhost:3000', {
47
- headers: { 'Authorization': 'Bearer token' },
48
- requestTimeoutMs: 60000,
49
- });
50
-
51
- await client.initialize({
52
- protocolVersion: '2024-11-05',
53
- clientInfo: { name: 'test-client', version: '1.0.0' },
54
- });
55
-
56
- const result = await client.callTool('my_tool', { query: 'test' });
57
- const prompt = await client.getPrompt('agent_brief');
58
- const resources = await client.listResources();
59
- const content = await client.readResource('custom://data');
60
-
61
- // Notifications
62
- const unsub = client.onNotification('notifications/tools/list_changed', (p) => console.log(p));
63
-
64
- await client.close();
65
- ```
66
-
67
- **Methods:** `initialize`, `close`, `callTool`, `getPrompt`, `listResources`, `readResource`, `listTools`, `listPrompts`, `sendRpc`, `notify`, `onNotification`
68
-
69
- ## Transport Types
70
-
71
- | Transport | Config | Use Case |
72
- |-----------|--------|----------|
73
- | STDIO | `mcp.transportType: "stdio"` | CLI, local dev |
74
- | HTTP | `mcp.transportType: "http"` | Web integrations, REST API |
75
- | SSE | HTTP transport | Long-running ops, streaming |
76
-
77
- ## Running Tests
78
-
79
- ```bash
80
- npm test # All tests (Jest)
81
- npx jest tests/path/file.test.ts # Single file
82
- npx jest --testNamePattern="pattern" # Filter by test name
83
- npm run test:mcp # STDIO transport tests
84
- npm run test:mcp-http # HTTP transport tests
85
- npm run test:mcp-sse # SSE transport tests
86
- ```
87
-
88
- ### Auth Headers for Tests
89
-
90
- ```typescript
91
- import { getAuthHeadersForTests } from 'fa-mcp-sdk';
92
-
93
- const headers = getAuthHeadersForTests(); // Uses config auth settings
94
- const result = await client.callTool('my_tool', { query: 'test' }, headers);
95
- ```
96
-
97
- ### What to Test
98
-
99
- - **Happy path** — tool returns expected result for valid input
100
- - **Error cases** — invalid params, missing required fields, service errors
101
- - **Auth flows** — authenticated vs unauthenticated, different auth methods
102
- - **Transport parity** — same behavior across STDIO, HTTP, SSE
103
- - **Edge cases** — empty strings, large payloads, special characters
104
-
105
- ## Best Practices
106
-
107
- ### Project Organization
108
- - One responsibility per tool
109
- - Use TypeScript throughout
110
- - Separate configs for dev/prod
111
-
112
- ### Tool Development
113
- - Validate all inputs
114
- - Use `formatToolResult()` for responses
115
- - Use error classes for failures
116
- - Log operations with `logger`
117
-
118
- ### Testing
119
- - Test all transport types
120
- - Include error cases
121
- - Use provided test clients
122
-
123
- ### Security
124
- - Environment variables for secrets
125
- - Enable auth for production
126
- - Validate all user inputs
127
- - Don't leak sensitive info in errors
1
+ # Testing and Operations
2
+
3
+ ## Test Clients
4
+
5
+ ### STDIO Transport
6
+
7
+ ```typescript
8
+ import { McpStdioClient } from 'fa-mcp-sdk';
9
+ import { spawn } from 'child_process';
10
+
11
+ const proc = spawn('node', ['dist/start.js', 'stdio'], {
12
+ stdio: ['pipe', 'pipe', 'pipe'],
13
+ env: { ...process.env, NODE_ENV: 'test' },
14
+ });
15
+
16
+ const client = new McpStdioClient(proc);
17
+ const result = await client.callTool('my_tool', { query: 'test' });
18
+ const prompt = await client.getPrompt('agent_brief');
19
+ ```
20
+
21
+ ### HTTP Transport
22
+
23
+ ```typescript
24
+ import { McpHttpClient } from 'fa-mcp-sdk';
25
+
26
+ const client = new McpHttpClient('http://localhost:3000');
27
+ const result = await client.callTool('my_tool', { query: 'test' }, {
28
+ 'Authorization': 'Bearer token'
29
+ });
30
+ ```
31
+
32
+ ### SSE Transport
33
+
34
+ ```typescript
35
+ import { McpSseClient } from 'fa-mcp-sdk';
36
+
37
+ const client = new McpSseClient('http://localhost:3000');
38
+ const result = await client.callTool('my_tool', { query: 'test' });
39
+ ```
40
+
41
+ ### Streamable HTTP (MCP 2025)
42
+
43
+ ```typescript
44
+ import { McpStreamableHttpClient } from 'fa-mcp-sdk';
45
+
46
+ const client = new McpStreamableHttpClient('http://localhost:3000', {
47
+ headers: { 'Authorization': 'Bearer token' },
48
+ requestTimeoutMs: 60000,
49
+ });
50
+
51
+ await client.initialize({
52
+ protocolVersion: '2024-11-05',
53
+ clientInfo: { name: 'test-client', version: '1.0.0' },
54
+ });
55
+
56
+ const result = await client.callTool('my_tool', { query: 'test' });
57
+ const prompt = await client.getPrompt('agent_brief');
58
+ const resources = await client.listResources();
59
+ const content = await client.readResource('custom://data');
60
+
61
+ // Notifications
62
+ const unsub = client.onNotification('notifications/tools/list_changed', (p) => console.log(p));
63
+
64
+ await client.close();
65
+ ```
66
+
67
+ **Methods:** `initialize`, `close`, `callTool`, `getPrompt`, `listResources`, `readResource`, `listTools`, `listPrompts`, `sendRpc`, `notify`, `onNotification`
68
+
69
+ ## Transport Types
70
+
71
+ | Transport | Config | Use Case |
72
+ |-----------|--------|----------|
73
+ | STDIO | `mcp.transportType: "stdio"` | CLI, local dev |
74
+ | HTTP | `mcp.transportType: "http"` | Web integrations, REST API |
75
+ | SSE | HTTP transport | Long-running ops, streaming |
76
+
77
+ ## Running Tests
78
+
79
+ ```bash
80
+ npm test # All tests (Jest)
81
+ npx jest tests/path/file.test.ts # Single file
82
+ npx jest --testNamePattern="pattern" # Filter by test name
83
+ npm run test:mcp # STDIO transport tests
84
+ npm run test:mcp-http # HTTP transport tests
85
+ npm run test:mcp-sse # SSE transport tests
86
+ ```
87
+
88
+ ### Auth Headers for Tests
89
+
90
+ ```typescript
91
+ import { getAuthHeadersForTests } from 'fa-mcp-sdk';
92
+
93
+ const headers = getAuthHeadersForTests(); // Uses config auth settings
94
+ const result = await client.callTool('my_tool', { query: 'test' }, headers);
95
+ ```
96
+
97
+ ### What to Test
98
+
99
+ - **Happy path** — tool returns expected result for valid input
100
+ - **Error cases** — invalid params, missing required fields, service errors
101
+ - **Auth flows** — authenticated vs unauthenticated, different auth methods
102
+ - **Transport parity** — same behavior across STDIO, HTTP, SSE
103
+ - **Edge cases** — empty strings, large payloads, special characters
104
+
105
+ ## Best Practices
106
+
107
+ ### Project Organization
108
+ - One responsibility per tool
109
+ - Use TypeScript throughout
110
+ - Separate configs for dev/prod
111
+
112
+ ### Tool Development
113
+ - Validate all inputs
114
+ - Use `formatToolResult()` for responses
115
+ - Use error classes for failures
116
+ - Log operations with `logger`
117
+
118
+ ### Testing
119
+ - Test all transport types
120
+ - Include error cases
121
+ - Use provided test clients
122
+
123
+ ### Security
124
+ - Environment variables for secrets
125
+ - Enable auth for production
126
+ - Validate all user inputs
127
+ - Don't leak sensitive info in errors
@@ -1,30 +1,27 @@
1
- export default {
2
- preset: 'ts-jest',
3
- testEnvironment: 'node',
4
- testMatch: ['**/tests/**/*.test.ts', '**/tests/**/*.spec.ts'],
5
- collectCoverageFrom: [
6
- 'src/**/*.ts',
7
- '!src/**/*.d.ts',
8
- '!src/index.ts'
9
- ],
10
- coverageDirectory: 'coverage',
11
- coverageReporters: ['text', 'lcov'],
12
- verbose: false,
13
- silent: true,
14
- reporters: ['<rootDir>/tests/jest-simple-reporter.js'],
15
- moduleNameMapper: {
16
- '^(\\.{1,2}/.*)\\.js$': '$1'
17
- },
18
- transform: {
19
- '^.+\\.ts$': ['ts-jest', {
20
- useESM: true
21
- }]
22
- },
23
- transformIgnorePatterns: [
24
- 'node_modules/(?!(chalk|@modelcontextprotocol|af-.*)/)'
25
- ],
26
- extensionsToTreatAsEsm: ['.ts'],
27
- forceExit: true,
28
- detectOpenHandles: true,
29
- testTimeout: 10000
30
- };
1
+ export default {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ testMatch: ['**/tests/**/*.test.ts', '**/tests/**/*.spec.ts'],
5
+ collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts', '!src/index.ts'],
6
+ coverageDirectory: 'coverage',
7
+ coverageReporters: ['text', 'lcov'],
8
+ verbose: false,
9
+ silent: true,
10
+ reporters: ['<rootDir>/tests/jest-simple-reporter.js'],
11
+ moduleNameMapper: {
12
+ '^(\\.{1,2}/.*)\\.js$': '$1',
13
+ },
14
+ transform: {
15
+ '^.+\\.ts$': [
16
+ 'ts-jest',
17
+ {
18
+ useESM: true,
19
+ },
20
+ ],
21
+ },
22
+ transformIgnorePatterns: ['node_modules/(?!(chalk|@modelcontextprotocol|af-.*)/)'],
23
+ extensionsToTreatAsEsm: ['.ts'],
24
+ forceExit: true,
25
+ detectOpenHandles: true,
26
+ testTimeout: 10000,
27
+ };