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.
- package/README.md +319 -314
- package/bin/fa-mcp.js +85 -68
- package/cli-template/.claude/agents/javascript-pro.md +276 -276
- package/cli-template/.claude/settings.json +50 -50
- package/cli-template/.claude/skills/upgrade-guide/SKILL.md +2 -1
- package/cli-template/.oxfmtrc.json +41 -0
- package/cli-template/.oxlintrc.json +120 -0
- package/cli-template/CLAUDE.md +358 -355
- package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +132 -132
- package/cli-template/FA-MCP-SDK-DOC/01-getting-started.md +146 -146
- package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +431 -431
- package/cli-template/FA-MCP-SDK-DOC/02-2-prompts-and-resources.md +201 -201
- package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +384 -384
- package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +412 -412
- package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +196 -196
- package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +163 -163
- package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +127 -127
- package/cli-template/jest.config.js +27 -30
- package/cli-template/package.json +10 -5
- package/cli-template/prompt-example-new-MCP.md +101 -101
- package/cli-template/readme-docs/SKILLS.md +1 -1
- package/cli-template/tsconfig.json +58 -58
- package/cli-template/update.cjs +41 -38
- package/config/custom-environment-variables.yaml +63 -63
- package/config/development.yaml +4 -4
- package/config/production.yaml +4 -4
- package/config/test.yaml +26 -26
- package/dist/core/_types_/TNtlm.d.ts.map +1 -1
- package/dist/core/_types_/active-directory-config.d.ts.map +1 -1
- package/dist/core/_types_/config.d.ts.map +1 -1
- package/dist/core/_types_/types.d.ts.map +1 -1
- package/dist/core/ad/group-checker.d.ts.map +1 -1
- package/dist/core/ad/group-checker.js.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.js +6 -6
- package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
- package/dist/core/agent-tester/check-llm.d.ts.map +1 -1
- package/dist/core/agent-tester/check-llm.js.map +1 -1
- package/dist/core/agent-tester/services/SummaryMemory.d.ts.map +1 -1
- package/dist/core/agent-tester/services/SummaryMemory.js +3 -9
- package/dist/core/agent-tester/services/SummaryMemory.js.map +1 -1
- package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
- package/dist/core/agent-tester/services/TesterAgentService.js +25 -27
- package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
- package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
- package/dist/core/agent-tester/services/TesterMcpClientService.js +26 -25
- package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
- package/dist/core/auth/admin-auth.d.ts.map +1 -1
- package/dist/core/auth/admin-auth.js +5 -5
- package/dist/core/auth/admin-auth.js.map +1 -1
- package/dist/core/auth/agent-tester-auth.d.ts.map +1 -1
- package/dist/core/auth/agent-tester-auth.js +1 -6
- package/dist/core/auth/agent-tester-auth.js.map +1 -1
- package/dist/core/auth/basic.d.ts.map +1 -1
- package/dist/core/auth/basic.js.map +1 -1
- package/dist/core/auth/ip-check.d.ts.map +1 -1
- package/dist/core/auth/ip-check.js +1 -1
- package/dist/core/auth/ip-check.js.map +1 -1
- package/dist/core/auth/jwt.d.ts.map +1 -1
- package/dist/core/auth/jwt.js +1 -1
- package/dist/core/auth/jwt.js.map +1 -1
- package/dist/core/auth/middleware.d.ts.map +1 -1
- package/dist/core/auth/middleware.js +9 -6
- package/dist/core/auth/middleware.js.map +1 -1
- package/dist/core/auth/multi-auth.d.ts.map +1 -1
- package/dist/core/auth/multi-auth.js +6 -6
- package/dist/core/auth/multi-auth.js.map +1 -1
- package/dist/core/auth/revocation.d.ts.map +1 -1
- package/dist/core/auth/revocation.js +2 -6
- package/dist/core/auth/revocation.js.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.d.ts.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js +2 -2
- package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-integration.d.ts.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-integration.js +4 -2
- package/dist/core/auth/token-generator/ntlm/ntlm-integration.js.map +1 -1
- package/dist/core/auth/token-generator/server.d.ts.map +1 -1
- package/dist/core/auth/token-generator/server.js.map +1 -1
- package/dist/core/bootstrap/init-config.d.ts.map +1 -1
- package/dist/core/bootstrap/init-config.js +2 -2
- package/dist/core/bootstrap/init-config.js.map +1 -1
- package/dist/core/bootstrap/startup-info.d.ts.map +1 -1
- package/dist/core/bootstrap/startup-info.js +3 -7
- package/dist/core/bootstrap/startup-info.js.map +1 -1
- package/dist/core/cache/cache.d.ts.map +1 -1
- package/dist/core/cache/cache.js +2 -2
- package/dist/core/cache/cache.js.map +1 -1
- package/dist/core/consul/deregister.d.ts.map +1 -1
- package/dist/core/consul/deregister.js.map +1 -1
- package/dist/core/consul/get-consul-api.d.ts.map +1 -1
- package/dist/core/consul/get-consul-api.js +1 -2
- package/dist/core/consul/get-consul-api.js.map +1 -1
- package/dist/core/db/pg-db.d.ts.map +1 -1
- package/dist/core/db/pg-db.js +3 -3
- package/dist/core/db/pg-db.js.map +1 -1
- package/dist/core/debug.d.ts.map +1 -1
- package/dist/core/debug.js.map +1 -1
- package/dist/core/errors/BaseMcpError.d.ts.map +1 -1
- package/dist/core/errors/BaseMcpError.js.map +1 -1
- package/dist/core/errors/ValidationError.d.ts.map +1 -1
- package/dist/core/errors/ValidationError.js.map +1 -1
- package/dist/core/errors/errors.d.ts.map +1 -1
- package/dist/core/errors/errors.js +1 -1
- package/dist/core/errors/errors.js.map +1 -1
- package/dist/core/index.d.ts +6 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -5
- package/dist/core/index.js.map +1 -1
- package/dist/core/init-mcp-server.d.ts.map +1 -1
- package/dist/core/init-mcp-server.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +1 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
- package/dist/core/mcp/create-mcp-server.js +1 -1
- package/dist/core/mcp/create-mcp-server.js.map +1 -1
- package/dist/core/mcp/prompts.d.ts.map +1 -1
- package/dist/core/mcp/prompts.js.map +1 -1
- package/dist/core/mcp/readme-assembler.d.ts.map +1 -1
- package/dist/core/mcp/readme-assembler.js +3 -1
- package/dist/core/mcp/readme-assembler.js.map +1 -1
- package/dist/core/mcp/resources.d.ts.map +1 -1
- package/dist/core/mcp/resources.js.map +1 -1
- package/dist/core/mcp/server-stdio.d.ts.map +1 -1
- package/dist/core/utils/formatToolResult.d.ts.map +1 -1
- package/dist/core/utils/formatToolResult.js.map +1 -1
- package/dist/core/utils/port-checker.d.ts.map +1 -1
- package/dist/core/utils/port-checker.js.map +1 -1
- package/dist/core/utils/rate-limit.d.ts.map +1 -1
- package/dist/core/utils/rate-limit.js +2 -8
- package/dist/core/utils/rate-limit.js.map +1 -1
- package/dist/core/utils/testing/BaseMcpClient.d.ts.map +1 -1
- package/dist/core/utils/testing/BaseMcpClient.js.map +1 -1
- package/dist/core/utils/testing/McpHttpClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpHttpClient.js +2 -2
- package/dist/core/utils/testing/McpHttpClient.js.map +1 -1
- package/dist/core/utils/testing/McpSseClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpSseClient.js +3 -8
- package/dist/core/utils/testing/McpSseClient.js.map +1 -1
- package/dist/core/utils/testing/McpStdioClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpStdioClient.js.map +1 -1
- package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpStreamableHttpClient.js +7 -8
- package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -1
- package/dist/core/utils/utils.d.ts.map +1 -1
- package/dist/core/utils/utils.js +3 -5
- package/dist/core/utils/utils.js.map +1 -1
- package/dist/core/web/admin-router.d.ts.map +1 -1
- package/dist/core/web/admin-router.js +3 -3
- package/dist/core/web/admin-router.js.map +1 -1
- package/dist/core/web/cors.d.ts.map +1 -1
- package/dist/core/web/cors.js.map +1 -1
- package/dist/core/web/favicon-svg.d.ts.map +1 -1
- package/dist/core/web/favicon-svg.js +1 -5
- package/dist/core/web/favicon-svg.js.map +1 -1
- package/dist/core/web/home-api.d.ts.map +1 -1
- package/dist/core/web/home-api.js +7 -8
- package/dist/core/web/home-api.js.map +1 -1
- package/dist/core/web/openapi.d.ts.map +1 -1
- package/dist/core/web/openapi.js +1 -3
- package/dist/core/web/openapi.js.map +1 -1
- package/dist/core/web/server-http.d.ts.map +1 -1
- package/dist/core/web/server-http.js +4 -4
- package/dist/core/web/server-http.js.map +1 -1
- package/dist/core/web/static/agent-tester/index.html +323 -323
- package/dist/core/web/static/agent-tester/script.js +311 -200
- package/dist/core/web/static/agent-tester/styles.css +1840 -1840
- package/dist/core/web/static/home/index.html +220 -220
- package/dist/core/web/static/home/script.js +72 -43
- package/dist/core/web/static/styles.css +927 -927
- package/dist/core/web/static/token-gen/index.html +136 -136
- package/dist/core/web/static/token-gen/script.js +58 -56
- package/dist/core/web/svg-icons.d.ts.map +1 -1
- package/dist/core/web/svg-icons.js +1 -5
- package/dist/core/web/svg-icons.js.map +1 -1
- package/package.json +10 -5
- package/{cli-template/.claude/hooks/eslint-fix.cjs → scripts/cc-hook-oxlint-oxfmt-fix.cjs} +109 -100
- package/scripts/generate-jwt.js +5 -9
- package/scripts/kill-port.js +5 -2
- package/scripts/npm/run.js +1 -2
- package/scripts/remove-nul.js +1 -1
- package/scripts/update-sdk.js +36 -14
- package/src/template/api/router.ts +3 -3
- package/src/template/prompts/agent-brief.ts +0 -1
- package/src/template/start.ts +3 -8
- package/src/template/tools/handle-tool-call.ts +3 -3
- package/src/template/tools/tools.ts +3 -7
- package/src/tests/jest-simple-reporter.js +1 -1
- package/src/tests/mcp/sse/mcp-sse-client-handling.md +111 -111
- package/src/tests/mcp/sse/test-sse-npm-package.js +2 -3
- package/src/tests/mcp/test-cases.js +6 -7
- package/src/tests/mcp/test-http.js +2 -2
- package/src/tests/mcp/test-sse.js +9 -7
- package/src/tests/mcp/test-stdio.js +12 -8
- package/src/tests/utils.ts +4 -3
- package/cli-template/eslint.config.js +0 -27
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
# MCP SSE Client - Preventing unhandledRejection
|
|
2
|
-
|
|
3
|
-
## Problem
|
|
4
|
-
|
|
5
|
-
When using `fa-mcp-sdk` as an npm package in tests where `McpSseClient` is imported, `unhandledRejection` errors may occur. This happens because MCP errors are handled asynchronously through SSE (Server-Sent Events) and may not be properly caught in the test context.
|
|
6
|
-
|
|
7
|
-
## Why this happens
|
|
8
|
-
|
|
9
|
-
1. **Local tests**: Run in the same process as the MCP server
|
|
10
|
-
2. **NPM package**: The test runs in a separate process
|
|
11
|
-
3. **SSE asynchronicity**: Errors may occur after the promise is created but before they are handled
|
|
12
|
-
|
|
13
|
-
## Solutions
|
|
14
|
-
|
|
15
|
-
### Solution 1: Use a static method (recommended)
|
|
16
|
-
|
|
17
|
-
```javascript
|
|
18
|
-
import { McpSseClient } from 'fa-mcp-sdk';
|
|
19
|
-
|
|
20
|
-
// Create a client with automatic unhandledRejection handling
|
|
21
|
-
const client = McpSseClient.createWithErrorHandler('http://localhost:3000');
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const response = await client.callTool('execute_sql_query', { sql: test.sql });
|
|
25
|
-
console.log('✅ Success:', response);
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.log('❌ Error:', error.message);
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Solution 2: Global unhandledRejection handler
|
|
32
|
-
|
|
33
|
-
Add at the beginning of the test file:
|
|
34
|
-
|
|
35
|
-
```javascript
|
|
36
|
-
// Global handling of MCP errors
|
|
37
|
-
process.on('unhandledRejection', (reason) => {
|
|
38
|
-
if (typeof reason === 'object' && reason?.message?.includes('MCP Error:')) {
|
|
39
|
-
// Ignore MCP errors — they are handled in try-catch
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Or using the built-in method
|
|
45
|
-
import { McpSseClient } from 'fa-mcp-sdk';
|
|
46
|
-
McpSseClient.setupGlobalErrorHandler();
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Solution 3: Promise with error handling
|
|
50
|
-
|
|
51
|
-
```javascript
|
|
52
|
-
import { McpSseClient } from 'fa-mcp-sdk';
|
|
53
|
-
|
|
54
|
-
const client = new McpSseClient('http://localhost:3000');
|
|
55
|
-
|
|
56
|
-
// Wrap all calls in an additional catch
|
|
57
|
-
async function safeCallTool(toolName, args) {
|
|
58
|
-
try {
|
|
59
|
-
return await client.callTool(toolName, args);
|
|
60
|
-
} catch (error) {
|
|
61
|
-
// Additional handling to prevent unhandledRejection
|
|
62
|
-
if (error.message.includes('MCP Error:')) {
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
65
|
-
throw new Error(`Unexpected error: ${error.message}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Full test example
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
import { McpSseClient } from 'fa-mcp-sdk';
|
|
74
|
-
|
|
75
|
-
async function testToolExecution() {
|
|
76
|
-
// Create a client with error handling
|
|
77
|
-
const client = McpSseClient.createWithErrorHandler('http://localhost:3000');
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
// Test successful execution
|
|
81
|
-
const successResponse = await client.callTool('example_tool', { query: 'ping' });
|
|
82
|
-
console.log('✅ Tool executed successfully:', successResponse);
|
|
83
|
-
|
|
84
|
-
// Test error handling (as in your example)
|
|
85
|
-
try {
|
|
86
|
-
await client.callTool('example_tool', {}); // No query — should error
|
|
87
|
-
console.log('❌ Expected error but got success');
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.log('✅ Expected error caught:', error.message);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
} catch (error) {
|
|
93
|
-
console.error('❌ Unexpected test error:', error);
|
|
94
|
-
} finally {
|
|
95
|
-
await client.close();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
testToolExecution();
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Important notes
|
|
103
|
-
|
|
104
|
-
1. **For npm packages only**: The issue usually does not occur in local tests
|
|
105
|
-
2. **MCP errors**: The handler filters only errors containing 'MCP Error:'
|
|
106
|
-
3. **Global handler**: Installed once per process
|
|
107
|
-
4. **Resources**: Don’t forget to call `client.close()` for cleanup
|
|
108
|
-
|
|
109
|
-
## Technical details
|
|
110
|
-
|
|
111
|
-
The issue arises because SSE errors are handled in `McpSseClient.handleSseEvent()` and may cause a promise rejection that is not yet caught at the moment the error occurs. New methods provide an additional layer of handling to prevent unhandledRejection.
|
|
1
|
+
# MCP SSE Client - Preventing unhandledRejection
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
When using `fa-mcp-sdk` as an npm package in tests where `McpSseClient` is imported, `unhandledRejection` errors may occur. This happens because MCP errors are handled asynchronously through SSE (Server-Sent Events) and may not be properly caught in the test context.
|
|
6
|
+
|
|
7
|
+
## Why this happens
|
|
8
|
+
|
|
9
|
+
1. **Local tests**: Run in the same process as the MCP server
|
|
10
|
+
2. **NPM package**: The test runs in a separate process
|
|
11
|
+
3. **SSE asynchronicity**: Errors may occur after the promise is created but before they are handled
|
|
12
|
+
|
|
13
|
+
## Solutions
|
|
14
|
+
|
|
15
|
+
### Solution 1: Use a static method (recommended)
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import { McpSseClient } from 'fa-mcp-sdk';
|
|
19
|
+
|
|
20
|
+
// Create a client with automatic unhandledRejection handling
|
|
21
|
+
const client = McpSseClient.createWithErrorHandler('http://localhost:3000');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const response = await client.callTool('execute_sql_query', { sql: test.sql });
|
|
25
|
+
console.log('✅ Success:', response);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.log('❌ Error:', error.message);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Solution 2: Global unhandledRejection handler
|
|
32
|
+
|
|
33
|
+
Add at the beginning of the test file:
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
// Global handling of MCP errors
|
|
37
|
+
process.on('unhandledRejection', (reason) => {
|
|
38
|
+
if (typeof reason === 'object' && reason?.message?.includes('MCP Error:')) {
|
|
39
|
+
// Ignore MCP errors — they are handled in try-catch
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Or using the built-in method
|
|
45
|
+
import { McpSseClient } from 'fa-mcp-sdk';
|
|
46
|
+
McpSseClient.setupGlobalErrorHandler();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Solution 3: Promise with error handling
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
import { McpSseClient } from 'fa-mcp-sdk';
|
|
53
|
+
|
|
54
|
+
const client = new McpSseClient('http://localhost:3000');
|
|
55
|
+
|
|
56
|
+
// Wrap all calls in an additional catch
|
|
57
|
+
async function safeCallTool(toolName, args) {
|
|
58
|
+
try {
|
|
59
|
+
return await client.callTool(toolName, args);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
// Additional handling to prevent unhandledRejection
|
|
62
|
+
if (error.message.includes('MCP Error:')) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Unexpected error: ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Full test example
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
import { McpSseClient } from 'fa-mcp-sdk';
|
|
74
|
+
|
|
75
|
+
async function testToolExecution() {
|
|
76
|
+
// Create a client with error handling
|
|
77
|
+
const client = McpSseClient.createWithErrorHandler('http://localhost:3000');
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
// Test successful execution
|
|
81
|
+
const successResponse = await client.callTool('example_tool', { query: 'ping' });
|
|
82
|
+
console.log('✅ Tool executed successfully:', successResponse);
|
|
83
|
+
|
|
84
|
+
// Test error handling (as in your example)
|
|
85
|
+
try {
|
|
86
|
+
await client.callTool('example_tool', {}); // No query — should error
|
|
87
|
+
console.log('❌ Expected error but got success');
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log('✅ Expected error caught:', error.message);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('❌ Unexpected test error:', error);
|
|
94
|
+
} finally {
|
|
95
|
+
await client.close();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
testToolExecution();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Important notes
|
|
103
|
+
|
|
104
|
+
1. **For npm packages only**: The issue usually does not occur in local tests
|
|
105
|
+
2. **MCP errors**: The handler filters only errors containing 'MCP Error:'
|
|
106
|
+
3. **Global handler**: Installed once per process
|
|
107
|
+
4. **Resources**: Don’t forget to call `client.close()` for cleanup
|
|
108
|
+
|
|
109
|
+
## Technical details
|
|
110
|
+
|
|
111
|
+
The issue arises because SSE errors are handled in `McpSseClient.handleSseEvent()` and may cause a promise rejection that is not yet caught at the moment the error occurs. New methods provide an additional layer of handling to prevent unhandledRejection.
|
|
@@ -13,7 +13,7 @@ import { McpSseClient } from 'fa-mcp-sdk';
|
|
|
13
13
|
|
|
14
14
|
const SERVER_URL = 'http://localhost:9876';
|
|
15
15
|
|
|
16
|
-
async function testMcpClient
|
|
16
|
+
async function testMcpClient() {
|
|
17
17
|
console.log('🧪 Testing MCP client as npm package');
|
|
18
18
|
console.log('='.repeat(50));
|
|
19
19
|
|
|
@@ -42,7 +42,7 @@ async function testMcpClient () {
|
|
|
42
42
|
// List tools
|
|
43
43
|
console.log('3. Listing tools...');
|
|
44
44
|
const tools = await client.listTools();
|
|
45
|
-
const toolNames = tools.tools?.map(t => t.name) || [];
|
|
45
|
+
const toolNames = tools.tools?.map((t) => t.name) || [];
|
|
46
46
|
console.log('✅ Available tools:', toolNames.join(', '));
|
|
47
47
|
|
|
48
48
|
// Test successful tool call
|
|
@@ -76,7 +76,6 @@ async function testMcpClient () {
|
|
|
76
76
|
|
|
77
77
|
console.log('\n🎉 All tests completed successfully!');
|
|
78
78
|
console.log('✨ No unhandledRejection errors occurred');
|
|
79
|
-
|
|
80
79
|
} catch (error) {
|
|
81
80
|
console.error('❌ Unexpected error:', error.message);
|
|
82
81
|
} finally {
|
|
@@ -30,10 +30,10 @@ export const TEMPLATE_TESTS = {
|
|
|
30
30
|
try {
|
|
31
31
|
const list = await client.listPrompts();
|
|
32
32
|
const prompts = list?.prompts || list;
|
|
33
|
-
const names = Array.isArray(prompts) ? prompts.map(p => p.name) : [];
|
|
33
|
+
const names = Array.isArray(prompts) ? prompts.map((p) => p.name) : [];
|
|
34
34
|
const okBrief = names.includes('agent_brief');
|
|
35
35
|
const okPrompt = names.includes('agent_prompt');
|
|
36
|
-
return
|
|
36
|
+
return okBrief && okPrompt ? ok(name, { names }) : fail(name, { names });
|
|
37
37
|
} catch (e) {
|
|
38
38
|
return fail(name, { error: e?.message });
|
|
39
39
|
}
|
|
@@ -77,7 +77,7 @@ export const TEMPLATE_TESTS = {
|
|
|
77
77
|
try {
|
|
78
78
|
const list = await client.listResources();
|
|
79
79
|
const resources = list?.resources || list;
|
|
80
|
-
const uris = Array.isArray(resources) ? resources.map(r => r.uri) : [];
|
|
80
|
+
const uris = Array.isArray(resources) ? resources.map((r) => r.uri) : [];
|
|
81
81
|
const found = uris.includes('custom-resource://resource1');
|
|
82
82
|
return found ? ok(name, { uris }) : fail(name, { uris });
|
|
83
83
|
} catch (e) {
|
|
@@ -105,10 +105,10 @@ export const TEMPLATE_TESTS = {
|
|
|
105
105
|
try {
|
|
106
106
|
const list = await client.listTools();
|
|
107
107
|
const tools = list?.tools || list;
|
|
108
|
-
const names = Array.isArray(tools) ? tools.map(t => t.name) : [];
|
|
108
|
+
const names = Array.isArray(tools) ? tools.map((t) => t.name) : [];
|
|
109
109
|
const ok1 = names.includes('example_tool');
|
|
110
110
|
const ok2 = names.includes('example_search');
|
|
111
|
-
return
|
|
111
|
+
return ok1 && ok2 ? ok(name, { names }) : fail(name, { names });
|
|
112
112
|
} catch (e) {
|
|
113
113
|
return fail(name, { error: e?.message });
|
|
114
114
|
}
|
|
@@ -121,8 +121,7 @@ export const TEMPLATE_TESTS = {
|
|
|
121
121
|
// Both structuredContent and text are acceptable; check message echo
|
|
122
122
|
const structured = r?.structuredContent;
|
|
123
123
|
const text = r?.content?.[0]?.text;
|
|
124
|
-
const hasProcessed = (structured && structured.message?.includes('Processed query'))
|
|
125
|
-
|| (typeof text === 'string' && text.includes('Processed query'));
|
|
124
|
+
const hasProcessed = (structured && structured.message?.includes('Processed query')) || (typeof text === 'string' && text.includes('Processed query'));
|
|
126
125
|
return hasProcessed ? ok(name, { response: r }) : fail(name, { response: r });
|
|
127
126
|
} catch (e) {
|
|
128
127
|
return fail(name, { error: e?.message });
|
|
@@ -11,7 +11,7 @@ import TEMPLATE_TESTS from './test-cases.js';
|
|
|
11
11
|
|
|
12
12
|
const baseURL = (process.env.TEST_MCP_SERVER_URL || `http://localhost:${appConfig.webServer.port}`).replace(/\/+$/, '');
|
|
13
13
|
|
|
14
|
-
async function runTestGroup
|
|
14
|
+
async function runTestGroup(title, tests, client) {
|
|
15
15
|
console.log(`\n${title}:`);
|
|
16
16
|
let passed = 0;
|
|
17
17
|
for (const test of tests) {
|
|
@@ -34,7 +34,7 @@ async function runTestGroup (title, tests, client) {
|
|
|
34
34
|
return passed;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
async function main
|
|
37
|
+
async function main() {
|
|
38
38
|
console.log('🧪 HTTP tests for template MCP server');
|
|
39
39
|
console.log('='.repeat(60));
|
|
40
40
|
|
|
@@ -11,7 +11,7 @@ import TEMPLATE_TESTS from './test-cases.js';
|
|
|
11
11
|
|
|
12
12
|
const baseURL = (process.env.TEST_MCP_SERVER_URL || `http://localhost:${appConfig.webServer.port}`).replace(/\/+$/, '');
|
|
13
13
|
|
|
14
|
-
async function runTestGroup
|
|
14
|
+
async function runTestGroup(title, tests, client) {
|
|
15
15
|
console.log(`\n${title}:`);
|
|
16
16
|
let passed = 0;
|
|
17
17
|
for (const test of tests) {
|
|
@@ -34,7 +34,7 @@ async function runTestGroup (title, tests, client) {
|
|
|
34
34
|
return passed;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
async function main
|
|
37
|
+
async function main() {
|
|
38
38
|
console.log('🧪 SSE tests for template MCP server');
|
|
39
39
|
console.log('='.repeat(60));
|
|
40
40
|
|
|
@@ -52,11 +52,13 @@ async function main () {
|
|
|
52
52
|
await client.health().catch(() => undefined);
|
|
53
53
|
|
|
54
54
|
// Initialize over RPC channel used by SSE client (POST /rpc)
|
|
55
|
-
await client
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
await client
|
|
56
|
+
.sendRequest('initialize', {
|
|
57
|
+
protocolVersion: '2024-11-05',
|
|
58
|
+
capabilities: { tools: {} },
|
|
59
|
+
clientInfo: { name: 'sse-test', version: '1.0.0' },
|
|
60
|
+
})
|
|
61
|
+
.catch(() => undefined);
|
|
60
62
|
|
|
61
63
|
const p1 = await runTestGroup('Prompts', TEMPLATE_TESTS.prompts, client);
|
|
62
64
|
const p2 = await runTestGroup('Resources', TEMPLATE_TESTS.resources, client);
|
|
@@ -18,7 +18,7 @@ const __dirname = dirname(__filename);
|
|
|
18
18
|
|
|
19
19
|
const serverPath = join(__dirname, '../../../dist/template/start.js');
|
|
20
20
|
|
|
21
|
-
async function runTestGroup
|
|
21
|
+
async function runTestGroup(title, tests, client) {
|
|
22
22
|
console.log(`\n${title}:`);
|
|
23
23
|
let passed = 0;
|
|
24
24
|
for (const test of tests) {
|
|
@@ -42,7 +42,7 @@ async function runTestGroup (title, tests, client) {
|
|
|
42
42
|
return passed;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
async function main
|
|
45
|
+
async function main() {
|
|
46
46
|
console.log('🧪 STDIO tests for template MCP server');
|
|
47
47
|
console.log('='.repeat(60));
|
|
48
48
|
|
|
@@ -55,11 +55,13 @@ async function main () {
|
|
|
55
55
|
|
|
56
56
|
try {
|
|
57
57
|
// Initialize handshake (optional for stdio server; safe to send)
|
|
58
|
-
await client
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
await client
|
|
59
|
+
.send('initialize', {
|
|
60
|
+
protocolVersion: '2024-11-05',
|
|
61
|
+
capabilities: { tools: {} },
|
|
62
|
+
clientInfo: { name: 'stdio-test', version: '1.0.0' },
|
|
63
|
+
})
|
|
64
|
+
.catch(() => undefined);
|
|
63
65
|
|
|
64
66
|
const p1 = await runTestGroup('Prompts', TEMPLATE_TESTS.prompts, client);
|
|
65
67
|
const p2 = await runTestGroup('Resources', TEMPLATE_TESTS.resources, client);
|
|
@@ -69,7 +71,9 @@ async function main () {
|
|
|
69
71
|
const sum = p1 + p2 + p3;
|
|
70
72
|
console.log(`\nSummary: ${sum}/${total} tests passed`);
|
|
71
73
|
} finally {
|
|
72
|
-
try {
|
|
74
|
+
try {
|
|
75
|
+
proc.kill();
|
|
76
|
+
} catch {}
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
package/src/tests/utils.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface ITestResult {
|
|
|
26
26
|
|
|
27
27
|
// Temporal metadata
|
|
28
28
|
timestamp: string; // ISO string
|
|
29
|
-
duration: number;
|
|
29
|
+
duration: number; // milliseconds
|
|
30
30
|
|
|
31
31
|
// Execution status
|
|
32
32
|
status: 'pending' | 'passed' | 'failed' | 'skipped' | 'expected_failure';
|
|
@@ -85,7 +85,9 @@ export const formatResultAsMarkdown = (result: ITestResult) => {
|
|
|
85
85
|
|
|
86
86
|
let requestHeaders = '';
|
|
87
87
|
if (result.requestHeaders && Object.keys(result.requestHeaders).length > 0) {
|
|
88
|
-
requestHeaders = `\nHeaders:\n${Object.entries(result.requestHeaders)
|
|
88
|
+
requestHeaders = `\nHeaders:\n${Object.entries(result.requestHeaders)
|
|
89
|
+
.map(([k, v]) => ` ${k}: ${v}`)
|
|
90
|
+
.join('\n')}\n`;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
// Format response section
|
|
@@ -121,7 +123,6 @@ export const formatResultAsMarkdown = (result: ITestResult) => {
|
|
|
121
123
|
}
|
|
122
124
|
responseText = `## Response\n\n${mdJson(text)}\n\n${addText}`;
|
|
123
125
|
}
|
|
124
|
-
|
|
125
126
|
} catch {
|
|
126
127
|
// Fallback to text if any parsing errors
|
|
127
128
|
responseText = `## Response\n\n${mdText(String(result.response))}\n\n`;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import baseConfig from 'eslint-config-at-26-2';
|
|
2
|
-
|
|
3
|
-
export default [
|
|
4
|
-
...baseConfig,
|
|
5
|
-
|
|
6
|
-
// Project-specific ignores not covered by base config
|
|
7
|
-
{
|
|
8
|
-
ignores: [
|
|
9
|
-
'cli-template/',
|
|
10
|
-
],
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
// Rules that were not in old config — disable to match previous behavior
|
|
14
|
-
{
|
|
15
|
-
rules: {
|
|
16
|
-
'no-console': 'off',
|
|
17
|
-
'import/order': 'off',
|
|
18
|
-
'prefer-arrow/prefer-arrow-functions': 'off',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
// JS-specific overrides
|
|
23
|
-
{
|
|
24
|
-
files: ['**/*.js', '**/*.mjs', '**/*.cjs'],
|
|
25
|
-
rules: {},
|
|
26
|
-
},
|
|
27
|
-
];
|