fa-mcp-sdk 0.4.3 → 0.4.6

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 (153) hide show
  1. package/bin/fa-mcp.js +1040 -1039
  2. package/cli-template/eslint.config.js +16 -136
  3. package/cli-template/package.json +9 -10
  4. package/cli-template/tsconfig.json +1 -0
  5. package/dist/core/_types_/active-directory-config.d.ts.map +1 -1
  6. package/dist/core/_types_/config.d.ts +1 -1
  7. package/dist/core/_types_/config.d.ts.map +1 -1
  8. package/dist/core/_types_/types.d.ts.map +1 -1
  9. package/dist/core/ad/group-checker.d.ts.map +1 -1
  10. package/dist/core/ad/group-checker.js.map +1 -1
  11. package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
  12. package/dist/core/agent-tester/agent-tester-router.js +8 -8
  13. package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
  14. package/dist/core/agent-tester/check-llm.d.ts.map +1 -1
  15. package/dist/core/agent-tester/check-llm.js +1 -1
  16. package/dist/core/agent-tester/check-llm.js.map +1 -1
  17. package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
  18. package/dist/core/agent-tester/services/TesterAgentService.js +53 -53
  19. package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
  20. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
  21. package/dist/core/agent-tester/services/TesterMcpClientService.js +2 -2
  22. package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
  23. package/dist/core/auth/admin-auth.d.ts.map +1 -1
  24. package/dist/core/auth/admin-auth.js +3 -3
  25. package/dist/core/auth/admin-auth.js.map +1 -1
  26. package/dist/core/auth/basic.d.ts.map +1 -1
  27. package/dist/core/auth/basic.js.map +1 -1
  28. package/dist/core/auth/jwt.d.ts.map +1 -1
  29. package/dist/core/auth/jwt.js +6 -16
  30. package/dist/core/auth/jwt.js.map +1 -1
  31. package/dist/core/auth/middleware.d.ts.map +1 -1
  32. package/dist/core/auth/middleware.js +3 -2
  33. package/dist/core/auth/middleware.js.map +1 -1
  34. package/dist/core/auth/multi-auth.d.ts +0 -3
  35. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  36. package/dist/core/auth/multi-auth.js +10 -7
  37. package/dist/core/auth/multi-auth.js.map +1 -1
  38. package/dist/core/auth/permanent.d.ts.map +1 -1
  39. package/dist/core/auth/permanent.js +1 -1
  40. package/dist/core/auth/permanent.js.map +1 -1
  41. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.d.ts.map +1 -1
  42. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js +2 -2
  43. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js.map +1 -1
  44. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.d.ts.map +1 -1
  45. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js +1 -1
  46. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js.map +1 -1
  47. package/dist/core/auth/token-generator/ntlm/ntlm-integration.d.ts.map +1 -1
  48. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js +1 -1
  49. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js.map +1 -1
  50. package/dist/core/auth/token-generator/ntlm/ntlm-templates.d.ts.map +1 -1
  51. package/dist/core/auth/token-generator/ntlm/ntlm-templates.js +222 -221
  52. package/dist/core/auth/token-generator/ntlm/ntlm-templates.js.map +1 -1
  53. package/dist/core/auth/token-generator/server.d.ts.map +1 -1
  54. package/dist/core/auth/token-generator/server.js +8 -8
  55. package/dist/core/auth/token-generator/server.js.map +1 -1
  56. package/dist/core/bootstrap/init-config.d.ts.map +1 -1
  57. package/dist/core/bootstrap/init-config.js +4 -4
  58. package/dist/core/bootstrap/init-config.js.map +1 -1
  59. package/dist/core/bootstrap/startup-info.d.ts.map +1 -1
  60. package/dist/core/bootstrap/startup-info.js +4 -4
  61. package/dist/core/bootstrap/startup-info.js.map +1 -1
  62. package/dist/core/cache/cache.d.ts.map +1 -1
  63. package/dist/core/cache/cache.js +3 -3
  64. package/dist/core/cache/cache.js.map +1 -1
  65. package/dist/core/consul/access-points-updater.d.ts.map +1 -1
  66. package/dist/core/consul/access-points-updater.js +3 -3
  67. package/dist/core/consul/access-points-updater.js.map +1 -1
  68. package/dist/core/consul/deregister.d.ts.map +1 -1
  69. package/dist/core/consul/deregister.js +1 -1
  70. package/dist/core/consul/deregister.js.map +1 -1
  71. package/dist/core/consul/get-consul-api.d.ts.map +1 -1
  72. package/dist/core/consul/get-consul-api.js +3 -3
  73. package/dist/core/consul/get-consul-api.js.map +1 -1
  74. package/dist/core/db/pg-db.d.ts +1 -1
  75. package/dist/core/db/pg-db.d.ts.map +1 -1
  76. package/dist/core/db/pg-db.js +2 -2
  77. package/dist/core/db/pg-db.js.map +1 -1
  78. package/dist/core/debug.js +1 -1
  79. package/dist/core/debug.js.map +1 -1
  80. package/dist/core/init-mcp-server.d.ts.map +1 -1
  81. package/dist/core/init-mcp-server.js +9 -9
  82. package/dist/core/init-mcp-server.js.map +1 -1
  83. package/dist/core/logger.d.ts.map +1 -1
  84. package/dist/core/logger.js +3 -3
  85. package/dist/core/logger.js.map +1 -1
  86. package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
  87. package/dist/core/mcp/create-mcp-server.js +1 -1
  88. package/dist/core/mcp/create-mcp-server.js.map +1 -1
  89. package/dist/core/mcp/prompts.d.ts.map +1 -1
  90. package/dist/core/mcp/prompts.js +1 -3
  91. package/dist/core/mcp/prompts.js.map +1 -1
  92. package/dist/core/mcp/resources.d.ts.map +1 -1
  93. package/dist/core/mcp/resources.js +8 -10
  94. package/dist/core/mcp/resources.js.map +1 -1
  95. package/dist/core/mcp/server-stdio.d.ts.map +1 -1
  96. package/dist/core/mcp/server-stdio.js.map +1 -1
  97. package/dist/core/utils/formatToolResult.d.ts.map +1 -1
  98. package/dist/core/utils/formatToolResult.js +1 -3
  99. package/dist/core/utils/formatToolResult.js.map +1 -1
  100. package/dist/core/utils/port-checker.d.ts.map +1 -1
  101. package/dist/core/utils/port-checker.js +1 -1
  102. package/dist/core/utils/port-checker.js.map +1 -1
  103. package/dist/core/utils/rate-limit.js +2 -2
  104. package/dist/core/utils/testing/McpSseClient.d.ts.map +1 -1
  105. package/dist/core/utils/testing/McpSseClient.js.map +1 -1
  106. package/dist/core/utils/testing/McpStdioClient.d.ts.map +1 -1
  107. package/dist/core/utils/testing/McpStdioClient.js.map +1 -1
  108. package/dist/core/utils/utils.d.ts.map +1 -1
  109. package/dist/core/utils/utils.js.map +1 -1
  110. package/dist/core/web/admin-router.d.ts.map +1 -1
  111. package/dist/core/web/admin-router.js +4 -4
  112. package/dist/core/web/admin-router.js.map +1 -1
  113. package/dist/core/web/cors.d.ts.map +1 -1
  114. package/dist/core/web/cors.js.map +1 -1
  115. package/dist/core/web/favicon-svg.d.ts.map +1 -1
  116. package/dist/core/web/favicon-svg.js.map +1 -1
  117. package/dist/core/web/home-api.d.ts.map +1 -1
  118. package/dist/core/web/home-api.js +4 -4
  119. package/dist/core/web/home-api.js.map +1 -1
  120. package/dist/core/web/openapi.d.ts.map +1 -1
  121. package/dist/core/web/openapi.js.map +1 -1
  122. package/dist/core/web/server-http.d.ts.map +1 -1
  123. package/dist/core/web/server-http.js +20 -22
  124. package/dist/core/web/server-http.js.map +1 -1
  125. package/dist/core/web/static/agent-tester/script.js +1503 -1513
  126. package/dist/core/web/static/home/script.js +646 -646
  127. package/dist/core/web/static/token-gen/script.js +561 -561
  128. package/dist/core/web/svg-icons.d.ts.map +1 -1
  129. package/dist/core/web/svg-icons.js +1 -1
  130. package/dist/core/web/svg-icons.js.map +1 -1
  131. package/package.json +2 -6
  132. package/scripts/copy-static.js +31 -31
  133. package/scripts/kill-port.js +107 -107
  134. package/scripts/npm/patch_node_modules.js +8 -8
  135. package/scripts/npm/run.js +31 -31
  136. package/scripts/remove-nul.js +53 -53
  137. package/scripts/update-doc.js +18 -18
  138. package/src/template/_types_/custom-config.ts +83 -83
  139. package/src/template/api/router.ts +86 -89
  140. package/src/template/custom-resources.ts +11 -11
  141. package/src/template/prompts/agent-brief.ts +8 -8
  142. package/src/template/prompts/agent-prompt.ts +10 -10
  143. package/src/template/prompts/custom-prompts.ts +12 -12
  144. package/src/template/start.ts +71 -72
  145. package/src/template/tools/handle-tool-call.ts +57 -56
  146. package/src/template/tools/tools.ts +89 -88
  147. package/src/tests/jest-simple-reporter.js +10 -10
  148. package/src/tests/mcp/sse/test-sse-npm-package.js +96 -96
  149. package/src/tests/mcp/test-cases.js +143 -143
  150. package/src/tests/mcp/test-http.js +76 -75
  151. package/src/tests/mcp/test-sse.js +80 -79
  152. package/src/tests/mcp/test-stdio.js +83 -81
  153. package/src/tests/utils.ts +157 -156
