@hcu-lab.me/mcp-device 1.0.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.
Files changed (261) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/bootstrap.d.ts +1 -0
  4. package/dist/bootstrap.js +22 -0
  5. package/dist/command-manager.d.ts +8 -0
  6. package/dist/command-manager.js +241 -0
  7. package/dist/config-field-definitions.d.ts +41 -0
  8. package/dist/config-field-definitions.js +37 -0
  9. package/dist/config-manager.d.ts +102 -0
  10. package/dist/config-manager.js +291 -0
  11. package/dist/config.d.ts +6 -0
  12. package/dist/config.js +10 -0
  13. package/dist/custom-stdio.d.ts +51 -0
  14. package/dist/custom-stdio.js +358 -0
  15. package/dist/data/official-app-ca.pem +12 -0
  16. package/dist/data/onboarding-prompts.json +70 -0
  17. package/dist/device/device-state.d.ts +13 -0
  18. package/dist/device/device-state.js +100 -0
  19. package/dist/device/device-status.d.ts +81 -0
  20. package/dist/device/device-status.js +156 -0
  21. package/dist/device/device.d.ts +16 -0
  22. package/dist/device/device.js +190 -0
  23. package/dist/device/execution-engine.d.ts +144 -0
  24. package/dist/device/execution-engine.js +195 -0
  25. package/dist/device/gateway-channel.d.ts +48 -0
  26. package/dist/device/gateway-channel.js +384 -0
  27. package/dist/device/gateway-config.d.ts +40 -0
  28. package/dist/device/gateway-config.js +207 -0
  29. package/dist/device/gateway-identity.d.ts +35 -0
  30. package/dist/device/gateway-identity.js +178 -0
  31. package/dist/device/gateway-pairing.d.ts +25 -0
  32. package/dist/device/gateway-pairing.js +105 -0
  33. package/dist/device/gateway-secure-transport.d.ts +25 -0
  34. package/dist/device/gateway-secure-transport.js +117 -0
  35. package/dist/device/gateway-tool-adapter.d.ts +17 -0
  36. package/dist/device/gateway-tool-adapter.js +284 -0
  37. package/dist/device/gateway-url-policy.d.ts +3 -0
  38. package/dist/device/gateway-url-policy.js +43 -0
  39. package/dist/device/linux-service.d.ts +70 -0
  40. package/dist/device/linux-service.js +268 -0
  41. package/dist/device/official-trust.d.ts +7 -0
  42. package/dist/device/official-trust.js +49 -0
  43. package/dist/device/project-inspection.d.ts +1 -0
  44. package/dist/device/project-inspection.js +180 -0
  45. package/dist/device/runtime-owner.d.ts +41 -0
  46. package/dist/device/runtime-owner.js +177 -0
  47. package/dist/device/windows-dpapi.d.ts +11 -0
  48. package/dist/device/windows-dpapi.js +67 -0
  49. package/dist/device/windows-service.d.ts +56 -0
  50. package/dist/device/windows-service.js +238 -0
  51. package/dist/error-handlers.d.ts +7 -0
  52. package/dist/error-handlers.js +15 -0
  53. package/dist/handlers/edit-search-handlers.d.ts +6 -0
  54. package/dist/handlers/edit-search-handlers.js +6 -0
  55. package/dist/handlers/filesystem-handlers.d.ts +38 -0
  56. package/dist/handlers/filesystem-handlers.js +440 -0
  57. package/dist/handlers/history-handlers.d.ts +12 -0
  58. package/dist/handlers/history-handlers.js +67 -0
  59. package/dist/handlers/index.d.ts +6 -0
  60. package/dist/handlers/index.js +7 -0
  61. package/dist/handlers/process-handlers.d.ts +9 -0
  62. package/dist/handlers/process-handlers.js +15 -0
  63. package/dist/handlers/search-handlers.d.ts +17 -0
  64. package/dist/handlers/search-handlers.js +224 -0
  65. package/dist/handlers/terminal-handlers.d.ts +21 -0
  66. package/dist/handlers/terminal-handlers.js +35 -0
  67. package/dist/index.d.ts +2 -0
  68. package/dist/index.js +138 -0
  69. package/dist/mcp-device.d.ts +2 -0
  70. package/dist/mcp-device.js +7 -0
  71. package/dist/npm-scripts/remote.d.ts +3 -0
  72. package/dist/npm-scripts/remote.js +314 -0
  73. package/dist/search-manager.d.ts +147 -0
  74. package/dist/search-manager.js +828 -0
  75. package/dist/server.d.ts +46 -0
  76. package/dist/server.js +1563 -0
  77. package/dist/terminal-manager.d.ts +104 -0
  78. package/dist/terminal-manager.js +635 -0
  79. package/dist/tools/config.d.ts +96 -0
  80. package/dist/tools/config.js +260 -0
  81. package/dist/tools/edit.d.ts +38 -0
  82. package/dist/tools/edit.js +435 -0
  83. package/dist/tools/feedback.d.ts +8 -0
  84. package/dist/tools/feedback.js +132 -0
  85. package/dist/tools/filesystem.d.ts +79 -0
  86. package/dist/tools/filesystem.js +947 -0
  87. package/dist/tools/fuzzySearch.d.ts +12 -0
  88. package/dist/tools/fuzzySearch.js +74 -0
  89. package/dist/tools/fuzzySearchCore.d.ts +52 -0
  90. package/dist/tools/fuzzySearchCore.js +125 -0
  91. package/dist/tools/improved-process-tools.d.ts +24 -0
  92. package/dist/tools/improved-process-tools.js +627 -0
  93. package/dist/tools/mime-types.d.ts +3 -0
  94. package/dist/tools/mime-types.js +28 -0
  95. package/dist/tools/pdf/extract-images.d.ts +34 -0
  96. package/dist/tools/pdf/extract-images.js +132 -0
  97. package/dist/tools/pdf/index.d.ts +6 -0
  98. package/dist/tools/pdf/index.js +3 -0
  99. package/dist/tools/pdf/lib/pdf2md.d.ts +36 -0
  100. package/dist/tools/pdf/lib/pdf2md.js +76 -0
  101. package/dist/tools/pdf/manipulations.d.ts +13 -0
  102. package/dist/tools/pdf/manipulations.js +99 -0
  103. package/dist/tools/pdf/markdown.d.ts +26 -0
  104. package/dist/tools/pdf/markdown.js +275 -0
  105. package/dist/tools/pdf/utils.d.ts +12 -0
  106. package/dist/tools/pdf/utils.js +34 -0
  107. package/dist/tools/process.d.ts +3 -0
  108. package/dist/tools/process.js +56 -0
  109. package/dist/tools/prompts.d.ts +28 -0
  110. package/dist/tools/prompts.js +259 -0
  111. package/dist/tools/schemas.d.ts +454 -0
  112. package/dist/tools/schemas.js +242 -0
  113. package/dist/tools/usage.d.ts +5 -0
  114. package/dist/tools/usage.js +24 -0
  115. package/dist/types.d.ts +83 -0
  116. package/dist/types.js +1 -0
  117. package/dist/ui/config-editor/config-editor-runtime.js +150 -0
  118. package/dist/ui/config-editor/index.html +13 -0
  119. package/dist/ui/config-editor/src/app.d.ts +43 -0
  120. package/dist/ui/config-editor/src/app.js +831 -0
  121. package/dist/ui/config-editor/src/array-modal.d.ts +19 -0
  122. package/dist/ui/config-editor/src/array-modal.js +185 -0
  123. package/dist/ui/config-editor/src/main.d.ts +1 -0
  124. package/dist/ui/config-editor/src/main.js +2 -0
  125. package/dist/ui/config-editor/styles.css +587 -0
  126. package/dist/ui/contracts.d.ts +14 -0
  127. package/dist/ui/contracts.js +21 -0
  128. package/dist/ui/file-preview/index.html +16 -0
  129. package/dist/ui/file-preview/preview-runtime.js +469 -0
  130. package/dist/ui/file-preview/shared/preview-file-types.d.ts +5 -0
  131. package/dist/ui/file-preview/shared/preview-file-types.js +59 -0
  132. package/dist/ui/file-preview/src/app.d.ts +4 -0
  133. package/dist/ui/file-preview/src/app.js +680 -0
  134. package/dist/ui/file-preview/src/components/code-viewer.d.ts +6 -0
  135. package/dist/ui/file-preview/src/components/code-viewer.js +73 -0
  136. package/dist/ui/file-preview/src/components/highlighting.d.ts +2 -0
  137. package/dist/ui/file-preview/src/components/highlighting.js +54 -0
  138. package/dist/ui/file-preview/src/components/html-renderer.d.ts +5 -0
  139. package/dist/ui/file-preview/src/components/html-renderer.js +47 -0
  140. package/dist/ui/file-preview/src/components/markdown-renderer.d.ts +1 -0
  141. package/dist/ui/file-preview/src/components/markdown-renderer.js +59 -0
  142. package/dist/ui/file-preview/src/directory-controller.d.ts +8 -0
  143. package/dist/ui/file-preview/src/directory-controller.js +240 -0
  144. package/dist/ui/file-preview/src/document-layout.d.ts +20 -0
  145. package/dist/ui/file-preview/src/document-layout.js +109 -0
  146. package/dist/ui/file-preview/src/document-outline.d.ts +17 -0
  147. package/dist/ui/file-preview/src/document-outline.js +97 -0
  148. package/dist/ui/file-preview/src/document-workspace.d.ts +19 -0
  149. package/dist/ui/file-preview/src/document-workspace.js +33 -0
  150. package/dist/ui/file-preview/src/file-type-handlers.d.ts +10 -0
  151. package/dist/ui/file-preview/src/file-type-handlers.js +109 -0
  152. package/dist/ui/file-preview/src/host/external-actions.d.ts +8 -0
  153. package/dist/ui/file-preview/src/host/external-actions.js +55 -0
  154. package/dist/ui/file-preview/src/host/selection-context.d.ts +9 -0
  155. package/dist/ui/file-preview/src/host/selection-context.js +106 -0
  156. package/dist/ui/file-preview/src/image-preview.d.ts +3 -0
  157. package/dist/ui/file-preview/src/image-preview.js +21 -0
  158. package/dist/ui/file-preview/src/main.d.ts +1 -0
  159. package/dist/ui/file-preview/src/main.js +5 -0
  160. package/dist/ui/file-preview/src/markdown/conflict-dialog.d.ts +40 -0
  161. package/dist/ui/file-preview/src/markdown/conflict-dialog.js +163 -0
  162. package/dist/ui/file-preview/src/markdown/controller.d.ts +44 -0
  163. package/dist/ui/file-preview/src/markdown/controller.js +1043 -0
  164. package/dist/ui/file-preview/src/markdown/editor.d.ts +131 -0
  165. package/dist/ui/file-preview/src/markdown/editor.js +1479 -0
  166. package/dist/ui/file-preview/src/markdown/linking.d.ts +16 -0
  167. package/dist/ui/file-preview/src/markdown/linking.js +228 -0
  168. package/dist/ui/file-preview/src/markdown/outline.d.ts +2 -0
  169. package/dist/ui/file-preview/src/markdown/outline.js +16 -0
  170. package/dist/ui/file-preview/src/markdown/parser.d.ts +30 -0
  171. package/dist/ui/file-preview/src/markdown/parser.js +38 -0
  172. package/dist/ui/file-preview/src/markdown/preview.d.ts +1 -0
  173. package/dist/ui/file-preview/src/markdown/preview.js +20 -0
  174. package/dist/ui/file-preview/src/markdown/slugify.d.ts +3 -0
  175. package/dist/ui/file-preview/src/markdown/slugify.js +31 -0
  176. package/dist/ui/file-preview/src/markdown/utils.d.ts +1 -0
  177. package/dist/ui/file-preview/src/markdown/utils.js +15 -0
  178. package/dist/ui/file-preview/src/model.d.ts +35 -0
  179. package/dist/ui/file-preview/src/model.js +1 -0
  180. package/dist/ui/file-preview/src/panel-actions.d.ts +17 -0
  181. package/dist/ui/file-preview/src/panel-actions.js +182 -0
  182. package/dist/ui/file-preview/src/path-utils.d.ts +6 -0
  183. package/dist/ui/file-preview/src/path-utils.js +64 -0
  184. package/dist/ui/file-preview/src/payload-utils.d.ts +11 -0
  185. package/dist/ui/file-preview/src/payload-utils.js +119 -0
  186. package/dist/ui/file-preview/src/types.d.ts +1 -0
  187. package/dist/ui/file-preview/src/types.js +1 -0
  188. package/dist/ui/file-preview/styles.css +1631 -0
  189. package/dist/ui/resources.d.ts +28 -0
  190. package/dist/ui/resources.js +86 -0
  191. package/dist/ui/shared/compact-row.d.ts +11 -0
  192. package/dist/ui/shared/compact-row.js +18 -0
  193. package/dist/ui/shared/escape-html.d.ts +4 -0
  194. package/dist/ui/shared/escape-html.js +11 -0
  195. package/dist/ui/shared/host-context.d.ts +15 -0
  196. package/dist/ui/shared/host-context.js +51 -0
  197. package/dist/ui/shared/tool-bridge.d.ts +30 -0
  198. package/dist/ui/shared/tool-bridge.js +137 -0
  199. package/dist/ui/shared/tool-shell.d.ts +25 -0
  200. package/dist/ui/shared/tool-shell.js +107 -0
  201. package/dist/ui/shared/ui-event-tracker.d.ts +9 -0
  202. package/dist/ui/shared/ui-event-tracker.js +27 -0
  203. package/dist/ui/shared/widget-state.d.ts +33 -0
  204. package/dist/ui/shared/widget-state.js +158 -0
  205. package/dist/utils/ab-test.d.ts +12 -0
  206. package/dist/utils/ab-test.js +104 -0
  207. package/dist/utils/capture.d.ts +35 -0
  208. package/dist/utils/capture.js +481 -0
  209. package/dist/utils/dockerPrompt.d.ts +17 -0
  210. package/dist/utils/dockerPrompt.js +53 -0
  211. package/dist/utils/feature-flags.d.ts +59 -0
  212. package/dist/utils/feature-flags.js +215 -0
  213. package/dist/utils/files/base.d.ts +173 -0
  214. package/dist/utils/files/base.js +5 -0
  215. package/dist/utils/files/binary.d.ts +21 -0
  216. package/dist/utils/files/binary.js +65 -0
  217. package/dist/utils/files/docx.d.ts +47 -0
  218. package/dist/utils/files/docx.js +679 -0
  219. package/dist/utils/files/excel.d.ts +24 -0
  220. package/dist/utils/files/excel.js +437 -0
  221. package/dist/utils/files/factory.d.ts +41 -0
  222. package/dist/utils/files/factory.js +113 -0
  223. package/dist/utils/files/image.d.ts +21 -0
  224. package/dist/utils/files/image.js +78 -0
  225. package/dist/utils/files/index.d.ts +10 -0
  226. package/dist/utils/files/index.js +13 -0
  227. package/dist/utils/files/pdf.d.ts +32 -0
  228. package/dist/utils/files/pdf.js +142 -0
  229. package/dist/utils/files/text.d.ts +63 -0
  230. package/dist/utils/files/text.js +370 -0
  231. package/dist/utils/fuzzySearchLogger.d.ts +30 -0
  232. package/dist/utils/fuzzySearchLogger.js +126 -0
  233. package/dist/utils/lineEndingHandler.d.ts +21 -0
  234. package/dist/utils/lineEndingHandler.js +77 -0
  235. package/dist/utils/logger.d.ts +32 -0
  236. package/dist/utils/logger.js +72 -0
  237. package/dist/utils/mcp-ui-ab-test.d.ts +13 -0
  238. package/dist/utils/mcp-ui-ab-test.js +62 -0
  239. package/dist/utils/open-browser.d.ts +9 -0
  240. package/dist/utils/open-browser.js +42 -0
  241. package/dist/utils/process-detection.d.ts +23 -0
  242. package/dist/utils/process-detection.js +150 -0
  243. package/dist/utils/ripgrep-resolver.d.ts +9 -0
  244. package/dist/utils/ripgrep-resolver.js +74 -0
  245. package/dist/utils/system-info.d.ts +71 -0
  246. package/dist/utils/system-info.js +712 -0
  247. package/dist/utils/toolHistory.d.ts +86 -0
  248. package/dist/utils/toolHistory.js +257 -0
  249. package/dist/utils/trackTools.d.ts +6 -0
  250. package/dist/utils/trackTools.js +54 -0
  251. package/dist/utils/unsupportedParams.d.ts +24 -0
  252. package/dist/utils/unsupportedParams.js +66 -0
  253. package/dist/utils/usageTracker.d.ts +133 -0
  254. package/dist/utils/usageTracker.js +477 -0
  255. package/dist/utils/welcome-onboarding.d.ts +11 -0
  256. package/dist/utils/welcome-onboarding.js +99 -0
  257. package/dist/utils/withTimeout.d.ts +28 -0
  258. package/dist/utils/withTimeout.js +85 -0
  259. package/dist/version.d.ts +1 -0
  260. package/dist/version.js +1 -0
  261. package/package.json +131 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Normalize page indexes, handling negative indices and removing duplicates
