fa-mcp-sdk 0.4.74 → 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/mcp-app-add-to-server/SKILL.md +427 -0
- package/cli-template/.claude/skills/mcp-app-create/SKILL.md +222 -0
- 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/FA-MCP-SDK-DOC/08-agent-tester-and-headless-api.md +681 -659
- package/cli-template/README.md +193 -191
- 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 +86 -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,101 +1,101 @@
|
|
|
1
|
-
# Goal
|
|
2
|
-
Write the code for MCP server tools that implement retrieving the current cross-rate for a specified pair of currencies.
|
|
3
|
-
|
|
4
|
-
## Instructions
|
|
5
|
-
|
|
6
|
-
### Currency Cross-Rate API
|
|
7
|
-
|
|
8
|
-
#### Available Currencies
|
|
9
|
-
Currency codes (ISO 4217 code Alpha-3): ALL, ARS, AUD, BGN, BRL, BYN, CAD, CHF, CLP, CNY, CZK, DKK, EUR, GBP, HKD, HRK, HUF, IDR, INR, ISK, JOD, JPY, KRW, KZT, LAK, LKR, MKD, MMK, MXN, MYR, NOK, NPR, NZD, PHP, PLN, RON, RSD, RUB, SEK, SGD, THB, TRY, TWD, UAH, USD, VND, ZAR
|
|
10
|
-
|
|
11
|
-
#### Endpoint
|
|
12
|
-
|
|
13
|
-
```http request
|
|
14
|
-
GET http://<appConfig.accessPoints.currencyService.host>:<appConfig.accessPoints.currencyService.port>/currency-service/?rate=<QUOTE_CURRENCY><BASE_CURRENCY>
|
|
15
|
-
Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Example:
|
|
19
|
-
|
|
20
|
-
```http request
|
|
21
|
-
GET http://smart-trade-ml.com:5001/currency-service/?rate=THBRUB
|
|
22
|
-
Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Response:
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{"symbol": "THBRUB", "rate": 2.424167346170733}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Possible error codes: 400, 401, 404, 502
|
|
32
|
-
|
|
33
|
-
### Addition to config/default.yaml
|
|
34
|
-
|
|
35
|
-
```yaml
|
|
36
|
-
accessPoints:
|
|
37
|
-
currencyService:
|
|
38
|
-
host: smart-trade-ml.com
|
|
39
|
-
port: 5002
|
|
40
|
-
token: '***'
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
### Create config/local.yaml
|
|
45
|
-
|
|
46
|
-
Create a file config/local.yaml with the following content:
|
|
47
|
-
|
|
48
|
-
```yaml
|
|
49
|
-
---
|
|
50
|
-
accessPoints:
|
|
51
|
-
currencyService:
|
|
52
|
-
token: '88888888-4444-4444-4444-bbbbbbbbbbbb'
|
|
53
|
-
|
|
54
|
-
agentTester:
|
|
55
|
-
enabled: true
|
|
56
|
-
openAi:
|
|
57
|
-
apiKey: '<ask the user for the key>'
|
|
58
|
-
|
|
59
|
-
consul:
|
|
60
|
-
service:
|
|
61
|
-
enable: false
|
|
62
|
-
|
|
63
|
-
webServer:
|
|
64
|
-
auth:
|
|
65
|
-
enabled: true
|
|
66
|
-
jwtToken:
|
|
67
|
-
encryptKey: 'dbbe87db-90d0-4732-aae3-4089763ec392'
|
|
68
|
-
checkMCPName: true
|
|
69
|
-
isCheckIP: false
|
|
70
|
-
permanentServerTokens: ['psToken1']
|
|
71
|
-
|
|
72
|
-
adminPanel:
|
|
73
|
-
enabled: true
|
|
74
|
-
authType: 'permanentServerTokens'
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
# Task
|
|
78
|
-
|
|
79
|
-
1) Instead of the test tool 'example_tool', add a tool to get the current currency cross-rate.
|
|
80
|
-
Tool parameters:
|
|
81
|
-
- quoteCurrency - Currency code (ISO 4217 code Alpha-3) - required parameter
|
|
82
|
-
- baseCurrency - Currency code (ISO 4217 code Alpha-3) - optional parameter, default is USD
|
|
83
|
-
|
|
84
|
-
2) Instead of the test resource 'custom-resource://resource1', add a resource to get the list of available currencies
|
|
85
|
-
|
|
86
|
-
3) Instead of the endpoint /api/example (/example) in the file `src/api/router.ts`, create the endpoint get-curr-rate as a proxy to http://<appConfig.accessPoints.currencyService.host>:<appConfig.accessPoints.currencyService.port>/currency-service/?rate=<QUOTE_CURRENCY><BASE_CURRENCY>
|
|
87
|
-
|
|
88
|
-
4) Replace file content `src/asset/logo.svg` with
|
|
89
|
-
```
|
|
90
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
91
|
-
<path fill="currentColor"
|
|
92
|
-
d="M12 14.4q-.8 0-1.4-.6l-.3-.3H10l-1 1v.2l.3.3q.7.8 1.9 1v1l.1.2h1.4l.2-.1v-1q2-.4 2.1-2.2c0-1.8-1.5-2.3-2.5-2.6-1.3-.4-1.5-.5-1.5-1s.8-.6 1.3-.6q.7 0 1.3.4l.3.2h.3l.7-1.3v-.2l-.4-.2Q13.8 8 13 8V7l-.2-.1h-1.4l-.1.2v1q-1.9.6-2 2.2c0 1.9 1.8 2.4 2.7 2.7q1.6.4 1.4.9c0 .4-.8.5-1.2.5m10 .2-.7-.1-.7.3a8.6 8.6 0 0 1-10.9 5.6c-2.8-1-5-3.2-5.7-6l1.7.8q.5.2.8-.3l.3-.5-.3-.8-3.7-2a1 1 0 0 0-.8.4l-2 3.7.3.8.6.3q.5.2.8-.3l.7-1.3A10.4 10.4 0 0 0 17 21.5q3.8-2 5.2-6.1a1 1 0 0 0-.4-.8M24 8q0-.3-.3-.4l-.6-.3-.8.3-.7 1.3A10.4 10.4 0 0 0 7 2.7a10 10 0 0 0-5.2 6q-.2.6.4.8l.6.2q.5.1.7-.4a8.6 8.6 0 0 1 10.9-5.6 9 9 0 0 1 5.7 6.1L18.3 9l-.8.3-.3.5.3.8 3.7 2 .8-.3 2-3.8z"/>
|
|
93
|
-
</svg>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
5) Formulate the prompt AGENT_BRIEF in `src/prompts/agent-brief.ts` and AGENT_PROMPT in `src/prompts/agent-prompt.ts`
|
|
97
|
-
|
|
98
|
-
6) Instead of the test examples in `tests/mcp/test-cases.js`, write tests for our case
|
|
99
|
-
|
|
100
|
-
7) Update the README.md to reflect the new project. This README.md will be used when searching for this MCP in the RAG system.
|
|
101
|
-
Therefore, describe the essence of the tool, its features, how to install, a list of tools, resources, prompts. Briefly and to the point.
|
|
1
|
+
# Goal
|
|
2
|
+
Write the code for MCP server tools that implement retrieving the current cross-rate for a specified pair of currencies.
|
|
3
|
+
|
|
4
|
+
## Instructions
|
|
5
|
+
|
|
6
|
+
### Currency Cross-Rate API
|
|
7
|
+
|
|
8
|
+
#### Available Currencies
|
|
9
|
+
Currency codes (ISO 4217 code Alpha-3): ALL, ARS, AUD, BGN, BRL, BYN, CAD, CHF, CLP, CNY, CZK, DKK, EUR, GBP, HKD, HRK, HUF, IDR, INR, ISK, JOD, JPY, KRW, KZT, LAK, LKR, MKD, MMK, MXN, MYR, NOK, NPR, NZD, PHP, PLN, RON, RSD, RUB, SEK, SGD, THB, TRY, TWD, UAH, USD, VND, ZAR
|
|
10
|
+
|
|
11
|
+
#### Endpoint
|
|
12
|
+
|
|
13
|
+
```http request
|
|
14
|
+
GET http://<appConfig.accessPoints.currencyService.host>:<appConfig.accessPoints.currencyService.port>/currency-service/?rate=<QUOTE_CURRENCY><BASE_CURRENCY>
|
|
15
|
+
Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
|
|
20
|
+
```http request
|
|
21
|
+
GET http://smart-trade-ml.com:5001/currency-service/?rate=THBRUB
|
|
22
|
+
Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Response:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{"symbol": "THBRUB", "rate": 2.424167346170733}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Possible error codes: 400, 401, 404, 502
|
|
32
|
+
|
|
33
|
+
### Addition to config/default.yaml
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
accessPoints:
|
|
37
|
+
currencyService:
|
|
38
|
+
host: smart-trade-ml.com
|
|
39
|
+
port: 5002
|
|
40
|
+
token: '***'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Create config/local.yaml
|
|
45
|
+
|
|
46
|
+
Create a file config/local.yaml with the following content:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
---
|
|
50
|
+
accessPoints:
|
|
51
|
+
currencyService:
|
|
52
|
+
token: '88888888-4444-4444-4444-bbbbbbbbbbbb'
|
|
53
|
+
|
|
54
|
+
agentTester:
|
|
55
|
+
enabled: true
|
|
56
|
+
openAi:
|
|
57
|
+
apiKey: '<ask the user for the key>'
|
|
58
|
+
|
|
59
|
+
consul:
|
|
60
|
+
service:
|
|
61
|
+
enable: false
|
|
62
|
+
|
|
63
|
+
webServer:
|
|
64
|
+
auth:
|
|
65
|
+
enabled: true
|
|
66
|
+
jwtToken:
|
|
67
|
+
encryptKey: 'dbbe87db-90d0-4732-aae3-4089763ec392'
|
|
68
|
+
checkMCPName: true
|
|
69
|
+
isCheckIP: false
|
|
70
|
+
permanentServerTokens: ['psToken1']
|
|
71
|
+
|
|
72
|
+
adminPanel:
|
|
73
|
+
enabled: true
|
|
74
|
+
authType: 'permanentServerTokens'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
# Task
|
|
78
|
+
|
|
79
|
+
1) Instead of the test tool 'example_tool', add a tool to get the current currency cross-rate.
|
|
80
|
+
Tool parameters:
|
|
81
|
+
- quoteCurrency - Currency code (ISO 4217 code Alpha-3) - required parameter
|
|
82
|
+
- baseCurrency - Currency code (ISO 4217 code Alpha-3) - optional parameter, default is USD
|
|
83
|
+
|
|
84
|
+
2) Instead of the test resource 'custom-resource://resource1', add a resource to get the list of available currencies
|
|
85
|
+
|
|
86
|
+
3) Instead of the endpoint /api/example (/example) in the file `src/api/router.ts`, create the endpoint get-curr-rate as a proxy to http://<appConfig.accessPoints.currencyService.host>:<appConfig.accessPoints.currencyService.port>/currency-service/?rate=<QUOTE_CURRENCY><BASE_CURRENCY>
|
|
87
|
+
|
|
88
|
+
4) Replace file content `src/asset/logo.svg` with
|
|
89
|
+
```
|
|
90
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
91
|
+
<path fill="currentColor"
|
|
92
|
+
d="M12 14.4q-.8 0-1.4-.6l-.3-.3H10l-1 1v.2l.3.3q.7.8 1.9 1v1l.1.2h1.4l.2-.1v-1q2-.4 2.1-2.2c0-1.8-1.5-2.3-2.5-2.6-1.3-.4-1.5-.5-1.5-1s.8-.6 1.3-.6q.7 0 1.3.4l.3.2h.3l.7-1.3v-.2l-.4-.2Q13.8 8 13 8V7l-.2-.1h-1.4l-.1.2v1q-1.9.6-2 2.2c0 1.9 1.8 2.4 2.7 2.7q1.6.4 1.4.9c0 .4-.8.5-1.2.5m10 .2-.7-.1-.7.3a8.6 8.6 0 0 1-10.9 5.6c-2.8-1-5-3.2-5.7-6l1.7.8q.5.2.8-.3l.3-.5-.3-.8-3.7-2a1 1 0 0 0-.8.4l-2 3.7.3.8.6.3q.5.2.8-.3l.7-1.3A10.4 10.4 0 0 0 17 21.5q3.8-2 5.2-6.1a1 1 0 0 0-.4-.8M24 8q0-.3-.3-.4l-.6-.3-.8.3-.7 1.3A10.4 10.4 0 0 0 7 2.7a10 10 0 0 0-5.2 6q-.2.6.4.8l.6.2q.5.1.7-.4a8.6 8.6 0 0 1 10.9-5.6 9 9 0 0 1 5.7 6.1L18.3 9l-.8.3-.3.5.3.8 3.7 2 .8-.3 2-3.8z"/>
|
|
93
|
+
</svg>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
5) Formulate the prompt AGENT_BRIEF in `src/prompts/agent-brief.ts` and AGENT_PROMPT in `src/prompts/agent-prompt.ts`
|
|
97
|
+
|
|
98
|
+
6) Instead of the test examples in `tests/mcp/test-cases.js`, write tests for our case
|
|
99
|
+
|
|
100
|
+
7) Update the README.md to reflect the new project. This README.md will be used when searching for this MCP in the RAG system.
|
|
101
|
+
Therefore, describe the essence of the tool, its features, how to install, a list of tools, resources, prompts. Briefly and to the point.
|
|
@@ -37,7 +37,7 @@ Generates JWT tokens for MCP server authentication via `scripts/generate-jwt.js`
|
|
|
37
37
|
Generates a migration guide for upgrading the `fa-mcp-sdk` dependency in this project. Analyzes diffs in:
|
|
38
38
|
|
|
39
39
|
- `config/*.yaml` — new/removed/changed keys and defaults (correlates `default.yaml`, `_local.yaml`, `local.yaml`)
|
|
40
|
-
- `cli-template/` — `package.json` (new deps only), `tsconfig.json`,
|
|
40
|
+
- `cli-template/` — `package.json` (new deps only), `tsconfig.json`, `.oxlintrc.json`, `.oxfmtrc.json`, `CLAUDE.md`, `deploy/`,
|
|
41
41
|
`.claude/skills/`, `.run/` (from `r/`)
|
|
42
42
|
- `scripts/` — new or updated SDK utilities (excluding SDK-internal `copy-static.js`, `publish.sh`)
|
|
43
43
|
- `dist/core/index.js` — added/removed/renamed exports and breaking type changes
|
|
@@ -140,6 +140,91 @@ Characteristics:
|
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
|
143
|
+
### `/mcp-app-create` — Scaffold a New MCP App
|
|
144
|
+
|
|
145
|
+
Comprehensive guidance for building **MCP Apps** — interactive UIs that render inside MCP-enabled hosts (Claude
|
|
146
|
+
Desktop, etc.) using the [`@modelcontextprotocol/ext-apps`](https://github.com/modelcontextprotocol/ext-apps) SDK.
|
|
147
|
+
Every MCP App pairs an MCP **tool** (called by the LLM/host) with an HTML **resource** (the UI shown to the user);
|
|
148
|
+
the tool's `_meta.ui.resourceUri` links them.
|
|
149
|
+
|
|
150
|
+
What it does:
|
|
151
|
+
|
|
152
|
+
- Clones the upstream `ext-apps` repo into `./mcp-ext-apps/` (added to `.gitignore`) for working examples,
|
|
153
|
+
JSDoc-annotated source, and the formal protocol spec (`specification/2026-01-26/apps.mdx`, SEP-1865)
|
|
154
|
+
- Walks through framework selection — React (with `useApp` hook), Vanilla JS, Vue, Svelte, Preact, Solid —
|
|
155
|
+
using the matching `basic-server-{framework}/` template as a reference
|
|
156
|
+
- Sets up the build pipeline: `vite` + `vite-plugin-singlefile` to bundle UI into a single HTML file, plus
|
|
157
|
+
`tsx` for running the TypeScript server (broader compatibility than `bun`)
|
|
158
|
+
- Generates `registerAppTool` + `registerAppResource` calls with the correct `_meta.ui.resourceUri` linking
|
|
159
|
+
- Implements lifecycle handlers (`ontoolinput`, `ontoolresult`, `onhostcontextchanged`, `onteardown`)
|
|
160
|
+
— emphasising they MUST be registered BEFORE `app.connect()`
|
|
161
|
+
- Covers advanced patterns (`docs/patterns.md`): app-only tools, polling, chunked responses, binary resources,
|
|
162
|
+
CSP/CORS, host context (theme/styles/fonts), fullscreen mode, streaming input, view state, visibility-pause
|
|
163
|
+
|
|
164
|
+
Characteristics:
|
|
165
|
+
|
|
166
|
+
- **Launch**: by command `/mcp-app-create` or by trigger phrases ("create an MCP App", "add a UI to an MCP tool",
|
|
167
|
+
"build an interactive MCP View", "scaffold an MCP App")
|
|
168
|
+
- **Input**: project context (existing server vs new server) + UI requirements
|
|
169
|
+
- **Output**: working tool + resource pair, single-file HTML bundle, framework-specific entry point with
|
|
170
|
+
registered handlers, `vite.config.ts`, updated `package.json` scripts
|
|
171
|
+
|
|
172
|
+
**Examples:**
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
/mcp-app-create
|
|
176
|
+
/mcp-app-create create an MCP App that shows search results as an interactive table (React)
|
|
177
|
+
/mcp-app-create scaffold a new MCP server with a map UI tool, vanilla JS
|
|
178
|
+
/mcp-app-create build a system-monitor App with a polling chart, use Vue
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### `/mcp-app-add-to-server` — Add Interactive UI to Existing MCP Server
|
|
184
|
+
|
|
185
|
+
Analyses the tools already exposed by an existing MCP server and enriches the ones that benefit from UI with
|
|
186
|
+
inline rendering via the MCP Apps SDK. Tools that don't need UI stay untouched; the text fallback is preserved
|
|
187
|
+
for text-only clients, so adding UI is a strict enhancement.
|
|
188
|
+
|
|
189
|
+
What it does:
|
|
190
|
+
|
|
191
|
+
- **Inventories** the server's existing tools (reads source, lists every registered tool)
|
|
192
|
+
- **Classifies** each tool by UI benefit using a decision framework: structured data / metrics over time /
|
|
193
|
+
media → high benefit; simple confirmations → text-only is fine; data feeds for other tools → app-only helper
|
|
194
|
+
- **Confirms** the analysis with the user before writing code
|
|
195
|
+
- Adds `@modelcontextprotocol/ext-apps` + `vite` + `vite-plugin-singlefile` (plus framework deps if needed)
|
|
196
|
+
via `npm install` — never hardcoded versions
|
|
197
|
+
- Configures the build pipeline (`vite.config.ts`, `mcp-app.html` entry, `package.json` scripts: `build:ui`,
|
|
198
|
+
`build:server`, `build`, `serve`) and links resources to tools via `_meta.ui.resourceUri`
|
|
199
|
+
- Converts plain `server.tool(...)` calls to `registerAppTool(...)` with `structuredContent` for the UI
|
|
200
|
+
while keeping the `content` array as a text fallback
|
|
201
|
+
- Registers HTML resources via `registerAppResource(...)` reading the bundled `dist/mcp-app.html`
|
|
202
|
+
- Wires UI lifecycle handlers + applies host styling (`applyDocumentTheme`, `applyHostStyleVariables`,
|
|
203
|
+
`applyHostFonts`, safe-area insets)
|
|
204
|
+
- Optional enhancements: app-only helper tools (`visibility: ["app"]`), CSP/CORS allow-lists
|
|
205
|
+
(`connectDomains` / `resourceDomains` / `frameDomains`), streaming partial input (`ontoolinputpartial`),
|
|
206
|
+
fullscreen mode (`requestDisplayMode`), graceful degradation via `getUiCapability()`
|
|
207
|
+
|
|
208
|
+
Characteristics:
|
|
209
|
+
|
|
210
|
+
- **Launch**: by command `/mcp-app-add-to-server` or by trigger phrases ("add an app to my MCP server",
|
|
211
|
+
"add UI to my MCP server", "add a view to my MCP tool", "enrich MCP tools with UI", "add MCP Apps to
|
|
212
|
+
my server")
|
|
213
|
+
- **Input**: none required — reads the project; user confirms which tools to enhance after the analysis
|
|
214
|
+
- **Output**: refactored `server.ts` (App tools + plain tools coexist), HTML entry + `vite.config.ts`,
|
|
215
|
+
resource registration code, lifecycle handlers in the UI entry, updated `package.json` scripts
|
|
216
|
+
|
|
217
|
+
**Examples:**
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
/mcp-app-add-to-server
|
|
221
|
+
/mcp-app-add-to-server add UI to the search and analytics tools, leave the lookup tools as text-only
|
|
222
|
+
/mcp-app-add-to-server обогати UI инструмент get_dashboard, остальные оставь без изменений
|
|
223
|
+
/mcp-app-add-to-server add an interactive map view to the geo-search tool
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
143
228
|
### `/create-mcp-wizard` — End-to-End MCP Server Implementation
|
|
144
229
|
|
|
145
230
|
Orchestrates the full implementation workflow from feature brief to a live GitLab repo. The project
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ES2022",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"lib": ["ES2022"],
|
|
7
|
-
"outDir": "./dist",
|
|
8
|
-
"rootDir": "./",
|
|
9
|
-
"baseUrl": "./",
|
|
10
|
-
"ignoreDeprecations": "6.0",
|
|
11
|
-
"strict": true,
|
|
12
|
-
"esModuleInterop": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"forceConsistentCasingInFileNames": true,
|
|
15
|
-
"declaration": true,
|
|
16
|
-
"declarationMap": true,
|
|
17
|
-
"sourceMap": true,
|
|
18
|
-
"removeComments": false,
|
|
19
|
-
"noImplicitAny": true,
|
|
20
|
-
"noImplicitReturns": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true,
|
|
22
|
-
"noUncheckedIndexedAccess": true,
|
|
23
|
-
"exactOptionalPropertyTypes": true,
|
|
24
|
-
"noImplicitOverride": true,
|
|
25
|
-
"allowSyntheticDefaultImports": true,
|
|
26
|
-
"resolveJsonModule": true,
|
|
27
|
-
"isolatedModules": true,
|
|
28
|
-
"experimentalDecorators": true,
|
|
29
|
-
"emitDecoratorMetadata": true
|
|
30
|
-
},
|
|
31
|
-
"include": [
|
|
32
|
-
"src/**/*",
|
|
33
|
-
"tests/**/*"
|
|
34
|
-
],
|
|
35
|
-
"exclude": [
|
|
36
|
-
".claude",
|
|
37
|
-
".idea",
|
|
38
|
-
".junie",
|
|
39
|
-
".playwright-mcp",
|
|
40
|
-
".run",
|
|
41
|
-
".serena",
|
|
42
|
-
"_misc",
|
|
43
|
-
"_tmp",
|
|
44
|
-
"config",
|
|
45
|
-
"out",
|
|
46
|
-
"deploy",
|
|
47
|
-
"dist",
|
|
48
|
-
"doc",
|
|
49
|
-
"docs",
|
|
50
|
-
"node_modules",
|
|
51
|
-
"out",
|
|
52
|
-
"coverage",
|
|
53
|
-
"swagger"
|
|
54
|
-
],
|
|
55
|
-
"ts-node": {
|
|
56
|
-
"esm": true
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./",
|
|
9
|
+
"baseUrl": "./",
|
|
10
|
+
"ignoreDeprecations": "6.0",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"declaration": true,
|
|
16
|
+
"declarationMap": true,
|
|
17
|
+
"sourceMap": true,
|
|
18
|
+
"removeComments": false,
|
|
19
|
+
"noImplicitAny": true,
|
|
20
|
+
"noImplicitReturns": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedIndexedAccess": true,
|
|
23
|
+
"exactOptionalPropertyTypes": true,
|
|
24
|
+
"noImplicitOverride": true,
|
|
25
|
+
"allowSyntheticDefaultImports": true,
|
|
26
|
+
"resolveJsonModule": true,
|
|
27
|
+
"isolatedModules": true,
|
|
28
|
+
"experimentalDecorators": true,
|
|
29
|
+
"emitDecoratorMetadata": true
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"src/**/*",
|
|
33
|
+
"tests/**/*"
|
|
34
|
+
],
|
|
35
|
+
"exclude": [
|
|
36
|
+
".claude",
|
|
37
|
+
".idea",
|
|
38
|
+
".junie",
|
|
39
|
+
".playwright-mcp",
|
|
40
|
+
".run",
|
|
41
|
+
".serena",
|
|
42
|
+
"_misc",
|
|
43
|
+
"_tmp",
|
|
44
|
+
"config",
|
|
45
|
+
"out",
|
|
46
|
+
"deploy",
|
|
47
|
+
"dist",
|
|
48
|
+
"doc",
|
|
49
|
+
"docs",
|
|
50
|
+
"node_modules",
|
|
51
|
+
"out",
|
|
52
|
+
"coverage",
|
|
53
|
+
"swagger"
|
|
54
|
+
],
|
|
55
|
+
"ts-node": {
|
|
56
|
+
"esm": true
|
|
57
|
+
}
|
|
58
|
+
}
|
package/cli-template/update.cjs
CHANGED
|
@@ -142,10 +142,11 @@ const logTryUpdate = (updateReason = '') => {
|
|
|
142
142
|
/**
|
|
143
143
|
* Execute command in NVM environment
|
|
144
144
|
*/
|
|
145
|
-
function execCommand
|
|
145
|
+
function execCommand(command, options = {}, withSetupScript = false) {
|
|
146
146
|
// If we have NVM setup, wrap the command
|
|
147
|
-
const fullCommand =
|
|
147
|
+
const fullCommand = setupScript && withSetupScript ? `${setupScript} && ${command}` : command;
|
|
148
148
|
try {
|
|
149
|
+
// noinspection UnnecessaryLocalVariableJS
|
|
149
150
|
const result = execSync(fullCommand, {
|
|
150
151
|
encoding: 'utf8',
|
|
151
152
|
stdio: options.silent ? 'inherit' : 'pipe',
|
|
@@ -158,14 +159,14 @@ function execCommand (command, options = {}, withSetupScript = false) {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
function execWithNODE
|
|
162
|
+
function execWithNODE(command, options = {}) {
|
|
162
163
|
return execCommand(command, options, true);
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
/**
|
|
166
167
|
* Load NVM environment and get Node.js version
|
|
167
168
|
*/
|
|
168
|
-
function loadNVMEnvironment
|
|
169
|
+
function loadNVMEnvironment() {
|
|
169
170
|
try {
|
|
170
171
|
if (fs.existsSync('.envrc')) {
|
|
171
172
|
const envrcContent = fs.readFileSync('.envrc', 'utf8');
|
|
@@ -187,7 +188,7 @@ function loadNVMEnvironment () {
|
|
|
187
188
|
/**
|
|
188
189
|
* Parse command line arguments
|
|
189
190
|
*/
|
|
190
|
-
function parseArgs
|
|
191
|
+
function parseArgs() {
|
|
191
192
|
const pArgs = process.argv.slice(2);
|
|
192
193
|
const args = {
|
|
193
194
|
expectedBranch: null,
|
|
@@ -219,7 +220,7 @@ function parseArgs () {
|
|
|
219
220
|
/**
|
|
220
221
|
* Show help information
|
|
221
222
|
*/
|
|
222
|
-
function showHelp
|
|
223
|
+
function showHelp() {
|
|
223
224
|
console.log(`
|
|
224
225
|
================================================================================
|
|
225
226
|
Project update and rebuild
|
|
@@ -244,7 +245,7 @@ function showHelp () {
|
|
|
244
245
|
/**
|
|
245
246
|
* Parse simple YAML content (key: value format)
|
|
246
247
|
*/
|
|
247
|
-
function parseSimpleYAML
|
|
248
|
+
function parseSimpleYAML(content) {
|
|
248
249
|
const config = {};
|
|
249
250
|
const lines = content.split('\n');
|
|
250
251
|
|
|
@@ -272,7 +273,7 @@ function parseSimpleYAML (content) {
|
|
|
272
273
|
/**
|
|
273
274
|
* Load configuration from YAML file
|
|
274
275
|
*/
|
|
275
|
-
function loadConfig
|
|
276
|
+
function loadConfig() {
|
|
276
277
|
// Load NVM environment from .envrc
|
|
277
278
|
loadNVMEnvironment();
|
|
278
279
|
|
|
@@ -301,7 +302,7 @@ function loadConfig () {
|
|
|
301
302
|
/**
|
|
302
303
|
* Get service name from package.json and .env
|
|
303
304
|
*/
|
|
304
|
-
function getServiceName
|
|
305
|
+
function getServiceName() {
|
|
305
306
|
let serviceName = '';
|
|
306
307
|
let serviceInstance = '';
|
|
307
308
|
try {
|
|
@@ -334,7 +335,7 @@ function getServiceName () {
|
|
|
334
335
|
/**
|
|
335
336
|
* Check if systemctl service exists
|
|
336
337
|
*/
|
|
337
|
-
function systemctlServiceExists
|
|
338
|
+
function systemctlServiceExists(serviceName) {
|
|
338
339
|
try {
|
|
339
340
|
execCommand(`systemctl list-unit-files "${serviceName}.service"`);
|
|
340
341
|
return true;
|
|
@@ -343,7 +344,7 @@ function systemctlServiceExists (serviceName) {
|
|
|
343
344
|
}
|
|
344
345
|
}
|
|
345
346
|
|
|
346
|
-
function pm2ServiceExists
|
|
347
|
+
function pm2ServiceExists(serviceName) {
|
|
347
348
|
try {
|
|
348
349
|
const res = execCommand(`pm2 id "${serviceName}"`);
|
|
349
350
|
return /\[\s*\d\s*]/.test(res);
|
|
@@ -355,7 +356,7 @@ function pm2ServiceExists (serviceName) {
|
|
|
355
356
|
/**
|
|
356
357
|
* Get git repository information
|
|
357
358
|
*/
|
|
358
|
-
function getRepoInfo
|
|
359
|
+
function getRepoInfo() {
|
|
359
360
|
try {
|
|
360
361
|
const branch = execCommand('git rev-parse --abbrev-ref HEAD').trim();
|
|
361
362
|
const headHash = execCommand('git rev-parse HEAD').trim();
|
|
@@ -376,27 +377,26 @@ function getRepoInfo () {
|
|
|
376
377
|
upstreamHash,
|
|
377
378
|
};
|
|
378
379
|
} catch (error) {
|
|
379
|
-
const message = String(error.message).includes(error.stderr)
|
|
380
|
-
? error.message
|
|
381
|
-
: [error.stderr, error.message].join('\n');
|
|
380
|
+
const message = String(error.message).includes(error.stderr) ? error.message : [error.stderr, error.message].join('\n');
|
|
382
381
|
|
|
383
382
|
console.error('Error getting repo info:', message);
|
|
384
383
|
return null;
|
|
385
384
|
}
|
|
386
385
|
}
|
|
387
386
|
|
|
388
|
-
const colorizeHTML = (text) =>
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
387
|
+
const colorizeHTML = (text) =>
|
|
388
|
+
text
|
|
389
|
+
.replace(/<red>/g, '<span style="color:#ff0000;">')
|
|
390
|
+
.replace(/<\/red>/g, '</span>')
|
|
391
|
+
.replace(/<y>/g, '<span style="background-color:#ffff00;">')
|
|
392
|
+
.replace(/<\/y>/g, '</span>')
|
|
393
|
+
.replace(/<g>/g, '<span style="background-color:#00ff00;">')
|
|
394
|
+
.replace(/<\/g>/g, '</span>')
|
|
395
|
+
.replace(/<r>/g, '<span style="background-color:#ff0000; color:#ffffff;">')
|
|
396
|
+
.replace(/<\/r>/g, '</span>')
|
|
397
|
+
.replace(/\[ERROR]/g, '<span style="color:#ffffff; background-color: #ff0000">[ERROR]</span>');
|
|
398
|
+
|
|
399
|
+
async function sendBuildNotification(emails, status, body, serviceName) {
|
|
400
400
|
if (!emails) {
|
|
401
401
|
return;
|
|
402
402
|
}
|
|
@@ -423,7 +423,10 @@ ${colorizeHTML(clearColors(body))}
|
|
|
423
423
|
</pre></body></html>`;
|
|
424
424
|
|
|
425
425
|
// Send to each email address
|
|
426
|
-
const emailArray = emails
|
|
426
|
+
const emailArray = emails
|
|
427
|
+
.split(',')
|
|
428
|
+
.map((email) => email.trim())
|
|
429
|
+
.filter((email) => email);
|
|
427
430
|
|
|
428
431
|
for (let i = 0; i < emailArray.length; i++) {
|
|
429
432
|
const emailAddress = emailArray[i];
|
|
@@ -507,7 +510,7 @@ const restartService = (serviceNamePM) => {
|
|
|
507
510
|
/**
|
|
508
511
|
* Main update function
|
|
509
512
|
*/
|
|
510
|
-
async function main
|
|
513
|
+
async function main() {
|
|
511
514
|
logTryUpdate();
|
|
512
515
|
fs.writeFileSync(runTimeLogFile, '');
|
|
513
516
|
const args = parseArgs();
|
|
@@ -603,9 +606,7 @@ async function main () {
|
|
|
603
606
|
logIt('No changes detected. Update skipped.');
|
|
604
607
|
}
|
|
605
608
|
} catch (err) {
|
|
606
|
-
const message = String(err.message).includes(err.stderr)
|
|
607
|
-
? err.message
|
|
608
|
-
: [err.stderr, err.message].join('\n');
|
|
609
|
+
const message = String(err.message).includes(err.stderr) ? err.message : [err.stderr, err.message].join('\n');
|
|
609
610
|
logError(message);
|
|
610
611
|
if (config.email) {
|
|
611
612
|
await sendBuildNotification(config.email, 'FAIL', logBuffer, serviceName);
|
|
@@ -630,9 +631,11 @@ process.on('SIGTERM', () => {
|
|
|
630
631
|
process.exit(1);
|
|
631
632
|
});
|
|
632
633
|
|
|
633
|
-
main()
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
634
|
+
main()
|
|
635
|
+
.then(() => {
|
|
636
|
+
process.exit(0);
|
|
637
|
+
})
|
|
638
|
+
.catch((error) => {
|
|
639
|
+
console.error('Update failed:', error.message);
|
|
640
|
+
process.exit(1);
|
|
641
|
+
});
|