@@ -1,56 +1,57 @@
1
- import { logger as lgr, formatToolResult, ToolExecutionError } from '../../core/index.js';
2
- import chalk from 'chalk';
3
-
4
- const logger = lgr.getSubLogger({ name: chalk.bgGrey('tools') });
5
-
6
- /**
7
- * Template tool handler - customize this for your specific tools
8
- * This handles MCP tool execution requests
9
- */
10
- export const handleToolCall = async (params: { name: string, arguments?: any }): Promise<any> => {
11
- const { name, arguments: args } = params;
12
-
13
- logger.info(`Tool called: ${name}`);
14
-
15
- try {
16
- // TODO: Implement your tool routing logic here
17
- switch (name) {
18
- case 'example_tool':
19
- return await handleExampleTool(args);
20
-
21
- default:
22
- throw new ToolExecutionError(name, `Unknown tool: ${name}`);
23
- }
24
- } catch (error: Error | any) {
25
- logger.error(`Tool execution failed for ${name}:`, error);
26
- error.printed = true;
27
- throw error;
28
- }
29
- };
30
-
31
- /**
32
- * Example tool implementation
33
- * Replace this with your actual tool logic
34
- */
35
- async function handleExampleTool (args: any): Promise<string> {
36
- const { query } = args || {};
37
-
38
- if (!query) {
39
- throw new ToolExecutionError('example_tool', 'Query parameter is required');
40
- }
41
-
42
- // Simulate some work
43
- await new Promise(resolve => setTimeout(resolve, 100));
44
-
45
- const result = {
46
- message: `Processed query: ${query}`,
47
- timestamp: new Date().toISOString(),
48
- };
49
-
50
- return formatToolResult(result);
51
- }
52
-
53
- // TODO: Add more tool handlers here
54
- // async function handleAnotherTool(args: any): Promise<string> {
55
- // // Your implementation
56
- // }
1
+ import chalk from 'chalk';
2
+
3
+ import { logger as lgr, formatToolResult, ToolExecutionError } from '../../core/index.js';
4
+
5
+ const logger = lgr.getSubLogger({ name: chalk.bgGrey('tools') });
6
+
7
+ /**
8
+ * Template tool handler - customize this for your specific tools
9
+ * This handles MCP tool execution requests
10
+ */
11
+ export const handleToolCall = async (params: { name: string, arguments?: any }): Promise<any> => {
12
+ const { name, arguments: args } = params;
13
+
14
+ logger.info(`Tool called: ${name}`);
15
+
16
+ try {
17
+ // TODO: Implement your tool routing logic here
18
+ switch (name) {
19
+ case 'example_tool':
20
+ return await handleExampleTool(args);
21
+
22
+ default:
23
+ throw new ToolExecutionError(name, `Unknown tool: ${name}`);
24
+ }
25
+ } catch (error: Error | any) {
26
+ logger.error(`Tool execution failed for ${name}:`, error);
27
+ error.printed = true;
28
+ throw error;
29
+ }
30
+ };
31
+
32
+ /**
33
+ * Example tool implementation
34
+ * Replace this with your actual tool logic
35
+ */
36
+ async function handleExampleTool (args: any): Promise<string> {
37
+ const { query } = args || {};
38
+
39
+ if (!query) {
40
+ throw new ToolExecutionError('example_tool', 'Query parameter is required');
41
+ }
42
+
43
+ // Simulate some work
44
+ await new Promise(resolve => setTimeout(resolve, 100));
45
+
46
+ const result = {
47
+ message: `Processed query: ${query}`,
48
+ timestamp: new Date().toISOString(),
49
+ };
50
+
51
+ return formatToolResult(result);
52
+ }
53
+
54
+ // TODO: Add more tool handlers here
55
+ // async function handleAnotherTool(args: any): Promise<string> {
56
+ // // Your implementation
57
+ // }
@@ -1,88 +1,89 @@
1
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- import { IToolInputSchema, IToolProperties } from '../../core/index.js';
3
-
4
- /**
5
- * Template tools configuration for MCP Server
6
- * Define your tools according to your server's functionality
7
- */
8
-
9
-
10
- const getGenericInputSchema = (
11
- queryDescription?: string,
12
- additionalProperties?: IToolProperties,
13
- ): IToolInputSchema => {
14
- const properties = {
15
- query: {
16
- type: 'string',
17
- description: queryDescription || 'Input query or text',
18
- },
19
- ...additionalProperties,
20
- };
21
-
22
- return {
23
- type: 'object',
24
- properties,
25
- required: ['query'],
26
- };
27
- };
28
-
29
- const getSearchInputSchema = (): IToolInputSchema => {
30
- return {
31
- type: 'object',
32
- properties: {
33
- query: {
34
- type: 'string',
35
- description: 'Search query',
36
- },
37
- limit: {
38
- type: 'number',
39
- description: 'Maximum number of results to return (1-100, default: 20)',
40
- minimum: 1,
41
- maximum: 100,
42
- },
43
- threshold: {
44
- type: 'number',
45
- description: 'Minimum similarity threshold (0-1)',
46
- minimum: 0,
47
- maximum: 1,
48
- },
49
- },
50
- required: ['query'],
51
- };
52
- };
53
-
54
- // Template tools - customize according to your needs
55
- export const tools: Tool[] = [
56
- {
57
- name: 'example_tool',
58
- description: 'Example tool that processes text input. Replace with your actual tools.',
59
- inputSchema: getGenericInputSchema('Text to process'),
60
- },
61
- {
62
- name: 'example_search',
63
- description: 'Example search tool with pagination and filtering. Template for search-based tools.',
64
- inputSchema: getSearchInputSchema(),
65
- },
66
- // TODO: Add your actual tools here
67
- // {
68
- // name: 'your_tool_name',
69
- // description: 'Description of what your tool does',
70
- // inputSchema: getGenericInputSchema('Your query description', {
71
- // // additional parameters
72
- // param1: {
73
- // type: 'string',
74
- // description: 'Description of param1',
75
- // },
76
- // }),
77
- // },
78
- ];
79
-
80
- // Helper to get tool by name
81
- export const getToolByName = (name: string): Tool | undefined => {
82
- return tools.find(tool => tool.name === name);
83
- };
84
-
85
- // Helper to get all tool names
86
- export const getToolNames = (): string[] => {
87
- return tools.map(tool => tool.name);
88
- };
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+
3
+ import { IToolInputSchema, IToolProperties } from '../../core/index.js';
4
+
5
+ /**
6
+ * Template tools configuration for MCP Server
7
+ * Define your tools according to your server's functionality
8
+ */
9
+
10
+
11
+ const getGenericInputSchema = (
12
+ queryDescription?: string,
13
+ additionalProperties?: IToolProperties,
14
+ ): IToolInputSchema => {
15
+ const properties = {
16
+ query: {
17
+ type: 'string',
18
+ description: queryDescription || 'Input query or text',
19
+ },
20
+ ...additionalProperties,
21
+ };
22
+
23
+ return {
24
+ type: 'object',
25
+ properties,
26
+ required: ['query'],
27
+ };
28
+ };
29
+
30
+ const getSearchInputSchema = (): IToolInputSchema => {
31
+ return {
32
+ type: 'object',
33
+ properties: {
34
+ query: {
35
+ type: 'string',
36
+ description: 'Search query',
37
+ },
38
+ limit: {
39
+ type: 'number',
40
+ description: 'Maximum number of results to return (1-100, default: 20)',
41
+ minimum: 1,
42
+ maximum: 100,
43
+ },
44
+ threshold: {
45
+ type: 'number',
46
+ description: 'Minimum similarity threshold (0-1)',
47
+ minimum: 0,
48
+ maximum: 1,
49
+ },
50
+ },
51
+ required: ['query'],
52
+ };
53
+ };
54
+
55
+ // Template tools - customize according to your needs
56
+ export const tools: Tool[] = [
57
+ {
58
+ name: 'example_tool',
59
+ description: 'Example tool that processes text input. Replace with your actual tools.',
60
+ inputSchema: getGenericInputSchema('Text to process'),
61
+ },
62
+ {
63
+ name: 'example_search',
64
+ description: 'Example search tool with pagination and filtering. Template for search-based tools.',
65
+ inputSchema: getSearchInputSchema(),
66
+ },
67
+ // TODO: Add your actual tools here
68
+ // {
69
+ // name: 'your_tool_name',
70
+ // description: 'Description of what your tool does',
71
+ // inputSchema: getGenericInputSchema('Your query description', {
72
+ // // additional parameters
73
+ // param1: {
74
+ // type: 'string',
75
+ // description: 'Description of param1',
76
+ // },
77
+ // }),
78
+ // },
79
+ ];
80
+
81
+ // Helper to get tool by name
82
+ export const getToolByName = (name: string): Tool | undefined => {
83
+ return tools.find(tool => tool.name === name);
84
+ };
85
+
86
+ // Helper to get all tool names
87
+ export const getToolNames = (): string[] => {
88
+ return tools.map(tool => tool.name);
89
+ };
@@ -1,10 +1,10 @@
1
- export default class SimpleReporter {
2
- onRunComplete (contexts, runResults) {
3
- const { numPassedTests, numFailedTests, numPendingTests } = runResults;
4
- const total = numPassedTests + numFailedTests + numPendingTests;
5
- const actualSuccess = numFailedTests === 0 && total > 0;
6
-
7
- console.log(`\nTest Results: ${numPassedTests} passed, ${numFailedTests} failed, ${numPendingTests} skipped (${total} total)`);
8
- console.log(`Status: ${actualSuccess ? 'PASSED' : 'FAILED'}`);
9
- }
10
- }
1
+ export default class SimpleReporter {
2
+ onRunComplete (contexts, runResults) {
3
+ const { numPassedTests, numFailedTests, numPendingTests } = runResults;
4
+ const total = numPassedTests + numFailedTests + numPendingTests;
5
+ const actualSuccess = numFailedTests === 0 && total > 0;
6
+
7
+ console.log(`\nTest Results: ${numPassedTests} passed, ${numFailedTests} failed, ${numPendingTests} skipped (${total} total)`);
8
+ console.log(`Status: ${actualSuccess ? 'PASSED' : 'FAILED'}`);
9
+ }
10
+ }
@@ -1,96 +1,96 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Example of using fa-mcp-sdk as an npm package without unhandledRejection issues
5
- *
6
- * To use this example:
7
- * 1. Install fa-mcp-sdk: npm install fa-mcp-sdk
8
- * 2. Start MCP server: npm run template:start (in fa-mcp-sdk project)
9
- * 3. Run this example: node test-npm-package.js
10
- */
11
-
12
- import { McpSseClient } from 'fa-mcp-sdk';
13
-
14
- const SERVER_URL = 'http://localhost:9876';
15
-
16
- async function testMcpClient () {
17
- console.log('🧪 Testing MCP client as npm package');
18
- console.log('='.repeat(50));
19
-
20
- // Use the new method that handles unhandledRejection
21
- const client = McpSseClient.createWithErrorHandler(SERVER_URL);
22
-
23
- try {
24
- // Health check
25
- console.log('1. Health check...');
26
- try {
27
- const health = await client.health();
28
- console.log('✅ Health check passed:', health.status);
29
- } catch (error) {
30
- console.log('⚠️ Health check failed:', error.message);
31
- }
32
-
33
- // Initialize
34
- console.log('2. Initializing...');
35
- await client.sendRequest('initialize', {
36
- protocolVersion: '2024-11-05',
37
- capabilities: { tools: {} },
38
- clientInfo: { name: 'npm-test', version: '1.0.0' },
39
- });
40
- console.log('✅ Initialized successfully');
41
-
42
- // List tools
43
- console.log('3. Listing tools...');
44
- const tools = await client.listTools();
45
- const toolNames = tools.tools?.map(t => t.name) || [];
46
- console.log('✅ Available tools:', toolNames.join(', '));
47
-
48
- // Test successful tool call
49
- console.log('4. Testing successful tool call...');
50
- try {
51
- const response = await client.callTool('example_tool', { query: 'ping' });
52
- console.log('✅ Tool call successful:', response.result?.structuredContent?.message || response.result?.content?.[0]?.text);
53
- } catch (error) {
54
- console.log('❌ Tool call failed:', error.message);
55
- }
56
-
57
- // Test expected error (like the test case in test-cases.js)
58
- console.log('5. Testing expected error handling...');
59
- try {
60
- await client.callTool('example_tool', {}); // Missing query parameter
61
- console.log('❌ Expected error but got success');
62
- } catch (error) {
63
- console.log('✅ Expected error caught:', error.message);
64
- // This error should NOT cause unhandledRejection
65
- }
66
-
67
- // Test with invalid tool name
68
- console.log('6. Testing invalid tool name...');
69
- try {
70
- await client.callTool('nonexistent_tool', {});
71
- console.log('❌ Expected error but got success');
72
- } catch (error) {
73
- console.log('✅ Expected error caught:', error.message);
74
- // This error should NOT cause unhandledRejection
75
- }
76
-
77
- console.log('\n🎉 All tests completed successfully!');
78
- console.log('✨ No unhandledRejection errors occurred');
79
-
80
- } catch (error) {
81
- console.error('❌ Unexpected error:', error.message);
82
- } finally {
83
- await client.close();
84
- console.log('🔚 Client closed');
85
- }
86
- }
87
-
88
- // Global handler for any unexpected unhandled rejections
89
- process.on('unhandledRejection', (reason, promise) => {
90
- console.error('💥 UNHANDLED REJECTION (this should not happen):');
91
- console.error('Reason:', reason);
92
- console.error('Promise:', promise);
93
- process.exit(1);
94
- });
95
-
96
- testMcpClient().catch(console.error);
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Example of using fa-mcp-sdk as an npm package without unhandledRejection issues
5
+ *
6
+ * To use this example:
7
+ * 1. Install fa-mcp-sdk: npm install fa-mcp-sdk
8
+ * 2. Start MCP server: npm run template:start (in fa-mcp-sdk project)
9
+ * 3. Run this example: node test-npm-package.js
10
+ */
11
+
12
+ import { McpSseClient } from 'fa-mcp-sdk';
13
+
14
+ const SERVER_URL = 'http://localhost:9876';
15
+
16
+ async function testMcpClient () {
17
+ console.log('🧪 Testing MCP client as npm package');
18
+ console.log('='.repeat(50));
19
+
20
+ // Use the new method that handles unhandledRejection
21
+ const client = McpSseClient.createWithErrorHandler(SERVER_URL);
22
+
23
+ try {
24
+ // Health check
25
+ console.log('1. Health check...');
26
+ try {
27
+ const health = await client.health();
28
+ console.log('✅ Health check passed:', health.status);
29
+ } catch (error) {
30
+ console.log('⚠️ Health check failed:', error.message);
31
+ }
32
+
33
+ // Initialize
34
+ console.log('2. Initializing...');
35
+ await client.sendRequest('initialize', {
36
+ protocolVersion: '2024-11-05',
37
+ capabilities: { tools: {} },
38
+ clientInfo: { name: 'npm-test', version: '1.0.0' },
39
+ });
40
+ console.log('✅ Initialized successfully');
41
+
42
+ // List tools
43
+ console.log('3. Listing tools...');
44
+ const tools = await client.listTools();
45
+ const toolNames = tools.tools?.map(t => t.name) || [];
46
+ console.log('✅ Available tools:', toolNames.join(', '));
47
+
48
+ // Test successful tool call
49
+ console.log('4. Testing successful tool call...');
50
+ try {
51
+ const response = await client.callTool('example_tool', { query: 'ping' });
52
+ console.log('✅ Tool call successful:', response.result?.structuredContent?.message || response.result?.content?.[0]?.text);
53
+ } catch (error) {
54
+ console.log('❌ Tool call failed:', error.message);
55
+ }
56
+
57
+ // Test expected error (like the test case in test-cases.js)
58
+ console.log('5. Testing expected error handling...');
59
+ try {
60
+ await client.callTool('example_tool', {}); // Missing query parameter
61
+ console.log('❌ Expected error but got success');
62
+ } catch (error) {
63
+ console.log('✅ Expected error caught:', error.message);
64
+ // This error should NOT cause unhandledRejection
65
+ }
66
+
67
+ // Test with invalid tool name
68
+ console.log('6. Testing invalid tool name...');
69
+ try {
70
+ await client.callTool('nonexistent_tool', {});
71
+ console.log('❌ Expected error but got success');
72
+ } catch (error) {
73
+ console.log('✅ Expected error caught:', error.message);
74
+ // This error should NOT cause unhandledRejection
75
+ }
76
+
77
+ console.log('\n🎉 All tests completed successfully!');
78
+ console.log('✨ No unhandledRejection errors occurred');
79
+
80
+ } catch (error) {
81
+ console.error('❌ Unexpected error:', error.message);
82
+ } finally {
83
+ await client.close();
84
+ console.log('🔚 Client closed');
85
+ }
86
+ }
87
+
88
+ // Global handler for any unexpected unhandled rejections
89
+ process.on('unhandledRejection', (reason, promise) => {
90
+ console.error('💥 UNHANDLED REJECTION (this should not happen):');
91
+ console.error('Reason:', reason);
92
+ console.error('Promise:', promise);
93
+ process.exit(1);
94
+ });
95
+
96
+ testMcpClient().catch(console.error);