simple-dynamsoft-mcp 7.1.0 → 7.1.1

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.
@@ -88,8 +88,8 @@
88
88
  "branch": "master",
89
89
  "owner": "dynamsoft-docs",
90
90
  "repo": "web-twain-docs",
91
- "commit": "779f3794064a224c3a26740470250389ca9aa0ce",
92
- "archiveUrl": "https://codeload.github.com/dynamsoft-docs/web-twain-docs/zip/779f3794064a224c3a26740470250389ca9aa0ce"
91
+ "commit": "275eefb2a97512e91cfca139ac58f8a8b6317f8a",
92
+ "archiveUrl": "https://codeload.github.com/dynamsoft-docs/web-twain-docs/zip/275eefb2a97512e91cfca139ac58f8a8b6317f8a"
93
93
  },
94
94
  {
95
95
  "name": "data/samples/dynamic-web-twain",
@@ -455,7 +455,7 @@
455
455
  "dwt": {
456
456
  "name": "Dynamic Web TWAIN",
457
457
  "description": "Document scanning SDK for web applications. Supports TWAIN, WIA, ICA, SANE scanners.",
458
- "version": "19.3",
458
+ "version": "19.3.2",
459
459
  "default_platform": "web",
460
460
  "snippet_path": "dynamic-web-twain",
461
461
  "api_docs": "web-twain-api-docs.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-dynamsoft-mcp",
3
- "version": "7.1.0",
3
+ "version": "7.1.1",
4
4
  "description": "MCP server for Dynamsoft SDKs - Capture Vision, Barcode Reader (Mobile/Python/Web), Dynamic Web TWAIN, and Document Viewer. Provides documentation, code snippets, and API guidance.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,9 +1,4 @@
1
- import {
2
- ListResourcesRequestSchema,
3
- ReadResourceRequestSchema,
4
- SubscribeRequestSchema,
5
- UnsubscribeRequestSchema
6
- } from "@modelcontextprotocol/sdk/types.js";
1
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
7
2
 
8
3
  export function registerResourceHandlers({
9
4
  server,
@@ -12,25 +7,27 @@ export function registerResourceHandlers({
12
7
  ensureLatestMajor,
13
8
  readResourceContent
14
9
  }) {
15
- server.server.registerCapabilities({
16
- resources: {
17
- listChanged: false,
18
- subscribe: true
19
- }
20
- });
21
-
22
- server.server.setRequestHandler(ListResourcesRequestSchema, async () => {
23
- const resources = getPinnedResources().map((entry) => ({
24
- uri: entry.uri,
25
- name: entry.title,
26
- description: entry.summary,
27
- mimeType: entry.mimeType
28
- }));
29
- return { resources };
30
- });
10
+ for (const entry of getPinnedResources()) {
11
+ server.registerResource(
12
+ entry.title,
13
+ entry.uri,
14
+ {
15
+ description: entry.summary,
16
+ mimeType: entry.mimeType
17
+ },
18
+ async (uri) => {
19
+ const resource = await readResourceContent(uri.toString());
20
+ if (!resource) {
21
+ throw new Error(`Resource not found: ${uri}`);
22
+ }
23
+ return { contents: [resource] };
24
+ }
25
+ );
26
+ }
31
27
 
32
- server.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
33
- const parsed = parseResourceUri(request.params.uri);
28
+ async function templateReadHandler(uri) {
29
+ const uriStr = uri.toString();
30
+ const parsed = parseResourceUri(uriStr);
34
31
  if (parsed && ["dcv", "dbr", "dwt", "ddv"].includes(parsed.product)) {
35
32
  const policy = ensureLatestMajor({
36
33
  product: parsed.product,
@@ -43,14 +40,25 @@ export function registerResourceHandlers({
43
40
  }
44
41
  }
45
42
 
46
- const resource = await readResourceContent(request.params.uri);
43
+ const resource = await readResourceContent(uriStr);
47
44
  if (!resource) {
48
- throw new Error(`Resource not found: ${request.params.uri}`);
45
+ throw new Error(`Resource not found: ${uriStr}`);
49
46
  }
50
47
 
51
48
  return { contents: [resource] };
52
- });
49
+ }
50
+
51
+ server.registerResource(
52
+ "doc-resource",
53
+ new ResourceTemplate("doc://{product}/{edition}/{platform}/{version}/{+slug}", {}),
54
+ { description: "Dynamsoft documentation resource" },
55
+ templateReadHandler
56
+ );
53
57
 
54
- server.server.setRequestHandler(SubscribeRequestSchema, async () => ({}));
55
- server.server.setRequestHandler(UnsubscribeRequestSchema, async () => ({}));
58
+ server.registerResource(
59
+ "sample-resource",
60
+ new ResourceTemplate("sample://{product}/{edition}/{platform}/{version}/{+rest}", {}),
61
+ { description: "Dynamsoft sample code resource" },
62
+ templateReadHandler
63
+ );
56
64
  }
@@ -20,8 +20,35 @@ export function registerIndexTools({
20
20
  "get_index",
21
21
  {
22
22
  title: "Get Index",
23
- description: "Get a compact index of products, editions, versions, samples/docs, plus DBR-vs-DCV selection guidance.",
24
- inputSchema: {}
23
+ description: [
24
+ "Get a compact index of all Dynamsoft products, editions, platforms, versions, and available docs/samples.",
25
+ "",
26
+ "WHEN TO USE:",
27
+ "- As the first call in any conversation to discover what is available.",
28
+ "- To determine valid product/edition/platform combinations before calling other tools.",
29
+ "- To get DBR-vs-DCV selection guidance (DBR for barcode-only; DCV for MRZ, VIN, document normalization, driver license).",
30
+ "",
31
+ "WHEN NOT TO USE:",
32
+ "- Do not call get_index repeatedly; the index is static within a session.",
33
+ "- If you already know the product/edition/platform, skip directly to search or get_quickstart.",
34
+ "",
35
+ "RETURNS: A JSON object with top-level keys: productSelection and products. productSelection contains guidance for choosing between products (for example, DBR vs DCV), and products contains per-product entries (dcv, dbr, dwt, ddv) with editions, platforms, latest versions, and counts of available docs and samples.",
36
+ "",
37
+ "PARAMETERS: None.",
38
+ "",
39
+ "EXAMPLE WORKFLOW:",
40
+ "1. Call get_index to discover available products.",
41
+ "2. Use the returned product/edition/platform values in search, list_samples, or get_quickstart.",
42
+ "",
43
+ "RELATED TOOLS: search (find specific resources), list_samples (browse samples), resolve_version (get exact version numbers)."
44
+ ].join("\n"),
45
+ inputSchema: {},
46
+ annotations: {
47
+ readOnlyHint: true,
48
+ destructiveHint: false,
49
+ idempotentHint: true,
50
+ openWorldHint: false
51
+ }
25
52
  },
26
53
  async () => ({
27
54
  content: [{ type: "text", text: JSON.stringify(buildIndexData(), null, 2) }]
@@ -32,21 +59,50 @@ export function registerIndexTools({
32
59
  "search",
33
60
  {
34
61
  title: "Search",
35
- description: "Search across docs and samples with semantic (RAG) search and fuzzy fallback. Accepts keywords or exact sample IDs. Returns resource links for lazy loading. Prefer DCV for MRZ/VIN/document-normalization/driver-license scenarios; DBR for barcode-only.",
62
+ description: [
63
+ "Search across documentation and samples using semantic (RAG) search with fuzzy fallback.",
64
+ "",
65
+ "WHEN TO USE:",
66
+ "- To find docs or samples by keyword, topic, or exact sample ID.",
67
+ "- To look up specific scenarios: MRZ scanning, VIN reading, barcode decoding, document normalization, etc.",
68
+ "- When you have a natural-language question about a Dynamsoft SDK.",
69
+ "- For sample lookup by exact ID (e.g. query='hello-world', type='sample').",
70
+ "",
71
+ "WHEN NOT TO USE:",
72
+ "- To browse all samples in a scope, use list_samples instead.",
73
+ "- To get starter code quickly, use get_quickstart instead.",
74
+ "- If you do not know valid products/editions, call get_index first.",
75
+ "",
76
+ "PARAMETERS:",
77
+ "- query (required): Keywords or exact sample ID. Examples: 'barcode scanning from camera', 'MRZ passport reader', 'hello-world'.",
78
+ "- product: dcv, dbr, dwt, or ddv. Prefer DCV for MRZ/VIN/document-normalization/driver-license; DBR for barcode-only.",
79
+ "- edition: core, mobile, web, or server.",
80
+ "- platform: android, ios, js, python, cpp, java, dotnet, nodejs, react, vue, angular, flutter, react-native, maui, etc.",
81
+ "- version: Version constraint (e.g. '10', '11.x'). Only latest major is served by default.",
82
+ "- type: 'doc', 'sample', 'index', 'policy', or 'any' (default). Use 'sample' to restrict to sample results.",
83
+ "- limit: 1-10 (default 5). Max number of results.",
84
+ "",
85
+ "RETURNS: An MCP response whose content array includes a leading text summary item followed by zero or more resource_link items with URIs. Use resources/read to fetch full content of doc:// URIs. Use get_sample_files to fetch full project files for sample:// URIs.",
86
+ "",
87
+ "RELATED TOOLS: get_index (discover products first), list_samples (browse all samples), get_sample_files (retrieve full sample project files), resources/read (read a doc resource)."
88
+ ].join("\n"),
36
89
  inputSchema: {
37
- query: z.string().describe("Keywords to search across docs and samples."),
90
+ query: z.string().trim().min(1, "Query is required.").describe("Keywords to search across docs and samples."),
38
91
  product: z.string().optional().describe("Product: dcv, dbr, dwt, ddv"),
39
92
  edition: z.string().optional().describe("Edition: core, mobile, web, server/desktop"),
40
93
  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"),
41
94
  version: z.string().optional().describe("Version constraint (major or full version)"),
42
95
  type: z.enum(["doc", "sample", "index", "policy", "any"]).optional(),
43
96
  limit: z.number().int().min(1).max(10).optional().describe("Max results (default 5)")
97
+ },
98
+ annotations: {
99
+ readOnlyHint: true,
100
+ destructiveHint: false,
101
+ idempotentHint: true,
102
+ openWorldHint: false
44
103
  }
45
104
  },
46
105
  async ({ query, product, edition, platform, version, type, limit }) => {
47
- if (!query || !query.trim()) {
48
- return { isError: true, content: [{ type: "text", text: "Query is required." }] };
49
- }
50
106
  const normalizedProduct = normalizeProduct(product);
51
107
  const normalizedPlatform = normalizePlatform(platform);
52
108
  const normalizedEdition = normalizeEdition(edition, normalizedPlatform, normalizedProduct);
@@ -30,15 +30,47 @@ export function registerProjectTools({
30
30
  "get_sample_files",
31
31
  {
32
32
  title: "Get Sample Files",
33
- description: "Get project files for a known sample (by sample_id or resource_uri) and return them inline. Use list_samples or search to discover sample IDs first.",
33
+ description: [
34
+ "Get the full project files for a known sample and return them inline as text.",
35
+ "",
36
+ "WHEN TO USE:",
37
+ "- When you have a sample_id (from list_samples) or a sample:// resource_uri (from search) and need the complete source code.",
38
+ "- When the user wants to see or scaffold a full sample project (multiple files, build configs, manifests).",
39
+ "",
40
+ "WHEN NOT TO USE:",
41
+ "- If you do not have a sample_id or resource_uri yet, call list_samples or search first to discover one.",
42
+ "- For doc:// URIs, use resources/read instead (this tool only handles sample:// URIs).",
43
+ "- If the user just wants a quick code snippet, use get_quickstart instead.",
44
+ "",
45
+ "PARAMETERS:",
46
+ "- product (required): dcv, dbr, dwt, or ddv.",
47
+ "- edition: mobile, web, or server.",
48
+ "- platform: android, ios, js, python, cpp, java, dotnet, nodejs, react, vue, angular, flutter, react-native, maui, etc.",
49
+ "- version: Version constraint. Latest major is used by default.",
50
+ "- sample_id: Sample identifier as returned by list_samples (e.g. 'hello-world', 'ScanSingleBarcode'). Requires product/edition.",
51
+ "- resource_uri: A sample:// URI as returned by search (e.g. 'sample://dbr/mobile/android/10/high-level/ScanSingleBarcode'). Preferred over sample_id when available.",
52
+ "- api_level: 'high-level' or 'low-level' (DBR mobile only).",
53
+ "",
54
+ "RETURNS: A text block containing all project files inline, each under a heading with its relative path and wrapped in a fenced code block. Files larger than 50KB are excluded. No zip file is created.",
55
+ "",
56
+ "EXAMPLE: get_sample_files with resource_uri='sample://dbr/mobile/android/10/high-level/ScanSingleBarcode' returns all source files for the Android barcode scanning sample.",
57
+ "",
58
+ "RELATED TOOLS: list_samples (discover sample IDs), search (find samples by keyword), get_quickstart (quick single-file snippet)."
59
+ ].join("\n"),
34
60
  inputSchema: {
35
- product: z.string().describe("Product: dcv, dbr, dwt, or ddv"),
61
+ product: z.string().trim().min(1, "Product is required.").describe("Product: dcv, dbr, dwt, or ddv"),
36
62
  edition: z.string().optional().describe("Edition: mobile, web, server/desktop"),
37
63
  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"),
38
64
  version: z.string().optional().describe("Version constraint"),
39
65
  sample_id: z.string().optional().describe("Sample identifier (name or path)"),
40
66
  resource_uri: z.string().optional().describe("Resource URI returned by search"),
41
67
  api_level: z.string().optional().describe("API level: high-level or low-level (mobile only)")
68
+ },
69
+ annotations: {
70
+ readOnlyHint: true,
71
+ destructiveHint: false,
72
+ idempotentHint: true,
73
+ openWorldHint: false
42
74
  }
43
75
  },
44
76
  async ({ product, edition, platform, version, sample_id, resource_uri, api_level }) => {
@@ -29,15 +29,46 @@ export function registerQuickstartTools({
29
29
  "get_quickstart",
30
30
  {
31
31
  title: "Get Quickstart",
32
- description: "Opinionated quickstart for a target product/edition/platform. DCV supports MRZ/VIN/document-normalization/driver-license workflows.",
32
+ description: [
33
+ "Get an opinionated quickstart with installation instructions and working sample code for a target product/edition/platform.",
34
+ "",
35
+ "WHEN TO USE:",
36
+ "- When the user wants to get started quickly with a Dynamsoft SDK.",
37
+ "- To generate a ready-to-run code snippet with install commands, license key, and SDK version.",
38
+ "- For scenario-specific starters: pass scenario='MRZ' for passport reading, 'VIN' for vehicle identification, 'document scan' for document normalization, etc.",
39
+ "",
40
+ "WHEN NOT TO USE:",
41
+ "- If the user wants full project files (multiple source files, build configs), use get_sample_files instead.",
42
+ "- If the user wants to browse available samples first, use search or list_samples.",
43
+ "- If the user only needs version info, use resolve_version.",
44
+ "",
45
+ "PARAMETERS:",
46
+ "- product (required): dcv, dbr, dwt, or ddv.",
47
+ "- edition: core, mobile, web, or server. Inferred from platform if omitted.",
48
+ "- platform: android, ios, js, python, cpp, java, dotnet, nodejs, react, vue, angular, flutter, react-native, maui, etc.",
49
+ "- language: kotlin, java, swift, js, ts, python, cpp, csharp, react, vue, angular. Helps select the best sample variant.",
50
+ "- version: Version constraint. Latest major is used by default.",
51
+ "- api_level: 'high-level' or 'low-level' (mobile only). Controls API abstraction level in generated code.",
52
+ "- scenario: MRZ, VIN, document scan, driver license, camera, image, single, multiple, etc. DCV supports MRZ/VIN/document-normalization/driver-license workflows.",
53
+ "",
54
+ "RETURNS: A formatted text block with SDK version, trial license key, install commands, and sample code. Ready to copy-paste.",
55
+ "",
56
+ "RELATED TOOLS: search (find specific docs or samples), get_sample_files (get full multi-file project), resolve_version (version numbers only)."
57
+ ].join("\n"),
33
58
  inputSchema: {
34
- product: z.string().describe("Product: dcv, dbr, dwt, or ddv"),
59
+ product: z.string().trim().min(1, "Product is required.").describe("Product: dcv, dbr, dwt, or ddv"),
35
60
  edition: z.string().optional().describe("Edition: core, mobile, web, server/desktop"),
36
61
  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"),
37
62
  language: z.string().optional().describe("Language hint: kotlin, java, swift, js, ts, python, cpp, csharp, react, vue, angular"),
38
63
  version: z.string().optional().describe("Version constraint"),
39
64
  api_level: z.string().optional().describe("API level: high-level or low-level (mobile only)"),
40
65
  scenario: z.string().optional().describe("Scenario: camera, image, single, multiple, MRZ, VIN, document scan/normalization, driver license, react, etc.")
66
+ },
67
+ annotations: {
68
+ readOnlyHint: true,
69
+ destructiveHint: false,
70
+ idempotentHint: true,
71
+ openWorldHint: false
41
72
  }
42
73
  },
43
74
  async ({ product, edition, platform, language, version, api_level, scenario }) => {
@@ -16,12 +16,42 @@ export function registerSampleTools({
16
16
  "list_samples",
17
17
  {
18
18
  title: "List Samples",
19
- description: "List available sample IDs and URIs for a given scope. Use DCV scope for MRZ/VIN/document normalization scenarios.",
19
+ description: [
20
+ "List all available sample IDs and URIs for a given product/edition/platform scope.",
21
+ "",
22
+ "WHEN TO USE:",
23
+ "- To browse the full catalog of samples available for a product/edition/platform.",
24
+ "- To discover sample IDs before calling get_sample_files.",
25
+ "- When the user wants to see what samples exist without a specific keyword.",
26
+ "- Use DCV scope for MRZ, VIN, document normalization, and driver license scenarios.",
27
+ "",
28
+ "WHEN NOT TO USE:",
29
+ "- If you have a specific keyword or topic, use search instead (it ranks results by relevance).",
30
+ "- If you already have a sample ID or URI, go directly to get_sample_files.",
31
+ "",
32
+ "PARAMETERS:",
33
+ "- product: dcv, dbr, dwt, or ddv. Omit to list across all products.",
34
+ "- edition: core, mobile, web, or server. Omit to list across all editions.",
35
+ "- platform: android, ios, js, python, cpp, java, dotnet, nodejs, react, vue, angular, flutter, react-native, maui, etc.",
36
+ "- limit: 1-200 (default 50). Max number of results.",
37
+ "",
38
+ "RETURNS: A single text content item that starts with totals and plain URIs, then appends 'JSON:' followed by a JSON object with total count and sample entries. Each entry includes sample_id, uri (sample:// URI), product, edition, platform, version, title, and summary. Use sample_id or uri with get_sample_files to retrieve full project files.",
39
+ "",
40
+ "EXAMPLE: Call list_samples with product='dbr', edition='mobile', platform='android' to see all Android barcode reader samples.",
41
+ "",
42
+ "RELATED TOOLS: search (keyword-based discovery), get_sample_files (retrieve full project files for a sample), get_index (discover valid product/edition/platform combinations)."
43
+ ].join("\n"),
20
44
  inputSchema: {
21
45
  product: z.string().optional().describe("Product: dcv, dbr, dwt, ddv"),
22
46
  edition: z.string().optional().describe("Edition: core, mobile, web, server/desktop"),
23
47
  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"),
24
48
  limit: z.number().int().min(1).max(200).optional().describe("Max results (default 50)")
49
+ },
50
+ annotations: {
51
+ readOnlyHint: true,
52
+ destructiveHint: false,
53
+ idempotentHint: true,
54
+ openWorldHint: false
25
55
  }
26
56
  },
27
57
  async ({ product, edition, platform, limit }) => {
@@ -13,13 +13,43 @@ export function registerVersionTools({
13
13
  "resolve_version",
14
14
  {
15
15
  title: "Resolve Version",
16
- description: "Resolve a concrete latest-major version for a product/edition/platform.",
16
+ description: [
17
+ "Resolve a concrete latest-major version number for a Dynamsoft product/edition/platform.",
18
+ "",
19
+ "WHEN TO USE:",
20
+ "- To get the exact current version string (e.g. '10.4.2001') for use in package installation or dependency pinning.",
21
+ "- When the user asks 'what is the latest version of DBR?'.",
22
+ "- To verify version compatibility before generating project scaffolding.",
23
+ "",
24
+ "WHEN NOT TO USE:",
25
+ "- If you just need sample code, use get_quickstart (it already includes the correct version).",
26
+ "- For browsing docs or samples, use search or list_samples (they already scope to latest major).",
27
+ "",
28
+ "PARAMETERS:",
29
+ "- product (required): dcv, dbr, dwt, or ddv.",
30
+ "- edition: core, mobile, web, or server. Omit to see all editions for the product.",
31
+ "- platform: android, ios, js, python, cpp, java, dotnet, nodejs, etc. Helps narrow edition when ambiguous.",
32
+ "- constraint: Version constraint like 'latest', '11.x', '10'. Only latest major version is served; legacy versions (e.g. DBR v9) return an error with migration guidance.",
33
+ "- feature: Optional feature hint for version policy checks.",
34
+ "",
35
+ "RETURNS: A text block showing the resolved version. For DCV/DBR without an edition, returns all edition versions. For DWT/DDV, returns the single web version.",
36
+ "",
37
+ "EXAMPLE: resolve_version with product='dbr', edition='web' returns the latest DBR web SDK version string.",
38
+ "",
39
+ "RELATED TOOLS: get_quickstart (includes version in starter code), get_index (shows version overview)."
40
+ ].join("\n"),
17
41
  inputSchema: {
18
- product: z.string().describe("Product: dcv, dbr, dwt, or ddv"),
42
+ product: z.string().trim().min(1, "Product is required.").describe("Product: dcv, dbr, dwt, or ddv"),
19
43
  edition: z.string().optional().describe("Edition: core, mobile, web, server/desktop"),
20
44
  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"),
21
45
  constraint: z.string().optional().describe("Version constraint, e.g., latest, 11.x, 10"),
22
46
  feature: z.string().optional().describe("Optional feature hint")
47
+ },
48
+ annotations: {
49
+ readOnlyHint: true,
50
+ destructiveHint: false,
51
+ idempotentHint: true,
52
+ openWorldHint: false
23
53
  }
24
54
  },
25
55
  async ({ product, edition, platform, constraint, feature }) => {