simple-dynamsoft-mcp 7.2.9 → 7.3.0
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 +3 -2
- package/data/metadata/data-manifest.json +40 -0
- package/package.json +1 -1
- package/src/data/repo-map.js +42 -2
- package/src/server/create-server.js +6 -1
- package/src/server/normalizers.js +8 -14
- package/src/server/public-offerings.js +71 -0
- package/src/server/resource-index/builders.js +384 -20
- package/src/server/resource-index/config.js +14 -0
- package/src/server/resource-index/paths.js +4 -0
- package/src/server/resource-index/samples.js +148 -1
- package/src/server/resource-index/uri.js +12 -0
- package/src/server/resource-index/version-policy.js +13 -5
- package/src/server/resource-index.js +60 -2
- package/src/server/resources/register-resources.js +1 -1
- package/src/server/tools/public-routing.js +75 -0
- package/src/server/tools/register-index-tools.js +33 -14
- package/src/server/tools/register-project-tools.js +100 -27
- package/src/server/tools/register-quickstart-tools.js +103 -14
- package/src/server/tools/register-sample-tools.js +12 -3
- package/src/server/tools/register-version-tools.js +51 -43
|
@@ -18,12 +18,16 @@ let cachedWebFrameworkPlatforms = null;
|
|
|
18
18
|
let cachedDbrWebFrameworkPlatforms = null;
|
|
19
19
|
let cachedDdvWebFrameworkPlatforms = null;
|
|
20
20
|
let cachedDcvWebFrameworkPlatforms = null;
|
|
21
|
+
let cachedMrzWebFrameworkPlatforms = null;
|
|
22
|
+
let cachedMdsWebFrameworkPlatforms = null;
|
|
21
23
|
|
|
22
24
|
function resetSampleDiscoveryCaches() {
|
|
23
25
|
cachedWebFrameworkPlatforms = null;
|
|
24
26
|
cachedDbrWebFrameworkPlatforms = null;
|
|
25
27
|
cachedDdvWebFrameworkPlatforms = null;
|
|
26
28
|
cachedDcvWebFrameworkPlatforms = null;
|
|
29
|
+
cachedMrzWebFrameworkPlatforms = null;
|
|
30
|
+
cachedMdsWebFrameworkPlatforms = null;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
function getCodeFileExtensions() {
|
|
@@ -46,6 +50,10 @@ function getDbrWebSamplesRoot() {
|
|
|
46
50
|
return getExistingPath(join(SAMPLE_ROOTS.dbrWeb, "web"), SAMPLE_ROOTS.dbrWeb);
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
function getDedicatedWebSamplesRoot(root) {
|
|
54
|
+
return getExistingPath(join(root, "samples"), root);
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
function getDbrCrossMobileRoot(platform) {
|
|
50
58
|
if (platform === "maui") return SAMPLE_ROOTS.dbrMaui;
|
|
51
59
|
if (platform === "react-native") return SAMPLE_ROOTS.dbrReactNative;
|
|
@@ -291,6 +299,63 @@ function discoverWebSamples() {
|
|
|
291
299
|
return categories;
|
|
292
300
|
}
|
|
293
301
|
|
|
302
|
+
function discoverDedicatedWebSamples(root) {
|
|
303
|
+
const categories = { root: [] };
|
|
304
|
+
const webPath = getDedicatedWebSamplesRoot(root);
|
|
305
|
+
if (!webPath || !existsSync(webPath)) return categories;
|
|
306
|
+
|
|
307
|
+
for (const entry of readdirSync(webPath, { withFileTypes: true })) {
|
|
308
|
+
if (entry.name.startsWith(".")) continue;
|
|
309
|
+
|
|
310
|
+
if (entry.isFile() && entry.name.endsWith(".html")) {
|
|
311
|
+
if (entry.name !== "index.html") {
|
|
312
|
+
categories.root.push(entry.name.replace(".html", ""));
|
|
313
|
+
}
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (!entry.isDirectory()) continue;
|
|
318
|
+
|
|
319
|
+
const categoryPath = join(webPath, entry.name);
|
|
320
|
+
|
|
321
|
+
if (entry.name === "frameworks" || entry.name === "scenarios") {
|
|
322
|
+
const categorySamples = [];
|
|
323
|
+
for (const child of readdirSync(categoryPath, { withFileTypes: true })) {
|
|
324
|
+
if (child.name.startsWith(".")) continue;
|
|
325
|
+
if (child.isDirectory()) categorySamples.push(child.name);
|
|
326
|
+
else if (child.isFile() && child.name.endsWith(".html") && child.name !== "index.html") {
|
|
327
|
+
categorySamples.push(child.name.replace(".html", ""));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
categories[entry.name] = sortUnique(categorySamples);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (existsSync(join(categoryPath, "index.html")) || existsSync(join(categoryPath, "README.md"))) {
|
|
336
|
+
categories.root.push(entry.name);
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const categorySamples = [];
|
|
341
|
+
for (const child of readdirSync(categoryPath, { withFileTypes: true })) {
|
|
342
|
+
if (child.name.startsWith(".")) continue;
|
|
343
|
+
if (child.isDirectory()) categorySamples.push(child.name);
|
|
344
|
+
else if (child.isFile() && child.name.endsWith(".html") && child.name !== "index.html") {
|
|
345
|
+
categorySamples.push(child.name.replace(".html", ""));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
categories[entry.name] = sortUnique(categorySamples);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
for (const [key, value] of Object.entries(categories)) {
|
|
353
|
+
if (value.length === 0) delete categories[key];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return categories;
|
|
357
|
+
}
|
|
358
|
+
|
|
294
359
|
function getWebSamplePath(category, sampleName) {
|
|
295
360
|
const webPath = getDbrWebSamplesRoot();
|
|
296
361
|
if (!webPath || !existsSync(webPath)) return null;
|
|
@@ -316,6 +381,44 @@ function getWebSamplePath(category, sampleName) {
|
|
|
316
381
|
return null;
|
|
317
382
|
}
|
|
318
383
|
|
|
384
|
+
function getDedicatedWebSamplePath(root, category, sampleName) {
|
|
385
|
+
const webPath = getDedicatedWebSamplesRoot(root);
|
|
386
|
+
if (!webPath || !existsSync(webPath)) return null;
|
|
387
|
+
|
|
388
|
+
if (category === "root" || !category) {
|
|
389
|
+
const htmlPath = join(webPath, `${sampleName}.html`);
|
|
390
|
+
if (existsSync(htmlPath)) return htmlPath;
|
|
391
|
+
|
|
392
|
+
const dirPath = join(webPath, sampleName);
|
|
393
|
+
if (existsSync(dirPath) && statSync(dirPath).isDirectory()) {
|
|
394
|
+
const indexPath = join(dirPath, "index.html");
|
|
395
|
+
if (existsSync(indexPath)) return indexPath;
|
|
396
|
+
const readmePath = join(dirPath, "README.md");
|
|
397
|
+
if (existsSync(readmePath)) return readmePath;
|
|
398
|
+
return dirPath;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const dirPath = join(webPath, category, sampleName);
|
|
405
|
+
if (existsSync(dirPath) && statSync(dirPath).isDirectory()) {
|
|
406
|
+
return dirPath;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const htmlPath = join(webPath, category, `${sampleName}.html`);
|
|
410
|
+
if (existsSync(htmlPath)) return htmlPath;
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function discoverMrzWebSamples() {
|
|
415
|
+
return discoverDedicatedWebSamples(SAMPLE_ROOTS.mrzWeb);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function discoverMdsWebSamples() {
|
|
419
|
+
return discoverDedicatedWebSamples(SAMPLE_ROOTS.mdsWeb);
|
|
420
|
+
}
|
|
421
|
+
|
|
319
422
|
function discoverDwtSamples() {
|
|
320
423
|
const categories = {};
|
|
321
424
|
if (!existsSync(SAMPLE_ROOTS.dwt)) return categories;
|
|
@@ -388,12 +491,42 @@ function getDdvWebFrameworkPlatforms() {
|
|
|
388
491
|
return cachedDdvWebFrameworkPlatforms;
|
|
389
492
|
}
|
|
390
493
|
|
|
494
|
+
function getMrzWebFrameworkPlatforms() {
|
|
495
|
+
if (cachedMrzWebFrameworkPlatforms) return cachedMrzWebFrameworkPlatforms;
|
|
496
|
+
const frameworks = new Set();
|
|
497
|
+
const webSamples = discoverMrzWebSamples();
|
|
498
|
+
if (webSamples.frameworks) {
|
|
499
|
+
for (const name of webSamples.frameworks) {
|
|
500
|
+
const normalized = normalizePlatform(name);
|
|
501
|
+
if (normalized && normalized !== "web") frameworks.add(normalized);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
cachedMrzWebFrameworkPlatforms = Array.from(frameworks).sort();
|
|
505
|
+
return cachedMrzWebFrameworkPlatforms;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function getMdsWebFrameworkPlatforms() {
|
|
509
|
+
if (cachedMdsWebFrameworkPlatforms) return cachedMdsWebFrameworkPlatforms;
|
|
510
|
+
const frameworks = new Set();
|
|
511
|
+
const webSamples = discoverMdsWebSamples();
|
|
512
|
+
if (webSamples.frameworks) {
|
|
513
|
+
for (const name of webSamples.frameworks) {
|
|
514
|
+
const normalized = normalizePlatform(name);
|
|
515
|
+
if (normalized && normalized !== "web") frameworks.add(normalized);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
cachedMdsWebFrameworkPlatforms = Array.from(frameworks).sort();
|
|
519
|
+
return cachedMdsWebFrameworkPlatforms;
|
|
520
|
+
}
|
|
521
|
+
|
|
391
522
|
function getWebFrameworkPlatforms() {
|
|
392
523
|
if (cachedWebFrameworkPlatforms) return cachedWebFrameworkPlatforms;
|
|
393
524
|
const frameworks = new Set([
|
|
394
525
|
...getDbrWebFrameworkPlatforms(),
|
|
395
526
|
...getDdvWebFrameworkPlatforms(),
|
|
396
|
-
...getDcvWebFrameworkPlatforms()
|
|
527
|
+
...getDcvWebFrameworkPlatforms(),
|
|
528
|
+
...getMrzWebFrameworkPlatforms(),
|
|
529
|
+
...getMdsWebFrameworkPlatforms()
|
|
397
530
|
]);
|
|
398
531
|
cachedWebFrameworkPlatforms = frameworks;
|
|
399
532
|
return cachedWebFrameworkPlatforms;
|
|
@@ -575,6 +708,14 @@ function getDcvWebSamplePath(sampleName) {
|
|
|
575
708
|
return null;
|
|
576
709
|
}
|
|
577
710
|
|
|
711
|
+
function getMrzWebSamplePath(category, sampleName) {
|
|
712
|
+
return getDedicatedWebSamplePath(SAMPLE_ROOTS.mrzWeb, category, sampleName);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function getMdsWebSamplePath(category, sampleName) {
|
|
716
|
+
return getDedicatedWebSamplePath(SAMPLE_ROOTS.mdsWeb, category, sampleName);
|
|
717
|
+
}
|
|
718
|
+
|
|
578
719
|
function readCodeFile(filePath) {
|
|
579
720
|
if (!existsSync(filePath)) return null;
|
|
580
721
|
return readFileSync(filePath, "utf8");
|
|
@@ -701,6 +842,8 @@ export {
|
|
|
701
842
|
discoverDcvServerSamples,
|
|
702
843
|
discoverDcvWebSamples,
|
|
703
844
|
discoverWebSamples,
|
|
845
|
+
discoverMrzWebSamples,
|
|
846
|
+
discoverMdsWebSamples,
|
|
704
847
|
getWebSamplePath,
|
|
705
848
|
discoverDwtSamples,
|
|
706
849
|
discoverDdvSamples,
|
|
@@ -708,6 +851,8 @@ export {
|
|
|
708
851
|
getDbrWebFrameworkPlatforms,
|
|
709
852
|
getDcvWebFrameworkPlatforms,
|
|
710
853
|
getDdvWebFrameworkPlatforms,
|
|
854
|
+
getMrzWebFrameworkPlatforms,
|
|
855
|
+
getMdsWebFrameworkPlatforms,
|
|
711
856
|
getWebFrameworkPlatforms,
|
|
712
857
|
findCodeFilesInSample,
|
|
713
858
|
getDbrMobilePlatforms,
|
|
@@ -720,6 +865,8 @@ export {
|
|
|
720
865
|
getDcvMobileSamplePath,
|
|
721
866
|
getDcvServerSamplePath,
|
|
722
867
|
getDcvWebSamplePath,
|
|
868
|
+
getMrzWebSamplePath,
|
|
869
|
+
getMdsWebSamplePath,
|
|
723
870
|
getDwtSamplePath,
|
|
724
871
|
getDdvSamplePath,
|
|
725
872
|
readCodeFile,
|
|
@@ -70,6 +70,18 @@ function parseSampleUri(uri) {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
if ((parsed.product === "mrz" || parsed.product === "mds") && (parsed.edition === "mobile" || parsed.edition === "server" || parsed.edition === "web")) {
|
|
74
|
+
const isStructuredWebSample = parsed.edition === "web" && parsed.parts.length >= 6;
|
|
75
|
+
return {
|
|
76
|
+
product: parsed.product,
|
|
77
|
+
edition: parsed.edition,
|
|
78
|
+
platform: parsed.platform,
|
|
79
|
+
version: parsed.version,
|
|
80
|
+
category: isStructuredWebSample ? parsed.parts[4] : undefined,
|
|
81
|
+
sampleName: isStructuredWebSample ? parsed.parts[5] : parsed.parts[4]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
73
85
|
if (parsed.product === "dcv" && (parsed.edition === "mobile" || parsed.edition === "server" || parsed.edition === "web")) {
|
|
74
86
|
return {
|
|
75
87
|
product: "dcv",
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { LEGACY_DBR_LINKS, LEGACY_DWT_LINKS } from "./config.js";
|
|
2
2
|
import { inferProductFromQuery, normalizeEdition, normalizePlatform } from "../normalizers.js";
|
|
3
3
|
|
|
4
|
+
const VERSION_FAMILY_BY_PRODUCT = {
|
|
5
|
+
mrz: "dcv",
|
|
6
|
+
mds: "dcv"
|
|
7
|
+
};
|
|
8
|
+
|
|
4
9
|
function parseMajorVersion(version) {
|
|
5
10
|
if (!version) return null;
|
|
6
11
|
const match = String(version).match(/(\d+)/);
|
|
@@ -69,7 +74,8 @@ function ensureLatestMajor({ product, version, query, edition, platform, latestM
|
|
|
69
74
|
const inferredProduct = product || inferProductFromQuery(query);
|
|
70
75
|
if (!inferredProduct) return { ok: true };
|
|
71
76
|
|
|
72
|
-
const
|
|
77
|
+
const versionFamily = VERSION_FAMILY_BY_PRODUCT[inferredProduct] || inferredProduct;
|
|
78
|
+
const currentMajor = latestMajor[versionFamily];
|
|
73
79
|
const requestedMajor = parseMajorVersion(version) ?? detectMajorFromQuery(query);
|
|
74
80
|
|
|
75
81
|
if (!requestedMajor || requestedMajor === currentMajor) {
|
|
@@ -83,10 +89,11 @@ function ensureLatestMajor({ product, version, query, edition, platform, latestM
|
|
|
83
89
|
};
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
if (
|
|
92
|
+
if (versionFamily === "dcv") {
|
|
93
|
+
const offeringName = inferredProduct === "dcv" ? "DCV" : inferredProduct.toUpperCase();
|
|
87
94
|
return {
|
|
88
95
|
ok: false,
|
|
89
|
-
message: `This MCP server only serves the latest major version of DCV
|
|
96
|
+
message: `This MCP server only serves the latest major version of ${offeringName} (DCV-backed, v${currentMajor}).`
|
|
90
97
|
};
|
|
91
98
|
}
|
|
92
99
|
|
|
@@ -140,13 +147,14 @@ function buildVersionPolicyText(latestMajor) {
|
|
|
140
147
|
"This MCP server only serves the latest major versions of each product.",
|
|
141
148
|
"",
|
|
142
149
|
`- DBR latest major: v${latestMajor.dbr}`,
|
|
143
|
-
`-
|
|
150
|
+
`- MRZ latest major: v${latestMajor.dcv} (DCV-backed)`,
|
|
151
|
+
`- MDS latest major: v${latestMajor.dcv} (DCV-backed)`,
|
|
144
152
|
`- DWT latest major: v${latestMajor.dwt}`,
|
|
145
153
|
`- DDV latest major: v${latestMajor.ddv}`,
|
|
146
154
|
"",
|
|
147
155
|
"Legacy support:",
|
|
148
156
|
"- DBR v9 and v10 docs are linked when requested.",
|
|
149
|
-
"-
|
|
157
|
+
"- MRZ and MDS do not publish separate legacy archive links; they follow the latest DCV-backed major only.",
|
|
150
158
|
`- DWT archived docs available: ${dwtLegacyVersions || "none"}.`,
|
|
151
159
|
"- DDV has no legacy archive links in this server.",
|
|
152
160
|
"",
|
|
@@ -32,14 +32,20 @@ import {
|
|
|
32
32
|
discoverDcvMobileSamples,
|
|
33
33
|
discoverDcvServerSamples,
|
|
34
34
|
discoverDcvWebSamples,
|
|
35
|
+
discoverMrzWebSamples,
|
|
36
|
+
discoverMdsWebSamples,
|
|
35
37
|
discoverWebSamples,
|
|
36
38
|
getWebSamplePath,
|
|
39
|
+
getMrzWebSamplePath,
|
|
40
|
+
getMdsWebSamplePath,
|
|
37
41
|
discoverDwtSamples,
|
|
38
42
|
discoverDdvSamples,
|
|
39
43
|
mapDdvSampleToFramework,
|
|
40
44
|
getDbrWebFrameworkPlatforms,
|
|
41
45
|
getDcvWebFrameworkPlatforms,
|
|
42
46
|
getDdvWebFrameworkPlatforms,
|
|
47
|
+
getMrzWebFrameworkPlatforms,
|
|
48
|
+
getMdsWebFrameworkPlatforms,
|
|
43
49
|
getWebFrameworkPlatforms,
|
|
44
50
|
findCodeFilesInSample,
|
|
45
51
|
getDbrMobilePlatforms,
|
|
@@ -137,6 +143,8 @@ let dbrMobileDocs = [];
|
|
|
137
143
|
let dbrServerDocs = [];
|
|
138
144
|
let dcvCoreDocs = [];
|
|
139
145
|
let dcvWebDocs = [];
|
|
146
|
+
let mrzWebDocs = [];
|
|
147
|
+
let mdsWebDocs = [];
|
|
140
148
|
let dcvMobileDocs = [];
|
|
141
149
|
let dcvServerDocs = [];
|
|
142
150
|
let dwtDocs = { articles: [] };
|
|
@@ -198,6 +206,28 @@ function loadDocumentationSets() {
|
|
|
198
206
|
() => "web"
|
|
199
207
|
);
|
|
200
208
|
|
|
209
|
+
mrzWebDocs = withEditionScope(
|
|
210
|
+
loadMarkdownDocs({
|
|
211
|
+
rootDir: DOC_ROOTS.mrzWeb,
|
|
212
|
+
urlBase: DOCS_CONFIG.mrzWeb.urlBase,
|
|
213
|
+
excludeDirs: DOCS_CONFIG.mrzWeb.excludeDirs,
|
|
214
|
+
excludeFiles: DOCS_CONFIG.mrzWeb.excludeFiles
|
|
215
|
+
}).articles,
|
|
216
|
+
"web",
|
|
217
|
+
() => "web"
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
mdsWebDocs = withEditionScope(
|
|
221
|
+
loadMarkdownDocs({
|
|
222
|
+
rootDir: DOC_ROOTS.mdsWeb,
|
|
223
|
+
urlBase: DOCS_CONFIG.mdsWeb.urlBase,
|
|
224
|
+
excludeDirs: DOCS_CONFIG.mdsWeb.excludeDirs,
|
|
225
|
+
excludeFiles: DOCS_CONFIG.mdsWeb.excludeFiles
|
|
226
|
+
}).articles,
|
|
227
|
+
"web",
|
|
228
|
+
() => "web"
|
|
229
|
+
);
|
|
230
|
+
|
|
201
231
|
dcvMobileDocs = withEditionScope(
|
|
202
232
|
loadMarkdownDocs({
|
|
203
233
|
rootDir: DOC_ROOTS.dcvMobile,
|
|
@@ -292,6 +322,8 @@ function buildIndexData() {
|
|
|
292
322
|
LATEST_MAJOR,
|
|
293
323
|
dcvCoreDocs,
|
|
294
324
|
dcvWebDocs,
|
|
325
|
+
mrzWebDocs,
|
|
326
|
+
mdsWebDocs,
|
|
295
327
|
dcvMobileDocs,
|
|
296
328
|
dcvServerDocs,
|
|
297
329
|
dbrWebDocs,
|
|
@@ -301,6 +333,10 @@ function buildIndexData() {
|
|
|
301
333
|
ddvDocs,
|
|
302
334
|
discoverDcvWebSamples,
|
|
303
335
|
getDcvWebFrameworkPlatforms,
|
|
336
|
+
discoverMrzWebSamples,
|
|
337
|
+
getMrzWebFrameworkPlatforms,
|
|
338
|
+
discoverMdsWebSamples,
|
|
339
|
+
getMdsWebFrameworkPlatforms,
|
|
304
340
|
getDcvMobilePlatforms,
|
|
305
341
|
getDcvServerPlatforms,
|
|
306
342
|
discoverDcvMobileSamples,
|
|
@@ -313,7 +349,8 @@ function buildIndexData() {
|
|
|
313
349
|
discoverDbrServerSamples,
|
|
314
350
|
discoverDwtSamples,
|
|
315
351
|
discoverDdvSamples,
|
|
316
|
-
getDdvWebFrameworkPlatforms
|
|
352
|
+
getDdvWebFrameworkPlatforms,
|
|
353
|
+
resourceIndex
|
|
317
354
|
});
|
|
318
355
|
}
|
|
319
356
|
|
|
@@ -326,6 +363,8 @@ function buildResourceIndex() {
|
|
|
326
363
|
LATEST_MAJOR,
|
|
327
364
|
dcvCoreDocs,
|
|
328
365
|
dcvWebDocs,
|
|
366
|
+
mrzWebDocs,
|
|
367
|
+
mdsWebDocs,
|
|
329
368
|
dcvMobileDocs,
|
|
330
369
|
dcvServerDocs,
|
|
331
370
|
dbrWebDocs,
|
|
@@ -341,6 +380,10 @@ function buildResourceIndex() {
|
|
|
341
380
|
getDcvServerSampleContent,
|
|
342
381
|
discoverDcvWebSamples,
|
|
343
382
|
getDcvWebSamplePath,
|
|
383
|
+
discoverMrzWebSamples,
|
|
384
|
+
getMrzWebSamplePath,
|
|
385
|
+
discoverMdsWebSamples,
|
|
386
|
+
getMdsWebSamplePath,
|
|
344
387
|
discoverMobileSamples,
|
|
345
388
|
getDbrMobilePlatforms,
|
|
346
389
|
getMobileSamplePath,
|
|
@@ -393,9 +436,12 @@ function platformMatches(normalizedPlatform, entry) {
|
|
|
393
436
|
if (normalizedPlatform === entry.platform) return true;
|
|
394
437
|
if (normalizedPlatform === "web") return entry.platform === "web";
|
|
395
438
|
if (isWebFrameworkPlatform(normalizedPlatform)) {
|
|
439
|
+
const aliases = WEB_FRAMEWORK_TAG_ALIASES[normalizedPlatform] || [normalizedPlatform];
|
|
440
|
+
if (aliases.includes(entry.platform)) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
396
443
|
if (entry.platform === "web" && Array.isArray(entry.tags)) {
|
|
397
444
|
const tags = entry.tags.map((tag) => String(tag).toLowerCase());
|
|
398
|
-
const aliases = WEB_FRAMEWORK_TAG_ALIASES[normalizedPlatform] || [normalizedPlatform];
|
|
399
445
|
return aliases.some((alias) => tags.includes(alias));
|
|
400
446
|
}
|
|
401
447
|
return entry.platform === normalizedPlatform;
|
|
@@ -499,6 +545,8 @@ function getRagSignatureData() {
|
|
|
499
545
|
resourceCount: resourceIndex.length,
|
|
500
546
|
dcvCoreDocCount: dcvCoreDocs.length,
|
|
501
547
|
dcvWebDocCount: dcvWebDocs.length,
|
|
548
|
+
mrzWebDocCount: mrzWebDocs.length,
|
|
549
|
+
mdsWebDocCount: mdsWebDocs.length,
|
|
502
550
|
dcvMobileDocCount: dcvMobileDocs.length,
|
|
503
551
|
dcvServerDocCount: dcvServerDocs.length,
|
|
504
552
|
dbrWebDocCount: dbrWebDocs.length,
|
|
@@ -519,6 +567,8 @@ function getRagSignatureData() {
|
|
|
519
567
|
dbrFlutterSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dbrFlutter),
|
|
520
568
|
dbrNodejsSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dbrNodejs),
|
|
521
569
|
dcvWebSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dcvWeb),
|
|
570
|
+
mrzWebSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.mrzWeb),
|
|
571
|
+
mdsWebSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.mdsWeb),
|
|
522
572
|
dcvMobileSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dcvMobile),
|
|
523
573
|
dcvPythonSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dcvPython),
|
|
524
574
|
dcvDotnetSamplesHead: readManifestRepoCommit(SAMPLE_ROOTS.dcvDotnet),
|
|
@@ -536,6 +586,8 @@ function getRagSignatureData() {
|
|
|
536
586
|
dbrServerDocsHead: readManifestRepoCommit(DOC_ROOTS.dbrServer),
|
|
537
587
|
dcvCoreDocsHead: readManifestRepoCommit(DOC_ROOTS.dcvCore),
|
|
538
588
|
dcvWebDocsHead: readManifestRepoCommit(DOC_ROOTS.dcvWeb),
|
|
589
|
+
mrzWebDocsHead: readManifestRepoCommit(DOC_ROOTS.mrzWeb),
|
|
590
|
+
mdsWebDocsHead: readManifestRepoCommit(DOC_ROOTS.mdsWeb),
|
|
539
591
|
dcvMobileDocsHead: readManifestRepoCommit(DOC_ROOTS.dcvMobile),
|
|
540
592
|
dcvServerDocsHead: readManifestRepoCommit(DOC_ROOTS.dcvServer),
|
|
541
593
|
dwtDocsHead: readManifestRepoCommit(DOC_ROOTS.dwt),
|
|
@@ -560,6 +612,8 @@ export {
|
|
|
560
612
|
discoverDcvMobileSamples,
|
|
561
613
|
discoverDcvServerSamples,
|
|
562
614
|
discoverDcvWebSamples,
|
|
615
|
+
discoverMrzWebSamples,
|
|
616
|
+
discoverMdsWebSamples,
|
|
563
617
|
discoverWebSamples,
|
|
564
618
|
getWebSamplePath,
|
|
565
619
|
discoverDwtSamples,
|
|
@@ -568,6 +622,8 @@ export {
|
|
|
568
622
|
getDbrWebFrameworkPlatforms,
|
|
569
623
|
getDcvWebFrameworkPlatforms,
|
|
570
624
|
getDdvWebFrameworkPlatforms,
|
|
625
|
+
getMrzWebFrameworkPlatforms,
|
|
626
|
+
getMdsWebFrameworkPlatforms,
|
|
571
627
|
getWebFrameworkPlatforms,
|
|
572
628
|
findCodeFilesInSample,
|
|
573
629
|
getDbrServerSamplePath,
|
|
@@ -580,6 +636,8 @@ export {
|
|
|
580
636
|
getDcvMobileSamplePath,
|
|
581
637
|
getDcvServerSamplePath,
|
|
582
638
|
getDcvWebSamplePath,
|
|
639
|
+
getMrzWebSamplePath,
|
|
640
|
+
getMdsWebSamplePath,
|
|
583
641
|
getDwtSamplePath,
|
|
584
642
|
getDdvSamplePath,
|
|
585
643
|
readCodeFile,
|
|
@@ -28,7 +28,7 @@ export function registerResourceHandlers({
|
|
|
28
28
|
async function templateReadHandler(uri) {
|
|
29
29
|
const uriStr = uri.toString();
|
|
30
30
|
const parsed = parseResourceUri(uriStr);
|
|
31
|
-
if (parsed && ["
|
|
31
|
+
if (parsed && ["dbr", "dwt", "ddv", "mrz", "mds"].includes(parsed.product)) {
|
|
32
32
|
const policy = ensureLatestMajor({
|
|
33
33
|
product: parsed.product,
|
|
34
34
|
version: parsed.version,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const SERVER_SAMPLE_REPOS = {
|
|
2
|
+
python: "https://github.com/Dynamsoft/capture-vision-python-samples",
|
|
3
|
+
cpp: "https://github.com/Dynamsoft/capture-vision-cpp-samples",
|
|
4
|
+
java: "https://github.com/Dynamsoft/capture-vision-java-samples",
|
|
5
|
+
dotnet: "https://github.com/Dynamsoft/capture-vision-dotnet-samples",
|
|
6
|
+
nodejs: "https://github.com/Dynamsoft/capture-vision-nodejs-samples"
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const MOBILE_SAMPLE_REPOS = {
|
|
10
|
+
android: "https://github.com/Dynamsoft/capture-vision-mobile-samples/tree/main/Android",
|
|
11
|
+
ios: "https://github.com/Dynamsoft/capture-vision-mobile-samples/tree/main/iOS",
|
|
12
|
+
spm: "https://github.com/Dynamsoft/capture-vision-mobile-samples/tree/main/iOS",
|
|
13
|
+
"react-native": "https://github.com/Dynamsoft/capture-vision-react-native-samples",
|
|
14
|
+
flutter: "https://github.com/Dynamsoft/capture-vision-flutter-samples",
|
|
15
|
+
maui: "https://github.com/Dynamsoft/capture-vision-maui-samples"
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function getPublicServerSamplesUrl(platform) {
|
|
19
|
+
return SERVER_SAMPLE_REPOS[platform] || SERVER_SAMPLE_REPOS.python;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getPublicMobileSamplesUrl(platform) {
|
|
23
|
+
return MOBILE_SAMPLE_REPOS[platform] || MOBILE_SAMPLE_REPOS.android;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getUnsupportedPublicScopeRedirect(product, edition, platform) {
|
|
27
|
+
if (product === "mrz" && edition === "server") {
|
|
28
|
+
return {
|
|
29
|
+
label: "MRZ",
|
|
30
|
+
docsUrl: "https://www.dynamsoft.com/capture-vision/docs/server/",
|
|
31
|
+
samplesUrl: getPublicServerSamplesUrl(platform)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (product === "mds" && edition === "mobile") {
|
|
36
|
+
return {
|
|
37
|
+
label: "MDS",
|
|
38
|
+
docsUrl: "https://www.dynamsoft.com/capture-vision/docs/mobile/",
|
|
39
|
+
samplesUrl: getPublicMobileSamplesUrl(platform)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (product === "mds" && edition === "server") {
|
|
44
|
+
return {
|
|
45
|
+
label: "MDS",
|
|
46
|
+
docsUrl: "https://www.dynamsoft.com/capture-vision/docs/server/",
|
|
47
|
+
samplesUrl: getPublicServerSamplesUrl(platform)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildUnsupportedPublicScopeResponse(product, edition, platform) {
|
|
55
|
+
const redirect = getUnsupportedPublicScopeRedirect(product, edition, platform);
|
|
56
|
+
if (!redirect) return null;
|
|
57
|
+
|
|
58
|
+
const scope = [edition, platform].filter(Boolean).join(" / ") || "general";
|
|
59
|
+
return {
|
|
60
|
+
content: [{
|
|
61
|
+
type: "text",
|
|
62
|
+
text: [
|
|
63
|
+
`${redirect.label} ${scope} is not indexed in this MCP yet. Use these official links instead.`,
|
|
64
|
+
"Reference links:",
|
|
65
|
+
`- Docs: ${redirect.docsUrl}`,
|
|
66
|
+
`- Samples: ${redirect.samplesUrl}`
|
|
67
|
+
].join("\n")
|
|
68
|
+
}]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
getUnsupportedPublicScopeRedirect,
|
|
74
|
+
buildUnsupportedPublicScopeResponse
|
|
75
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatScoreLabel, formatScoreNote } from "../helpers/server-helpers.js";
|
|
3
|
+
import { buildUnknownPublicProductResponse, isKnownPublicOffering } from "../public-offerings.js";
|
|
4
|
+
import { buildUnsupportedPublicScopeResponse } from "./public-routing.js";
|
|
3
5
|
|
|
4
6
|
export function registerIndexTools({
|
|
5
7
|
server,
|
|
@@ -16,23 +18,29 @@ export function registerIndexTools({
|
|
|
16
18
|
getSampleEntries,
|
|
17
19
|
getSampleSuggestions
|
|
18
20
|
}) {
|
|
21
|
+
function looksLikeSampleIdQuery(value) {
|
|
22
|
+
const normalized = String(value || "").trim();
|
|
23
|
+
if (!normalized) return false;
|
|
24
|
+
return /[-_/]/.test(normalized);
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
server.registerTool(
|
|
20
28
|
"get_index",
|
|
21
29
|
{
|
|
22
30
|
title: "Get Index",
|
|
23
31
|
description: [
|
|
24
|
-
"Get a compact index of
|
|
32
|
+
"Get a compact index of the public Dynamsoft offerings, editions, platforms, versions, and available docs/samples.",
|
|
25
33
|
"",
|
|
26
34
|
"WHEN TO USE:",
|
|
27
35
|
"- As the first call in any conversation to discover what is available.",
|
|
28
36
|
"- To determine valid product/edition/platform combinations before calling other tools.",
|
|
29
|
-
"- To get
|
|
37
|
+
"- To get public product-selection guidance (DBR for barcode-only; MRZ for machine-readable-zone workflows; MDS for document scan and normalization workflows).",
|
|
30
38
|
"",
|
|
31
39
|
"WHEN NOT TO USE:",
|
|
32
40
|
"- Do not call get_index repeatedly; the index is static within a session.",
|
|
33
41
|
"- If you already know the product/edition/platform, skip directly to search or get_quickstart.",
|
|
34
42
|
"",
|
|
35
|
-
"RETURNS: A JSON object with top-level keys: productSelection and products. productSelection contains guidance for choosing between
|
|
43
|
+
"RETURNS: A JSON object with top-level keys: productSelection and products. productSelection contains guidance for choosing between public offerings, and products contains per-product entries (dbr, dwt, ddv, mrz, mds) with editions, platforms, latest versions, and counts of available docs and samples.",
|
|
36
44
|
"",
|
|
37
45
|
"PARAMETERS: None.",
|
|
38
46
|
"",
|
|
@@ -64,7 +72,7 @@ export function registerIndexTools({
|
|
|
64
72
|
"",
|
|
65
73
|
"WHEN TO USE:",
|
|
66
74
|
"- To find docs or samples by keyword, topic, or exact sample ID.",
|
|
67
|
-
"- To look up specific scenarios: MRZ scanning,
|
|
75
|
+
"- To look up specific scenarios: MRZ scanning, barcode decoding, document normalization, document scanning, and viewer workflows.",
|
|
68
76
|
"- When you have a natural-language question about a Dynamsoft SDK.",
|
|
69
77
|
"- For sample lookup by exact ID (e.g. query='hello-world', type='sample').",
|
|
70
78
|
"",
|
|
@@ -75,7 +83,7 @@ export function registerIndexTools({
|
|
|
75
83
|
"",
|
|
76
84
|
"PARAMETERS:",
|
|
77
85
|
"- query (required): Keywords or exact sample ID. Examples: 'barcode scanning from camera', 'MRZ passport reader', 'hello-world'.",
|
|
78
|
-
"- product:
|
|
86
|
+
"- product: dbr, dwt, ddv, mrz, or mds. Use DBR for barcode-only, MRZ for passport/machine-readable-zone workflows, and MDS for document scan or normalization workflows.",
|
|
79
87
|
"- edition: core, mobile, web, or server.",
|
|
80
88
|
"- platform: android, ios, js, python, cpp, java, dotnet, nodejs, react, vue, angular, flutter, react-native, maui, etc.",
|
|
81
89
|
"- version: Version constraint (e.g. '10', '11.x'). Only latest major is served by default.",
|
|
@@ -88,7 +96,7 @@ export function registerIndexTools({
|
|
|
88
96
|
].join("\n"),
|
|
89
97
|
inputSchema: {
|
|
90
98
|
query: z.string().trim().min(1, "Query is required.").describe("Keywords to search across docs and samples."),
|
|
91
|
-
product: z.string().optional().describe("Product:
|
|
99
|
+
product: z.string().optional().describe("Product: dbr, dwt, ddv, mrz, mds"),
|
|
92
100
|
edition: z.string().optional().describe("Edition: core, mobile, web, server/desktop"),
|
|
93
101
|
platform: z.string().optional().describe("Platform: android, ios, maui, react-native, flutter, js, python, cpp, java, dotnet, nodejs, angular, blazor, capacitor, electron, es6, native-ts, next, nuxt, pwa, react, requirejs, svelte, vue, webview, spm, core"),
|
|
94
102
|
version: z.string().optional().describe("Version constraint (major or full version)"),
|
|
@@ -104,8 +112,14 @@ export function registerIndexTools({
|
|
|
104
112
|
},
|
|
105
113
|
async ({ query, product, edition, platform, version, type, limit }) => {
|
|
106
114
|
const normalizedProduct = normalizeProduct(product);
|
|
115
|
+
if (product && !isKnownPublicOffering(normalizedProduct)) {
|
|
116
|
+
return buildUnknownPublicProductResponse(product);
|
|
117
|
+
}
|
|
118
|
+
|
|
107
119
|
const normalizedPlatform = normalizePlatform(platform);
|
|
108
120
|
const normalizedEdition = normalizeEdition(edition, normalizedPlatform, normalizedProduct);
|
|
121
|
+
const unsupportedScopeResponse = buildUnsupportedPublicScopeResponse(normalizedProduct, normalizedEdition, normalizedPlatform);
|
|
122
|
+
if (unsupportedScopeResponse) return unsupportedScopeResponse;
|
|
109
123
|
|
|
110
124
|
await ensureScopeHydrated({
|
|
111
125
|
product: normalizedProduct,
|
|
@@ -185,14 +199,19 @@ export function registerIndexTools({
|
|
|
185
199
|
}
|
|
186
200
|
}
|
|
187
201
|
|
|
188
|
-
const
|
|
189
|
-
query
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
202
|
+
const preferSampleSuggestionFallback =
|
|
203
|
+
effectiveType === "sample" && looksLikeSampleIdQuery(query);
|
|
204
|
+
|
|
205
|
+
const topResults = preferSampleSuggestionFallback
|
|
206
|
+
? []
|
|
207
|
+
: await searchResources({
|
|
208
|
+
query,
|
|
209
|
+
product: normalizedProduct,
|
|
210
|
+
edition: normalizedEdition,
|
|
211
|
+
platform: normalizedPlatform,
|
|
212
|
+
type: effectiveType,
|
|
213
|
+
limit: maxResults
|
|
214
|
+
});
|
|
196
215
|
|
|
197
216
|
if (topResults.length === 0) {
|
|
198
217
|
// Only try sample suggestions when searching samples or any type
|