fa-mcp-sdk 0.4.69 → 0.4.71
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/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/SKILL.md +45 -13
- package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/headless-test.js +2 -2
- package/cli-template/.claude/skills/upgrade-guide/SKILL.md +10 -5
- package/cli-template/gitignore +1 -0
- package/cli-template/package.json +2 -2
- package/cli-template/r/{update-doc.js.xml → update-sdk.js.xml} +5 -5
- package/cli-template/readme-docs/SKILLS.md +10 -5
- package/config/_local.yaml +20 -18
- package/config/local.yaml +3 -4
- package/package.json +1 -1
- package/scripts/update-sdk.js +111 -0
- package/scripts/update-doc.js +0 -36
- /package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/check-openai.js +0 -0
- /package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/gen-secrets.js +0 -0
- /package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/gitlab-push.js +0 -0
- /package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/headless-chat.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: "Implement an fa-mcp MCP server end-to-end in this already-scaffolded project: verify Agent Tester OpenAI creds, seed dev-time secrets and lenient config, push the scaffold to GitLab (creating a new repo OR reusing an existing one when instructed), draft an implementation plan, implement tools/prompts/resources, iterate via the Agent Tester headless API, then push the finished work. Use when the user asks to develop/implement/deploy the MCP server in this project, mentions '
|
|
2
|
+
name: create-mcp-wizard
|
|
3
|
+
description: "Implement an fa-mcp MCP server end-to-end in this already-scaffolded project: verify Agent Tester OpenAI creds, seed dev-time secrets and lenient config, push the scaffold to GitLab (creating a new repo OR reusing an existing one when instructed), draft an implementation plan, implement tools/prompts/resources, iterate via the Agent Tester headless API, then push the finished work. Use when the user asks to develop/implement/deploy the MCP server in this project, mentions 'create-mcp-wizard', 'развернуть MCP', 'реализовать MCP', or supplies a feature brief."
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
allowed-tools: Bash(node *), Bash(yarn *), Bash(npm *), Bash(git *), Bash(pwd), Bash(cd *), Bash(curl *), Read, Write, Edit, Glob, Grep
|
|
6
6
|
---
|
|
@@ -34,6 +34,13 @@ All supporting scripts live in `${CLAUDE_SKILL_DIR}/scripts/` and are invoked wi
|
|
|
34
34
|
by the CLI / skill infrastructure and by the SDK maintainer. Do NOT modify, add, or delete files
|
|
35
35
|
inside them unless the accompanying text explicitly instructs you to. This applies to every step
|
|
36
36
|
below — implementation, tests, dev report, everything.
|
|
37
|
+
- **Reporting language**. Language for all generated artifacts (`claudedocs/*.md`, commit
|
|
38
|
+
messages, user-facing summaries) is resolved in this order:
|
|
39
|
+
1. Explicit directive in the feature brief.
|
|
40
|
+
2. Else, contents of `preferred-language.txt` in the project root, if it exists.
|
|
41
|
+
3. Else — English.
|
|
42
|
+
Translate prose — headings and body text — to the resolved language; leave code, paths, YAML
|
|
43
|
+
keys, and CLI commands as-is. Report the resolved language and its source in the Step 1 summary.
|
|
37
44
|
|
|
38
45
|
## Step 1 — Scan the accompanying text for requirements
|
|
39
46
|
|
|
@@ -50,8 +57,10 @@ Before touching code, read every message/file the user attached and extract:
|
|
|
50
57
|
- **Agent Tester OpenAI creds** — `apiKey` (required for Step 2) and `baseURL` (optional — Azure /
|
|
51
58
|
proxy / local LLM). If the text already supplies them, use those. If `config/local.yaml` already
|
|
52
59
|
has a working `agentTester.openAi.apiKey`, re-use it instead of asking again.
|
|
60
|
+
- **Reporting language** — resolve per the Ground rule above; record it for later steps.
|
|
53
61
|
|
|
54
|
-
Summarize what you found to the user in 3-6 bullets
|
|
62
|
+
Summarize what you found to the user in 3-6 bullets (including the resolved reporting language
|
|
63
|
+
and its source) and get a one-line confirmation before proceeding.
|
|
55
64
|
|
|
56
65
|
## Step 2 — Verify Agent Tester OpenAI credentials
|
|
57
66
|
|
|
@@ -128,7 +137,7 @@ what belongs in the initial commit. If the tree contains scratch notes, local-on
|
|
|
128
137
|
anything the user flagged as not-for-commit, stash it with an untracked-inclusive stash:
|
|
129
138
|
|
|
130
139
|
```
|
|
131
|
-
git stash push -u -m "
|
|
140
|
+
git stash push -u -m "create-mcp-wizard: pre-initial-push stash" -- <paths>
|
|
132
141
|
```
|
|
133
142
|
|
|
134
143
|
Announce what you stashed so the user can recover it later via `git stash list` / `git stash pop`.
|
|
@@ -205,7 +214,8 @@ OR switch to branch 4a if the "collision" is in fact the already-existing target
|
|
|
205
214
|
|
|
206
215
|
## Step 6 — Draft and commit to a plan
|
|
207
216
|
|
|
208
|
-
Create `claudedocs/impl-plan.md` (create the directory if needed).
|
|
217
|
+
Create `claudedocs/impl-plan.md` (create the directory if needed) in the reporting language.
|
|
218
|
+
Structure:
|
|
209
219
|
|
|
210
220
|
```markdown
|
|
211
221
|
# Implementation Plan — <project name>
|
|
@@ -245,7 +255,9 @@ Create `claudedocs/impl-plan.md` (create the directory if needed). Structure:
|
|
|
245
255
|
- [ ] `yarn typecheck` clean
|
|
246
256
|
- [ ] `yarn test:mcp`, `:mcp-http`, `:mcp-sse` all green
|
|
247
257
|
- [ ] Agent Tester iterations done, `claudedocs/test-log.md` has entries
|
|
248
|
-
- [ ] `claudedocs/dev-report.md` written
|
|
258
|
+
- [ ] `claudedocs/dev-report.md` written (full report)
|
|
259
|
+
- [ ] `claudedocs/breef-report.md` written (brief of work + problems — same content echoed to console)
|
|
260
|
+
- [ ] `claudedocs/dev-problems.md` written (blockers, failed checks, open questions)
|
|
249
261
|
- [ ] Final GitLab push (Step 10) complete
|
|
250
262
|
```
|
|
251
263
|
|
|
@@ -353,8 +365,9 @@ agent prompt, handler logic, error message — per `FA-MCP-SDK-DOC/08-agent-test
|
|
|
353
365
|
fix, rebuild (`yarn cb`), restart, and re-run the scenario. After restart, in-memory sessions on
|
|
354
366
|
the server are wiped — delete the stale `claudedocs/.agent-session` file before re-running.
|
|
355
367
|
|
|
356
|
-
Log every iteration in `claudedocs/test-log.md` (session header +
|
|
357
|
-
received / tools used / result / diagnosis / fix). This is the
|
|
368
|
+
Log every iteration in `claudedocs/test-log.md` in the reporting language (session header +
|
|
369
|
+
per-scenario: sent / expected / received / tools used / result / diagnosis / fix). This is the
|
|
370
|
+
audit trail.
|
|
358
371
|
|
|
359
372
|
Stop the server with `node scripts/kill-port.js <port>` (or Ctrl+C) when you're done iterating.
|
|
360
373
|
|
|
@@ -373,9 +386,22 @@ yarn test:mcp-sse
|
|
|
373
386
|
|
|
374
387
|
Zero errors, zero warnings that matter, all transport tests green.
|
|
375
388
|
|
|
376
|
-
Write `claudedocs/dev-report.md`
|
|
377
|
-
(what was built, architecture decisions, agent prompt rationale,
|
|
378
|
-
configuration, known limitations).
|
|
389
|
+
Write `claudedocs/dev-report.md` in the reporting language, following the structure in
|
|
390
|
+
`CLAUDE.md` → "Development Report" (what was built, architecture decisions, agent prompt rationale,
|
|
391
|
+
test coverage, Agent Tester findings, configuration, known limitations).
|
|
392
|
+
|
|
393
|
+
Alongside the full report, produce two companion files in the reporting language:
|
|
394
|
+
|
|
395
|
+
- **`claudedocs/breef-report.md`** — a brief of the work done and problems encountered. Keep it
|
|
396
|
+
short and scannable (not a duplicate of `dev-report.md`): what was implemented, what passed,
|
|
397
|
+
what failed, the key problems in 1–2 lines each. The same content is echoed verbatim to the
|
|
398
|
+
console as part of the "Final report" step below — that is the primary way the user sees it.
|
|
399
|
+
- **`claudedocs/dev-problems.md`** — a focused list of what could NOT be done / tested / connected
|
|
400
|
+
to during this session, plus any open questions, unresolved blockers, or decisions the user
|
|
401
|
+
needs to make. Include: failed external connections (DB, upstream API, AD, Consul, etc.),
|
|
402
|
+
tests that were skipped or disabled and why, missing creds, ambiguous requirements from the
|
|
403
|
+
brief, anything deferred. If there are no problems, write the file anyway with a single
|
|
404
|
+
"No outstanding issues." line so the user can see the check was done.
|
|
379
405
|
|
|
380
406
|
## Step 10 — Final GitLab push
|
|
381
407
|
|
|
@@ -386,7 +412,7 @@ implemented feature and pushes it on top of the scaffold commit.
|
|
|
386
412
|
content that shouldn't ship to the remote, stash it first:
|
|
387
413
|
|
|
388
414
|
```
|
|
389
|
-
git stash push -u -m "
|
|
415
|
+
git stash push -u -m "create-mcp-wizard: pre-final-push stash" -- <paths>
|
|
390
416
|
```
|
|
391
417
|
|
|
392
418
|
Leave anything stashed from Step 5 still stashed — if it shouldn't be in the initial commit, it
|
|
@@ -423,8 +449,14 @@ Tell the user:
|
|
|
423
449
|
(Step 5) and the feature push (Step 10) landed on `main`.
|
|
424
450
|
3. Summary of tools/resources/prompts/endpoints that were implemented.
|
|
425
451
|
4. Any flagged limitations from the dev report.
|
|
426
|
-
5.
|
|
452
|
+
5. Links to `claudedocs/impl-plan.md`, `claudedocs/test-log.md`, `claudedocs/dev-report.md`,
|
|
453
|
+
`claudedocs/breef-report.md`, `claudedocs/dev-problems.md`.
|
|
427
454
|
6. Anything still stashed from Step 5 / Step 10 (so the user remembers to `git stash pop` or drop).
|
|
455
|
+
7. **Echo the full contents of `claudedocs/breef-report.md` to the console** (in the reporting
|
|
456
|
+
language, as written). This is the brief of work done + problems — it must appear inline in
|
|
457
|
+
the chat, not only as a file link, so the user can read it without opening the file. If
|
|
458
|
+
`claudedocs/dev-problems.md` contains anything other than "No outstanding issues.", also call
|
|
459
|
+
that out explicitly and point at the file.
|
|
428
460
|
|
|
429
461
|
## Troubleshooting
|
|
430
462
|
|
package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/headless-test.js
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Thin wrapper around POST /agent-tester/api/chat/test — used by the
|
|
3
|
+
* Thin wrapper around POST /agent-tester/api/chat/test — used by the create-mcp-wizard skill
|
|
4
4
|
* to exercise the freshly-built MCP server through the full agent loop.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
@@ -107,4 +107,4 @@ const req = http.request({
|
|
|
107
107
|
req.on('error', (e) => { console.error(`request error: ${e.message}`); process.exit(1); });
|
|
108
108
|
req.on('timeout', () => { req.destroy(new Error('timeout')); });
|
|
109
109
|
req.write(payload);
|
|
110
|
-
req.end();
|
|
110
|
+
req.end();
|
|
@@ -110,10 +110,15 @@ Wait for completion. If it fails, report the error and stop.
|
|
|
110
110
|
|
|
111
111
|
Run:
|
|
112
112
|
```bash
|
|
113
|
-
node ./node_modules/fa-mcp-sdk/scripts/update-
|
|
113
|
+
node ./node_modules/fa-mcp-sdk/scripts/update-sdk.js
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
This copies the latest `FA-MCP-SDK-DOC/` from the SDK into the project.
|
|
116
|
+
This copies the latest `FA-MCP-SDK-DOC/` and `.claude/` from the SDK into the project.
|
|
117
|
+
|
|
118
|
+
**Pinned folders.** Any folder under the project's `.claude/` that contains a direct file named
|
|
119
|
+
`pin` is preserved as-is — the script neither deletes it nor overwrites it with template content.
|
|
120
|
+
Drop a `pin` file into `.claude/skills/<your-skill>/` (or any other `.claude/` subdirectory) to
|
|
121
|
+
protect local customizations from being reset on upgrade.
|
|
117
122
|
|
|
118
123
|
## Step 4: Analyze Changes in SDK Between Versions
|
|
119
124
|
|
|
@@ -187,7 +192,7 @@ Map of template file → project file (the CLI `bin/fa-mcp.js` applies these tra
|
|
|
187
192
|
| `node_modules/fa-mcp-sdk/cli-template/.claude/skills/<skill>/` | `.claude/skills/<skill>/` | overwrite unless locally customized |
|
|
188
193
|
| `node_modules/fa-mcp-sdk/cli-template/r/<name>.xml` | `.run/<name>.run.xml` | **Renamed** — see rule below |
|
|
189
194
|
| `node_modules/fa-mcp-sdk/cli-template/gitignore` | `.gitignore` | source has no leading dot |
|
|
190
|
-
| `node_modules/fa-mcp-sdk/cli-template/FA-MCP-SDK-DOC/` | `FA-MCP-SDK-DOC/` | auto-updated by `update-
|
|
195
|
+
| `node_modules/fa-mcp-sdk/cli-template/FA-MCP-SDK-DOC/` | `FA-MCP-SDK-DOC/` | auto-updated by `update-sdk.js` |
|
|
191
196
|
|
|
192
197
|
#### Rule: package.json — ADD ONLY new dependencies, do NOT touch anything else
|
|
193
198
|
|
|
@@ -286,7 +291,7 @@ Generated: <timestamp>
|
|
|
286
291
|
### New Configuration Keys
|
|
287
292
|
|
|
288
293
|
<For each new key, provide:>
|
|
289
|
-
- Key path (e.g., `webServer.
|
|
294
|
+
- Key path (e.g., `webServer.auth.enabled`)
|
|
290
295
|
- Default value
|
|
291
296
|
- Description
|
|
292
297
|
- Whether it needs to be added to the project's config
|
|
@@ -403,7 +408,7 @@ changes specifically affect THIS project. Add a section to the guide:
|
|
|
403
408
|
- When comparing YAML configs, preserve comments and structure.
|
|
404
409
|
- **Correlate config file changes**: when `config/default.yaml` changes, ALWAYS also check `config/_local.yaml` in the SDK. Report whether `_local.yaml` has analogous changes or needs manual updates. Also advise checking the project's `config/local.yaml` for stale overrides that may conflict with the new defaults.
|
|
405
410
|
- **Do not forget `config/local.yaml` in the project**: the project's `config/local.yaml` overrides `config/default.yaml`. When new keys are added or sections restructured in `default.yaml`, explicitly instruct the user to verify that their `config/local.yaml` doesn't have stale overrides that conflict with the new structure, and to add any new keys there too if they want non-default values.
|
|
406
|
-
- Do not modify project files other than `package.json` (via yarn add) and `FA-MCP-SDK-DOC/` (via update-
|
|
411
|
+
- Do not modify project files other than `package.json` (via yarn add) and `FA-MCP-SDK-DOC/` (via update-sdk.js) unless the user explicitly asks.
|
|
407
412
|
- The migration guide must contain ACTIONABLE instructions with exact code/config snippets — not vague recommendations.
|
|
408
413
|
- If GitHub API is unavailable or rate-limited, fall back to comparing files directly from `node_modules/fa-mcp-sdk/` against project files.
|
|
409
414
|
- Write the guide in the language detected from the user's arguments (default: **English**). Translate all headings, prose, and descriptions. Keep file paths, YAML keys, code blocks, and shell commands in English.
|
package/cli-template/gitignore
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"generate-token": "node node_modules/fa-mcp-sdk/dist/core/auth/token-generator/server.js",
|
|
23
23
|
"dead:exports": "ts-prune",
|
|
24
24
|
"dead:files": "knip",
|
|
25
|
-
"update-sdk-docs": "node ../scripts/update-
|
|
25
|
+
"update-sdk-docs": "node ../scripts/update-sdk.js",
|
|
26
26
|
"postinstall": "node ../scripts/npm/patch_node_modules.js",
|
|
27
27
|
"check-llm": "node node_modules/fa-mcp-sdk/dist/core/agent-tester/check-llm.js",
|
|
28
28
|
"consul:unreg": "node node_modules/fa-mcp-sdk/dist/core/consul/deregister.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
52
52
|
"dotenv": "^17.4.1",
|
|
53
|
-
"fa-mcp-sdk": "^0.4.
|
|
53
|
+
"fa-mcp-sdk": "^0.4.71"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/express": "^5.0.6",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration default="false" name="update-
|
|
3
|
-
<method v="2" />
|
|
4
|
-
</configuration>
|
|
5
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="update-sdk.js" type="NodeJSConfigurationType" nameIsGenerated="true" path-to-js-file="scripts/update-sdk.js" working-dir="$PROJECT_DIR$">
|
|
3
|
+
<method v="2" />
|
|
4
|
+
</configuration>
|
|
5
|
+
</component>
|
|
@@ -140,7 +140,7 @@ Characteristics:
|
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
|
143
|
-
### `/
|
|
143
|
+
### `/create-mcp-wizard` — End-to-End MCP Server Implementation
|
|
144
144
|
|
|
145
145
|
Orchestrates the full implementation workflow from feature brief to a live GitLab repo. The project
|
|
146
146
|
must already be scaffolded by the `fa-mcp` CLI — this skill picks up from `yarn install` onwards.
|
|
@@ -169,20 +169,25 @@ Pipeline (10 steps):
|
|
|
169
169
|
|
|
170
170
|
Characteristics:
|
|
171
171
|
|
|
172
|
-
- **Launch**: **command-only** via `/
|
|
172
|
+
- **Launch**: **command-only** via `/create-mcp-wizard`. `disable-model-invocation: true` — does NOT
|
|
173
173
|
trigger on implicit mentions
|
|
174
174
|
- **Input**: feature brief comes from the accompanying user message(s) and attached files. OpenAI
|
|
175
175
|
and GitLab creds may be supplied inline or asked interactively
|
|
176
176
|
- **Ground rules**: every step explicit and verified; free-form inputs asked in plain prose (never
|
|
177
177
|
predefined options); exclusions from the brief honoured; dev defaults intentionally lenient;
|
|
178
178
|
`.claude/`, `deploy/`, `FA-MCP-SDK-DOC/` are NOT modified unless the brief explicitly says to
|
|
179
|
+
- **Reporting language**: all generated artifacts (`claudedocs/*.md`, commit messages, user-facing
|
|
180
|
+
summaries) are written in a language resolved in this order: (1) explicit directive in the
|
|
181
|
+
feature brief, else (2) contents of `preferred-language.txt` in the project root, else
|
|
182
|
+
(3) English. Prose (headings + body) is translated; code, paths, YAML keys, and CLI commands
|
|
183
|
+
stay as-is
|
|
179
184
|
- **Output**: implemented project + `claudedocs/{impl-plan,test-log,dev-report}.md`, GitLab repo
|
|
180
185
|
with two commits on `main` (scaffold + feature)
|
|
181
186
|
|
|
182
187
|
**Examples:**
|
|
183
188
|
|
|
184
189
|
```
|
|
185
|
-
/
|
|
186
|
-
/
|
|
187
|
-
/
|
|
190
|
+
/create-mcp-wizard
|
|
191
|
+
/create-mcp-wizard реализуй инструменты из task.md, OpenAI key sk-..., GitLab group mcp-servers
|
|
192
|
+
/create-mcp-wizard implement tools from the message; repo уже существует, push to git@gitlab.example:ai/mcp-foo.git
|
|
188
193
|
```
|
package/config/_local.yaml
CHANGED
|
@@ -24,6 +24,26 @@
|
|
|
24
24
|
# #> Override the Consul service name to look up (defaults to the alias key)
|
|
25
25
|
# consulServiceName: <consulServiceName>
|
|
26
26
|
|
|
27
|
+
#> ========================================================================
|
|
28
|
+
#> ADMIN PANEL
|
|
29
|
+
#> Token generation & validation UI served at /admin.
|
|
30
|
+
#> Supports 4 authentication methods: permanentServerTokens, basic, jwtToken, ntlm.
|
|
31
|
+
#> ========================================================================
|
|
32
|
+
adminPanel:
|
|
33
|
+
#> Enable/disable admin panel. false — /admin is not mounted at all.
|
|
34
|
+
enabled: true
|
|
35
|
+
#> Authentication type: 'permanentServerTokens' | 'basic' | 'jwtToken' | 'ntlm' | 'none'
|
|
36
|
+
#> Accepts a single type (string) or multiple types (array):
|
|
37
|
+
#> authType: 'basic'
|
|
38
|
+
#> authType: ['jwtToken', 'basic']
|
|
39
|
+
#> 'none' / null / empty array / not set → panel opens WITHOUT authentication
|
|
40
|
+
#> (convenience for local development and debugging; do NOT use in production).
|
|
41
|
+
#> For permanentServerTokens, basic, jwtToken — uses credentials from webServer.auth section.
|
|
42
|
+
#> For ntlm — uses AD configuration from ad.domains section.
|
|
43
|
+
#> When multiple types are set (e.g. ['jwtToken', 'basic']), the login page shows tabs
|
|
44
|
+
#> to choose between Token and Login (username/password) authentication.
|
|
45
|
+
authType: 'basic'
|
|
46
|
+
|
|
27
47
|
#> Active Directory / LDAP settings.
|
|
28
48
|
#> Used for authentication/authorization (e.g., NTLM in admin panel) and checking user membership in AD groups.
|
|
29
49
|
ad:
|
|
@@ -325,21 +345,3 @@ webServer:
|
|
|
325
345
|
#> Requires valid Authorization header (any method configured in webServer.auth).
|
|
326
346
|
#> ========================================================================
|
|
327
347
|
genJwtApiEnable: false
|
|
328
|
-
|
|
329
|
-
#> ========================================================================
|
|
330
|
-
#> ADMIN PANEL AUTHENTICATION
|
|
331
|
-
#> Token generation page available at /admin endpoint
|
|
332
|
-
#> Supports 4 authentication methods: permanentServerTokens, basic, jwtToken, ntlm
|
|
333
|
-
#> ========================================================================
|
|
334
|
-
adminAuth:
|
|
335
|
-
#> Enable/disable admin panel
|
|
336
|
-
enabled: true
|
|
337
|
-
#> Authentication type for admin panel: 'permanentServerTokens' | 'basic' | 'jwtToken' | 'ntlm'
|
|
338
|
-
#> Accepts a single type (string) or multiple types (array):
|
|
339
|
-
#> type: 'basic'
|
|
340
|
-
#> type: ['jwtToken', 'basic']
|
|
341
|
-
#> For permanentServerTokens, basic, jwtToken — uses credentials from webServer.auth section
|
|
342
|
-
#> For ntlm — uses AD configuration from ad.domains section (no additional credentials needed)
|
|
343
|
-
#> When multiple types are set (e.g. ['jwtToken', 'basic']), the login page shows tabs
|
|
344
|
-
#> to choose between Token and Login (username/password) authentication.
|
|
345
|
-
type: 'basic'
|
package/config/local.yaml
CHANGED
|
@@ -11,6 +11,9 @@ agentTester:
|
|
|
11
11
|
baseURL: https://litellm.finam.ru/v1
|
|
12
12
|
exposeToClient: true
|
|
13
13
|
|
|
14
|
+
adminPanel:
|
|
15
|
+
enabled: true
|
|
16
|
+
authType: [ 'permanentServerTokens', 'basic', 'jwtToken' ]
|
|
14
17
|
|
|
15
18
|
ad:
|
|
16
19
|
domains:
|
|
@@ -104,7 +107,3 @@ webServer:
|
|
|
104
107
|
|
|
105
108
|
|
|
106
109
|
genJwtApiEnable: false
|
|
107
|
-
adminAuth:
|
|
108
|
-
enabled: true
|
|
109
|
-
# 'permanentServerTokens' | 'basic' | 'jwtToken' | 'ntlm'
|
|
110
|
-
type: [ 'permanentServerTokens', 'basic', 'jwtToken' ]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fa-mcp-sdk",
|
|
3
3
|
"productName": "FA MCP SDK",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.71",
|
|
5
5
|
"description": "Core infrastructure and templates for building Model Context Protocol (MCP) servers with TypeScript",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/core/index.js",
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'fs';
|
|
3
|
+
import { basename, dirname, join, relative, sep } from 'path';
|
|
4
|
+
|
|
5
|
+
const templateDir = join(process.cwd(), './node_modules/fa-mcp-sdk/cli-template');
|
|
6
|
+
const cwd = process.cwd();
|
|
7
|
+
|
|
8
|
+
const targets = [
|
|
9
|
+
{ name: 'FA-MCP-SDK-DOC', src: join(templateDir, 'FA-MCP-SDK-DOC'), dest: join(cwd, 'FA-MCP-SDK-DOC') },
|
|
10
|
+
{
|
|
11
|
+
name: '.claude',
|
|
12
|
+
src: join(templateDir, '.claude'),
|
|
13
|
+
dest: join(cwd, '.claude'),
|
|
14
|
+
preserve: ['settings.json'],
|
|
15
|
+
respectPin: true,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
// A folder containing a direct file named `pin` is preserved untouched —
|
|
20
|
+
// it is neither deleted nor overwritten with new content from the template.
|
|
21
|
+
function findPinnedFolders (rootDir) {
|
|
22
|
+
const pinned = new Set();
|
|
23
|
+
if (!existsSync(rootDir)) {return pinned;}
|
|
24
|
+
const walk = (currentDir) => {
|
|
25
|
+
const entries = readdirSync(currentDir, { withFileTypes: true });
|
|
26
|
+
if (entries.some((e) => e.isFile() && e.name === 'pin')) {
|
|
27
|
+
const rel = relative(rootDir, currentDir);
|
|
28
|
+
if (rel) {pinned.add(rel);}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.isDirectory()) {walk(join(currentDir, entry.name));}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
walk(rootDir);
|
|
36
|
+
return pinned;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isInsidePinned (relPath, pinned) {
|
|
40
|
+
if (!relPath) {return false;}
|
|
41
|
+
if (pinned.has(relPath)) {return true;}
|
|
42
|
+
for (const p of pinned) {
|
|
43
|
+
if (relPath.startsWith(p + sep)) {return true;}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function cleanExceptPinned (rootDir, pinned) {
|
|
49
|
+
if (!existsSync(rootDir)) {return;}
|
|
50
|
+
const walk = (currentDir) => {
|
|
51
|
+
const entries = readdirSync(currentDir, { withFileTypes: true });
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const full = join(currentDir, entry.name);
|
|
54
|
+
const fullRel = relative(rootDir, full);
|
|
55
|
+
if (pinned.has(fullRel)) {continue;}
|
|
56
|
+
const hasPinnedDescendant = [...pinned].some((p) => p.startsWith(fullRel + sep));
|
|
57
|
+
if (entry.isDirectory() && hasPinnedDescendant) {
|
|
58
|
+
walk(full);
|
|
59
|
+
} else {
|
|
60
|
+
rmSync(full, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
walk(rootDir);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for (const { name, src, dest, preserve = [], respectPin = false } of targets) {
|
|
68
|
+
if (!existsSync(src)) {
|
|
69
|
+
console.error('Source not found:', src);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const saved = {};
|
|
73
|
+
for (const file of preserve) {
|
|
74
|
+
const p = join(dest, file);
|
|
75
|
+
if (existsSync(p)) {saved[file] = readFileSync(p);}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const pinned = respectPin ? findPinnedFolders(dest) : new Set();
|
|
79
|
+
|
|
80
|
+
if (existsSync(dest)) {
|
|
81
|
+
if (pinned.size > 0) {
|
|
82
|
+
cleanExceptPinned(dest, pinned);
|
|
83
|
+
} else {
|
|
84
|
+
rmSync(dest, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
cpSync(src, dest, {
|
|
89
|
+
recursive: true,
|
|
90
|
+
filter: (srcPath) => {
|
|
91
|
+
if (preserve.includes(basename(srcPath))) {return false;}
|
|
92
|
+
if (respectPin && pinned.size > 0) {
|
|
93
|
+
const rel = relative(src, srcPath);
|
|
94
|
+
if (isInsidePinned(rel, pinned)) {return false;}
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
for (const [file, content] of Object.entries(saved)) {
|
|
101
|
+
const p = join(dest, file);
|
|
102
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
103
|
+
writeFileSync(p, content);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (pinned.size > 0) {
|
|
107
|
+
console.log(`${name} updated (pinned folders preserved: ${[...pinned].join(', ')})`);
|
|
108
|
+
} else {
|
|
109
|
+
console.log(`${name} updated`);
|
|
110
|
+
}
|
|
111
|
+
}
|
package/scripts/update-doc.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
3
|
-
import { basename, dirname, join } from 'path';
|
|
4
|
-
|
|
5
|
-
const templateDir = join(process.cwd(), './node_modules/fa-mcp-sdk/cli-template');
|
|
6
|
-
const cwd = process.cwd();
|
|
7
|
-
|
|
8
|
-
const targets = [
|
|
9
|
-
{ name: 'FA-MCP-SDK-DOC', src: join(templateDir, 'FA-MCP-SDK-DOC'), dest: join(cwd, 'FA-MCP-SDK-DOC') },
|
|
10
|
-
{ name: '.claude', src: join(templateDir, '.claude'), dest: join(cwd, '.claude'), preserve: ['settings.json'] },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
for (const { name, src, dest, preserve = [] } of targets) {
|
|
14
|
-
if (!existsSync(src)) {
|
|
15
|
-
console.error('Source not found:', src);
|
|
16
|
-
process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
const saved = {};
|
|
19
|
-
for (const file of preserve) {
|
|
20
|
-
const p = join(dest, file);
|
|
21
|
-
if (existsSync(p)) saved[file] = readFileSync(p);
|
|
22
|
-
}
|
|
23
|
-
if (existsSync(dest)) {
|
|
24
|
-
rmSync(dest, { recursive: true });
|
|
25
|
-
}
|
|
26
|
-
cpSync(src, dest, {
|
|
27
|
-
recursive: true,
|
|
28
|
-
filter: (srcPath) => !preserve.includes(basename(srcPath)),
|
|
29
|
-
});
|
|
30
|
-
for (const [file, content] of Object.entries(saved)) {
|
|
31
|
-
const p = join(dest, file);
|
|
32
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
33
|
-
writeFileSync(p, content);
|
|
34
|
-
}
|
|
35
|
-
console.log(`${name} updated`);
|
|
36
|
-
}
|
/package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/check-openai.js
RENAMED
|
File without changes
|
/package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/gen-secrets.js
RENAMED
|
File without changes
|
/package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/gitlab-push.js
RENAMED
|
File without changes
|
/package/cli-template/.claude/skills/{deploy-mcp → create-mcp-wizard}/scripts/headless-chat.js
RENAMED
|
File without changes
|