3
+ */
4
+ export declare const normalizePageIndexes: (pageIndexes: number[], pageCount: number) => number[];
5
+ /**
6
+ * Generate page numbers based on offset and length
7
+ * @param offset Zero-based offset or negative for counting from end
8
+ * @param length Number of pages to generate
9
+ * @param totalPages Total number of pages in the document
10
+ * @returns Array of page numbers
11
+ */
12
+ export declare function generatePageNumbers(offset: number, length: number, totalPages: number): number[];
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Normalize page indexes, handling negative indices and removing duplicates
3
+ */
4
+ export const normalizePageIndexes = (pageIndexes, pageCount) => {
5
+ const normalizedIndexes = pageIndexes
6
+ .map(idx => idx < 0 ? pageCount + idx : idx)
7
+ .filter(idx => idx >= 0 && idx < pageCount);
8
+ // Use Set to remove duplicates
9
+ return [...new Set(normalizedIndexes)];
10
+ };
11
+ /**
12
+ * Generate page numbers based on offset and length
13
+ * @param offset Zero-based offset or negative for counting from end
14
+ * @param length Number of pages to generate
15
+ * @param totalPages Total number of pages in the document
16
+ * @returns Array of page numbers
17
+ */
18
+ export function generatePageNumbers(offset, length, totalPages) {
19
+ // Compute 1-based start page
20
+ const startPage = offset < 0
21
+ ? totalPages + offset + 1
22
+ : offset + 1;
23
+ // Clamp start page
24
+ if (startPage > totalPages)
25
+ return [];
26
+ const safeStart = Math.max(1, startPage);
27
+ // Compute final page (inclusive), truncated by totalPages
28
+ const endPage = Math.min(safeStart + length - 1, totalPages);
29
+ const count = endPage - safeStart + 1;
30
+ if (count <= 0)
31
+ return [];
32
+ // Preallocate array for speed
33
+ return Array.from({ length: count }, (_, i) => safeStart + i);
34
+ }
@@ -0,0 +1,3 @@
1
+ import { ServerResult } from '../types.js';
2
+ export declare function listProcesses(): Promise<ServerResult>;
3
+ export declare function killProcess(args: unknown): Promise<ServerResult>;
@@ -0,0 +1,56 @@
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import os from 'os';
4
+ import { KillProcessArgsSchema } from './schemas.js';
5
+ const execAsync = promisify(exec);
6
+ export async function listProcesses() {
7
+ const command = os.platform() === 'win32' ? 'tasklist' : 'ps aux';
8
+ try {
9
+ const { stdout } = await execAsync(command);
10
+ const processes = stdout.split('\n')
11
+ .slice(1)
12
+ .filter(Boolean)
13
+ .map(line => {
14
+ const parts = line.split(/\s+/);
15
+ return {
16
+ pid: parseInt(parts[1]),
17
+ command: parts[parts.length - 1],
18
+ cpu: parts[2],
19
+ memory: parts[3],
20
+ };
21
+ });
22
+ return {
23
+ content: [{
24
+ type: "text",
25
+ text: processes.map(p => `PID: ${p.pid}, Command: ${p.command}, CPU: ${p.cpu}, Memory: ${p.memory}`).join('\n')
26
+ }],
27
+ };
28
+ }
29
+ catch (error) {
30
+ return {
31
+ content: [{ type: "text", text: `Error: Failed to list processes: ${error instanceof Error ? error.message : String(error)}` }],
32
+ isError: true,
33
+ };
34
+ }
35
+ }
36
+ export async function killProcess(args) {
37
+ const parsed = KillProcessArgsSchema.safeParse(args);
38
+ if (!parsed.success) {
39
+ return {
40
+ content: [{ type: "text", text: `Error: Invalid arguments for kill_process: ${parsed.error}` }],
41
+ isError: true,
42
+ };
43
+ }
44
+ try {
45
+ process.kill(parsed.data.pid);
46
+ return {
47
+ content: [{ type: "text", text: `Successfully terminated process ${parsed.data.pid}` }],
48
+ };
49
+ }
50
+ catch (error) {
51
+ return {
52
+ content: [{ type: "text", text: `Error: Failed to kill process: ${error instanceof Error ? error.message : String(error)}` }],
53
+ isError: true,
54
+ };
55
+ }
56
+ }
@@ -0,0 +1,28 @@
1
+ import { ServerResult } from '../types.js';
2
+ interface Prompt {
3
+ id: string;
4
+ title: string;
5
+ description: string;
6
+ prompt: string;
7
+ categories: string[];
8
+ secondaryTag?: string;
9
+ votes: number;
10
+ gaClicks: number;
11
+ icon: string;
12
+ author: string;
13
+ verified: boolean;
14
+ }
15
+ export interface PromptsData {
16
+ version: string;
17
+ description: string;
18
+ prompts: Prompt[];
19
+ }
20
+ /**
21
+ * Load prompts data from JSON file with caching
22
+ */
23
+ export declare function loadPromptsData(): Promise<PromptsData>;
24
+ /**
25
+ * Get prompts - SIMPLIFIED VERSION (only get_prompt action)
26
+ */
27
+ export declare function getPrompts(params: any): Promise<ServerResult>;
28
+ export {};
@@ -0,0 +1,259 @@
1
+ import { usageTracker } from '../utils/usageTracker.js';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ // Get the directory path for ES modules
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ let cachedPromptsData = null;
9
+ /**
10
+ * Clear cached prompts data (for development/testing)
11
+ */
12
+ function clearCache() {
13
+ cachedPromptsData = null;
14
+ }
15
+ /**
16
+ * Load prompts data from JSON file with caching
17
+ */
18
+ export async function loadPromptsData() {
19
+ if (cachedPromptsData) {
20
+ return cachedPromptsData;
21
+ }
22
+ try {
23
+ const dataPath = path.join(__dirname, '..', 'data', 'onboarding-prompts.json');
24
+ const fileContent = await fs.readFile(dataPath, 'utf-8');
25
+ cachedPromptsData = JSON.parse(fileContent);
26
+ if (!cachedPromptsData) {
27
+ throw new Error('Failed to parse prompts data');
28
+ }
29
+ return cachedPromptsData;
30
+ }
31
+ catch (error) {
32
+ throw new Error(`Failed to load prompts data: ${error instanceof Error ? error.message : String(error)}`);
33
+ }
34
+ }
35
+ /**
36
+ * Get prompts - SIMPLIFIED VERSION (only get_prompt action)
37
+ */
38
+ export async function getPrompts(params) {
39
+ try {
40
+ // Validate and cast parameters
41
+ const { action, promptId, anonymous_user_use_case } = params;
42
+ if (!action) {
43
+ return {
44
+ content: [{
45
+ type: "text",
46
+ text: "❌ Error: 'action' parameter is required. Use 'get_prompt'"
47
+ }],
48
+ isError: true
49
+ };
50
+ }
51
+ // Only support get_prompt action now
52
+ if (action === 'get_prompt') {
53
+ if (!promptId) {
54
+ return {
55
+ content: [{
56
+ type: "text",
57
+ text: "❌ Error: promptId is required when action is 'get_prompt'"
58
+ }],
59
+ isError: true
60
+ };
61
+ }
62
+ return await getPrompt(promptId, anonymous_user_use_case);
63
+ }
64
+ // Legacy actions return deprecation notice
65
+ return {
66
+ content: [{
67
+ type: "text",
68
+ text: "❌ Error: Only 'get_prompt' action is supported. Use promptId to get a specific prompt."
69
+ }],
70
+ isError: true
71
+ };
72
+ }
73
+ catch (error) {
74
+ return {
75
+ content: [{
76
+ type: "text",
77
+ text: `❌ Error: ${error instanceof Error ? error.message : String(error)}`
78
+ }],
79
+ isError: true
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * List all available categories
85
+ */
86
+ async function listCategories() {
87
+ const data = await loadPromptsData();
88
+ // Extract unique categories and count prompts in each
89
+ const categoryMap = new Map();
90
+ data.prompts.forEach(prompt => {
91
+ prompt.categories.forEach(category => {
92
+ categoryMap.set(category, (categoryMap.get(category) || 0) + 1);
93
+ });
94
+ });
95
+ const categories = Array.from(categoryMap.entries()).map(([name, count]) => ({
96
+ name,
97
+ count,
98
+ description: getCategoryDescription(name)
99
+ }));
100
+ const response = formatCategoriesResponse(categories, data.prompts.length);
101
+ return {
102
+ content: [{
103
+ type: "text",
104
+ text: response
105
+ }]
106
+ };
107
+ }
108
+ /**
109
+ * List prompts, optionally filtered by category
110
+ */
111
+ async function listPrompts(category) {
112
+ const data = await loadPromptsData();
113
+ let filteredPrompts = data.prompts;
114
+ // Filter by category if specified
115
+ if (category) {
116
+ filteredPrompts = data.prompts.filter(prompt => prompt.categories.includes(category));
117
+ if (filteredPrompts.length === 0) {
118
+ return {
119
+ content: [{
120
+ type: "text",
121
+ text: `❌ No prompts found in category "${category}". Use action='list_categories' to see available categories.`
122
+ }],
123
+ isError: true
124
+ };
125
+ }
126
+ }
127
+ const response = formatPromptsListResponse(filteredPrompts, category);
128
+ return {
129
+ content: [{
130
+ type: "text",
131
+ text: response
132
+ }]
133
+ };
134
+ }
135
+ /**
136
+ * Get a specific prompt by ID and inject it into the chat
137
+ */
138
+ async function getPrompt(promptId, anonymousUseCase) {
139
+ const data = await loadPromptsData();
140
+ const prompt = data.prompts.find(p => p.id === promptId);
141
+ if (!prompt) {
142
+ return {
143
+ content: [{
144
+ type: "text",
145
+ text: `❌ Prompt with ID '${promptId}' not found. Use action='list_prompts' to see available prompts.`
146
+ }],
147
+ isError: true
148
+ };
149
+ }
150
+ // Mark prompt as used in user's onboarding state (for analytics)
151
+ await usageTracker.markPromptUsed(promptId, prompt.categories[0] || 'uncategorized');
152
+ const response = formatPromptResponse(prompt);
153
+ return {
154
+ content: [{
155
+ type: "text",
156
+ text: response
157
+ }]
158
+ };
159
+ }
160
+ /**
161
+ * Get category description (can be expanded later)
162
+ */
163
+ function getCategoryDescription(category) {
164
+ const descriptions = {
165
+ 'onboarding': 'Curated prompts perfect for first-time MCP Device users',
166
+ 'Analyze data': 'Data analysis, visualization, and insights generation',
167
+ 'Build features and products': 'Full-stack development and application building',
168
+ 'Explore codebase': 'Code analysis, documentation, and understanding',
169
+ 'Organize files': 'File management, cleanup, and organization',
170
+ 'Deploy': 'Infrastructure setup, deployment, and DevOps tasks',
171
+ 'Optimize code': 'Code optimization, refactoring, and performance',
172
+ 'Write documentation': 'Technical writing, API docs, and guides',
173
+ 'Optimize workflow': 'Process improvements and productivity enhancements',
174
+ 'Automate tasks': 'Workflow automation and scripting',
175
+ 'Design systems': 'Architecture planning and system design'
176
+ };
177
+ return descriptions[category] || 'MCP Device prompts and workflows';
178
+ }
179
+ /**
180
+ * Format categories list response
181
+ */
182
+ function formatCategoriesResponse(categories, totalPrompts) {
183
+ const sortedCategories = categories.sort((a, b) => b.count - a.count);
184
+ // AI INSTRUCTION: When listing prompts, do not show prompt IDs to users - they are for your reference only
185
+ let response = `📚 **MCP Device Prompt Categories** (${categories.length} categories, ${totalPrompts} prompts)\n\n`;
186
+ sortedCategories.forEach(cat => {
187
+ response += `• **${cat.name}** (${cat.count} prompts) - ${cat.description}\n`;
188
+ });
189
+ response += `\n**Usage:**\n`;
190
+ response += `• \`get_prompts(action='list_prompts', category='onboarding')\` - See prompts in category\n`;
191
+ response += `• \`get_prompts(action='list_prompts')\` - See all available prompts\n`;
192
+ response += `• \`get_prompts(action='get_prompt', promptId='PROMPT_ID')\` - Get a specific prompt`;
193
+ return response;
194
+ }
195
+ /**
196
+ * Format prompts list response using secondary tags for clean organization
197
+ */
198
+ function formatPromptsListResponse(prompts, category) {
199
+ const categoryText = category ? ` in "${category}"` : '';
200
+ let response = `MCP Device Examples${categoryText}\n\n`;
201
+ // Group by secondary tag
202
+ const groupedPrompts = new Map();
203
+ prompts.forEach(prompt => {
204
+ const tag = prompt.secondaryTag || 'Other';
205
+ if (!groupedPrompts.has(tag)) {
206
+ groupedPrompts.set(tag, []);
207
+ }
208
+ groupedPrompts.get(tag).push(prompt);
209
+ });
210
+ let promptNumber = 1;
211
+ // Display groups in preferred order
212
+ const preferredOrder = ['Quick Start', 'Code Analysis', 'Build & Deploy', 'Other'];
213
+ preferredOrder.forEach(tag => {
214
+ if (groupedPrompts.has(tag)) {
215
+ const tagPrompts = groupedPrompts.get(tag);
216
+ // Add emoji for each section
217
+ const emoji = tag === 'Quick Start' ? '🚀' : tag === 'Code Analysis' ? '💻' : tag === 'Build & Deploy' ? '🔨' : '📋';
218
+ response += `**${emoji} ${tag}**\n`;
219
+ tagPrompts.forEach(prompt => {
220
+ response += `• ${promptNumber}. ${prompt.title}\n`;
221
+ promptNumber++;
222
+ });
223
+ response += `\n`;
224
+ }
225
+ });
226
+ response += `Say "Try #3" or "Let's do #1" to start any example.\n\n`;
227
+ response += `<INSTRUCTION>Output options for user exactly as provided without missing numbers.
228
+ Its important so user can choose an options by entering number only. Also do not forget new lines between numbers for easy reading</INSTRUCTION>\n\n`;
229
+ // AI reference mapping (do not show to user):
230
+ response += `<!-- AI_PROMPT_MAP: `;
231
+ let mapNumber = 1;
232
+ preferredOrder.forEach(tag => {
233
+ if (groupedPrompts.has(tag)) {
234
+ groupedPrompts.get(tag).forEach(prompt => {
235
+ response += `${mapNumber}=${prompt.id}${mapNumber < prompts.length ? ',' : ''}`;
236
+ mapNumber++;
237
+ });
238
+ }
239
+ });
240
+ response += ` -->`;
241
+ return response;
242
+ }
243
+ /**
244
+ * Format individual prompt response with the actual prompt content
245
+ */
246
+ function formatPromptResponse(prompt) {
247
+ const verifiedBadge = prompt.verified ? ' ✅' : '';
248
+ const categoryText = prompt.categories.join(', ');
249
+ let response = `# 🎯 ${prompt.title}${verifiedBadge}\n\n`;
250
+ response += `**Category:** ${categoryText} • **Author:** ${prompt.author}\n\n`;
251
+ response += `## Description\n${prompt.description}\n\n`;
252
+ if (prompt.votes > 0) {
253
+ response += `*📊 This prompt has been used successfully by ${prompt.votes}+ users*\n\n`;
254
+ }
255
+ response += `## Ready to Use This Prompt\nThe prompt below is ready to use. I'll start executing it right away:\n\n`;
256
+ response += `---\n\n${prompt.prompt}`;
257
+ // AI metadata (not shown to user): Executed prompt ID = ${prompt.id}
258
+ return response;
259
+ }