@hcu-lab.me/mcp-device 1.0.6 → 1.0.7

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 (44) hide show
  1. package/README.md +7 -71
  2. package/dist/bootstrap.js +1 -1
  3. package/dist/config-manager.js +1 -1
  4. package/dist/config.js +1 -1
  5. package/dist/custom-stdio.js +1 -2
  6. package/dist/data/onboarding-prompts.json +22 -11
  7. package/dist/device/device-state.d.ts +0 -5
  8. package/dist/device/device-state.js +0 -84
  9. package/dist/device/device.d.ts +1 -1
  10. package/dist/device/device.js +8 -7
  11. package/dist/device/execution-engine.d.ts +10 -1
  12. package/dist/device/execution-engine.js +81 -128
  13. package/dist/device/gateway-channel.d.ts +6 -0
  14. package/dist/device/gateway-channel.js +16 -1
  15. package/dist/device/gateway-tool-adapter.d.ts +3 -3
  16. package/dist/device/gateway-tool-adapter.js +12 -11
  17. package/dist/device/linux-service.d.ts +4 -0
  18. package/dist/device/linux-service.js +10 -3
  19. package/dist/device/runtime-owner.js +2 -2
  20. package/dist/device/windows-service.d.ts +3 -4
  21. package/dist/device/windows-service.js +5 -44
  22. package/dist/npm-scripts/remote.js +0 -2
  23. package/dist/server.js +9 -99
  24. package/dist/terminal-manager.js +1 -1
  25. package/dist/tools/config.d.ts +1 -1
  26. package/dist/tools/filesystem.js +3 -3
  27. package/dist/tools/pdf/markdown.js +1 -1
  28. package/dist/tools/schemas.d.ts +2 -3
  29. package/dist/tools/schemas.js +0 -10
  30. package/dist/ui/config-editor/index.html +1 -1
  31. package/dist/ui/file-preview/index.html +1 -1
  32. package/dist/ui/file-preview/styles.css +2 -2
  33. package/dist/utils/capture.d.ts +5 -28
  34. package/dist/utils/capture.js +11 -455
  35. package/dist/utils/feature-flags.d.ts +0 -47
  36. package/dist/utils/feature-flags.js +5 -199
  37. package/dist/utils/files/docx.d.ts +2 -2
  38. package/dist/utils/files/docx.js +2 -2
  39. package/dist/utils/usageTracker.js +0 -24
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.js +1 -1
  42. package/package.json +5 -6
  43. package/dist/tools/feedback.d.ts +0 -8
  44. package/dist/tools/feedback.js +0 -132
@@ -21,12 +21,11 @@ function isMissingRegistrationError(error) {
21
21
  export function buildWindowsTaskName(deviceId) {
22
22
  return `MCP-Device-${taskSafeDeviceId(deviceId)}`;
23
23
  }
24
- function legacyWindowsTaskName(deviceId) {
25
- return `HCU-Device-${taskSafeDeviceId(deviceId)}`;
26
- }
27
24
  export function buildWindowsRunnerScript(options) {
25
+ const runtimeDir = options.runtimeDir ? String(options.runtimeDir) : deviceStatePaths().runtime;
28
26
  return [
29
27
  "$ErrorActionPreference = 'Stop'",
28
+ `Set-Location -LiteralPath ${psQuote(runtimeDir)}`,
30
29
  `& ${psQuote(options.nodePath)} ${psQuote(options.entrypoint)} --service`,
31
30
  'exit $LASTEXITCODE',
32
31
  ''
@@ -40,9 +39,9 @@ export class WindowsDeviceService {
40
39
  return { stdout: String(result.stdout || ''), stderr: String(result.stderr || '') };
41
40
  });
42
41
  this.runnerPath = path.resolve(options.runnerPath || path.join(deviceStatePaths().root, 'run-device.ps1'));
43
- this.legacyRunnerPath = path.resolve(options.legacyRunnerPath || path.join(deviceStatePaths().legacyRoot, 'run-device.ps1'));
44
42
  this.nodePath = path.resolve(options.nodePath || process.execPath);
45
43
  this.entrypoint = path.resolve(options.entrypoint || process.argv[1]);
44
+ this.runtimeDir = options.runtimeDir ? String(options.runtimeDir) : deviceStatePaths().runtime;
46
45
  }
47
46
  assertWindows() {
48
47
  if (this.platform !== 'win32')
@@ -91,41 +90,6 @@ export class WindowsDeviceService {
91
90
  }
92
91
  catch { /* absent is fine */ }
93
92
  }
94
- commandReferencesLegacyRunner(value) {
95
- const normalize = (text) => String(text || '').replace(/\//g, '\\').toLowerCase();
96
- return normalize(value).includes(normalize(this.legacyRunnerPath));
97
- }
98
- async deleteVerifiedLegacyRegistrations(taskName) {
99
- let scheduledAction = null;
100
- try {
101
- const command = `(Get-ScheduledTask -TaskName ${psQuote(taskName)} -ErrorAction Stop).Actions | ForEach-Object { ($_.Execute + ' ' + $_.Arguments) }`;
102
- scheduledAction = String((await this.execFile('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', command])).stdout || '');
103
- }
104
- catch { /* absent scheduled task is fine */ }
105
- if (scheduledAction !== null && this.commandReferencesLegacyRunner(scheduledAction)) {
106
- try {
107
- await this.execFile('schtasks.exe', ['/Delete', '/F', '/TN', taskName]);
108
- }
109
- catch (error) {
110
- if (!isMissingRegistrationError(error))
111
- throw error;
112
- }
113
- }
114
- let runValue = null;
115
- try {
116
- runValue = String((await this.execFile('reg.exe', ['query', USER_RUN_KEY, '/v', taskName])).stdout || '');
117
- }
118
- catch { /* absent Run value is fine */ }
119
- if (runValue !== null && this.commandReferencesLegacyRunner(runValue)) {
120
- try {
121
- await this.execFile('reg.exe', ['delete', USER_RUN_KEY, '/v', taskName, '/f']);
122
- }
123
- catch (error) {
124
- if (!isMissingRegistrationError(error))
125
- throw error;
126
- }
127
- }
128
- }
129
93
  async createAutostartRegistration(taskName) {
130
94
  const taskAction = `powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${this.runnerPath}"`;
131
95
  try {
@@ -157,13 +121,12 @@ export class WindowsDeviceService {
157
121
  async install(options) {
158
122
  this.assertWindows();
159
123
  const taskName = buildWindowsTaskName(options.deviceId);
160
- const legacyTaskName = legacyWindowsTaskName(options.deviceId);
161
124
  const existing = await this.status(options.deviceId).catch(() => null);
162
125
  const preserveManual = existing?.installed === true && existing.autostart === false;
163
- const runner = buildWindowsRunnerScript({ nodePath: this.nodePath, entrypoint: this.entrypoint });
126
+ const runner = buildWindowsRunnerScript({ nodePath: this.nodePath, entrypoint: this.entrypoint, runtimeDir: this.runtimeDir });
127
+ await fs.mkdir(this.runtimeDir, { recursive: true, mode: 0o700 });
164
128
  await fs.mkdir(path.dirname(this.runnerPath), { recursive: true });
165
129
  await fs.writeFile(this.runnerPath, runner, { mode: 0o600 });
166
- await this.deleteVerifiedLegacyRegistrations(legacyTaskName);
167
130
  if (preserveManual) {
168
131
  await this.deleteRegistrations(taskName);
169
132
  return;
@@ -226,13 +189,11 @@ export class WindowsDeviceService {
226
189
  async uninstall(deviceId) {
227
190
  this.assertWindows();
228
191
  const taskName = buildWindowsTaskName(deviceId);
229
- const legacyTaskName = legacyWindowsTaskName(deviceId);
230
192
  try {
231
193
  await this.stop(deviceId);
232
194
  }
233
195
  catch { /* registration cleanup remains authoritative; runtime is never PID-killed. */ }
234
196
  await this.deleteRegistrations(taskName);
235
- await this.deleteVerifiedLegacyRegistrations(legacyTaskName);
236
197
  await fs.rm(this.runnerPath, { force: true });
237
198
  }
238
199
  }
@@ -325,8 +325,6 @@ async function serviceCommand(command) {
325
325
  }
326
326
  export async function runRemote() {
327
327
  // MCP Device owns its account-scoped usage telemetry at the gateway.
328
- // Never send inherited Desktop Commander analytics from the remote execution path.
329
- process.env.DESKTOP_COMMANDER_DISABLE_TELEMETRY = 'true';
330
328
  const disableNoSleep = process.argv.includes('--disable-no-sleep');
331
329
  const verbose = process.argv.includes('--debug');
332
330
  if (!verbose)
package/dist/server.js CHANGED
@@ -1,4 +1,3 @@
1
- import path from 'path';
2
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
2
  import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, ListPromptsRequestSchema, InitializeRequestSchema, LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, } from "@modelcontextprotocol/sdk/types.js";
4
3
  import { zodToJsonSchema } from "zod-to-json-schema";
@@ -9,11 +8,10 @@ const OS_GUIDANCE = getOSSpecificGuidance(SYSTEM_INFO);
9
8
  const DEV_TOOL_GUIDANCE = getDevelopmentToolGuidance(SYSTEM_INFO);
10
9
  const PATH_GUIDANCE = `IMPORTANT: ${getPathGuidance(SYSTEM_INFO)} Relative paths may fail as they depend on the current working directory. Tilde paths (~/...) might not work in all contexts. Unless the user explicitly asks for relative paths, use absolute paths.`;
11
10
  const CMD_PREFIX_DESCRIPTION = `This command can be referenced as "MCP Device: ..." or "use MCP Device to ..." in your instructions.`;
12
- import { StartProcessArgsSchema, ReadProcessOutputArgsSchema, InteractWithProcessArgsSchema, ForceTerminateArgsSchema, ListSessionsArgsSchema, KillProcessArgsSchema, ReadFileArgsSchema, ReadMultipleFilesArgsSchema, WriteFileArgsSchema, CreateDirectoryArgsSchema, ListDirectoryArgsSchema, MoveFileArgsSchema, GetFileInfoArgsSchema, GetConfigArgsSchema, SetConfigValueArgsSchema, ListProcessesArgsSchema, EditBlockArgsSchema, GetUsageStatsArgsSchema, GiveFeedbackArgsSchema, StartSearchArgsSchema, GetMoreSearchResultsArgsSchema, StopSearchArgsSchema, ListSearchesArgsSchema, GetPromptsArgsSchema, GetRecentToolCallsArgsSchema, WritePdfArgsSchema, toolArgSchemas, } from './tools/schemas.js';
11
+ import { StartProcessArgsSchema, ReadProcessOutputArgsSchema, InteractWithProcessArgsSchema, ForceTerminateArgsSchema, ListSessionsArgsSchema, KillProcessArgsSchema, ReadFileArgsSchema, ReadMultipleFilesArgsSchema, WriteFileArgsSchema, CreateDirectoryArgsSchema, ListDirectoryArgsSchema, MoveFileArgsSchema, GetFileInfoArgsSchema, GetConfigArgsSchema, SetConfigValueArgsSchema, ListProcessesArgsSchema, EditBlockArgsSchema, GetUsageStatsArgsSchema, StartSearchArgsSchema, GetMoreSearchResultsArgsSchema, StopSearchArgsSchema, ListSearchesArgsSchema, GetPromptsArgsSchema, GetRecentToolCallsArgsSchema, WritePdfArgsSchema, toolArgSchemas, } from './tools/schemas.js';
13
12
  import { detectUnsupportedParams, getSupportedParams, buildUnsupportedParamsWarning, } from './utils/unsupportedParams.js';
14
13
  import { getConfig, setConfigValue } from './tools/config.js';
15
14
  import { getUsageStats } from './tools/usage.js';
16
- import { giveFeedbackToDesktopCommander } from './tools/feedback.js';
17
15
  import { getPrompts } from './tools/prompts.js';
18
16
  import { trackToolCall } from './utils/trackTools.js';
19
17
  import { usageTracker } from './utils/usageTracker.js';
@@ -89,7 +87,7 @@ function setCurrentCallIsRemote(isRemote) {
89
87
  currentCallIsRemote = isRemote;
90
88
  }
91
89
  // The remote caller's client for the in-flight tool call (e.g. openai-mcp,
92
- // claude-ai). Set per CallTool when the call is remote; null for local calls.
90
+ // remote client). Set per CallTool when the call is remote; null for local calls.
93
91
  // Mirrors currentCallIsRemote so telemetry attributes remote events to the
94
92
  // actual remote client instead of the device's own currentClient (which stays
95
93
  // LOCAL and must not be polluted by remote callers).
@@ -104,11 +102,10 @@ function setCurrentRemoteClient(clientInfo) {
104
102
  /**
105
103
  * True when this server instance is serving remote services rather than a
106
104
  * local MCP client. The device wrapper marks the server it spawns with
107
- * MCP_DEVICE_REMOTE=true (see device/execution-engine.ts);
108
- * the client-name check covers older wrappers that predate the env marker.
105
+ * MCP_DEVICE_REMOTE=true (see device/execution-engine.ts).
109
106
  */
110
107
  function isRemoteClientContext(clientName) {
111
- return process.env.MCP_DEVICE_REMOTE === 'true' || clientName === 'desktop-commander-client';
108
+ return process.env.MCP_DEVICE_REMOTE === 'true';
112
109
  }
113
110
  /**
114
111
  * Unified way to update client information
@@ -138,44 +135,19 @@ server.setRequestHandler(InitializeRequestSchema, async (request) => {
138
135
  const clientInfo = request.params?.clientInfo;
139
136
  if (clientInfo) {
140
137
  await updateCurrentClient(clientInfo);
141
- // Welcome page for new users (A/B test controlled) — all clients except
142
- // the Desktop Commander app and remote contexts. Further exclusions are
143
- // flag-served via welcome_page_excluded_clients (e.g. claude-code, which
144
- // covers Claude Code and Cowork plugin sessions — both identify as
145
- // `claude-code` and provide their own onboarding surface).
146
- const isWelcomePageEligibleClient = currentClient.name !== 'desktop-commander-app'
147
- && currentClient.name !== 'desktop-commander'
148
- && !isRemoteClientContext(currentClient.name)
138
+ const isWelcomePageEligibleClient = !isRemoteClientContext(currentClient.name)
149
139
  && !global.disableOnboarding;
150
140
  if (isRemoteClientContext(currentClient.name)) {
151
- // Remote MCP Device children must not mutate local onboarding
152
- // state merely because they initialized an inherited MCP server.
141
+ // Remote child engines do not mutate local onboarding state.
153
142
  }
154
143
  else if (isWelcomePageEligibleClient) {
155
144
  await handleWelcomePageOnboarding(currentClient.name);
156
145
  }
157
146
  else {
158
- // Do not carry a first-run page over to a client that is made
159
- // eligible in a later release.
160
147
  await skipWelcomePageOnboarding();
161
148
  }
149
+ capture('run_server_mcp_initialized');
162
150
  }
163
- // Raw host environment signals (no PII, undefined when absent). Some
164
- // hosts share a clientInfo name — Claude Code CLI, Claude Code inside
165
- // the Claude Desktop app, and Cowork all report 'claude-code' — and
166
- // these let analytics tell them apart without client-specific
167
- // branching in code. Verified signatures: CLI → entrypoint 'cli';
168
- // CC-in-desktop → entrypoint 'claude-desktop'; Cowork → no
169
- // entrypoint/agent, plugin id 'desktop-commander-inline'.
170
- // Values truncated to GA4's 100-char param limit (same convention as
171
- // containerName/containerImage) so an oversized value can never get
172
- // the whole event rejected.
173
- capture('run_server_mcp_initialized', {
174
- host_entrypoint: process.env.CLAUDE_CODE_ENTRYPOINT?.substring(0, 100),
175
- host_agent: process.env.AI_AGENT?.substring(0, 100),
176
- host_plugin_id: process.env.CLAUDE_PLUGIN_DATA
177
- ? path.basename(process.env.CLAUDE_PLUGIN_DATA).substring(0, 100) : undefined
178
- });
179
151
  // Negotiate protocol version with client
180
152
  const requestedVersion = request.params?.protocolVersion;
181
153
  const protocolVersion = (requestedVersion && SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion))
@@ -207,15 +179,7 @@ deferLog('info', 'Setting up request handlers...');
207
179
  /**
208
180
  * Check if a tool should be included based on current client
209
181
  */
210
- function shouldIncludeTool(toolName) {
211
- // Exclude these tools for desktop-commander client (DC-specific meta-tools not useful when DC itself is the client)
212
- if (currentClient?.name === 'desktop-commander-app') {
213
- if (toolName === 'give_feedback_to_desktop_commander' || toolName === 'get_prompts') {
214
- return false;
215
- }
216
- }
217
- // Add more conditional tool logic here as needed
218
- // Example: if (toolName === 'some_tool' && currentClient?.name === 'some_client') return false;
182
+ function shouldIncludeTool(_toolName) {
219
183
  return true;
220
184
  }
221
185
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -1073,48 +1037,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
1073
1037
  readOnlyHint: true,
1074
1038
  },
1075
1039
  },
1076
- {
1077
- name: "give_feedback_to_desktop_commander",
1078
- description: `
1079
- Open feedback form in browser to provide feedback about MCP Device.
1080
-
1081
- IMPORTANT: This tool simply opens the feedback form - no pre-filling available.
1082
- The user will fill out the form manually in their browser.
1083
-
1084
- WORKFLOW:
1085
- 1. When user agrees to give feedback, just call this tool immediately
1086
- 2. No need to ask questions or collect information
1087
- 3. Tool opens form with only usage statistics pre-filled automatically:
1088
- - tool_call_count: Number of commands they've made
1089
- - days_using: How many days they've used MCP Device
1090
- - platform: Their operating system (Mac/Windows/Linux)
1091
- - client_id: Analytics identifier
1092
-
1093
- All survey questions will be answered directly in the form:
1094
- - Job title and technical comfort level
1095
- - Company URL for industry context
1096
- - Other AI tools they use
1097
- - MCP Device's biggest advantage
1098
- - How they typically use it
1099
- - Recommendation likelihood (0-10)
1100
- - User study participation interest
1101
- - Email and any additional feedback
1102
-
1103
- EXAMPLE INTERACTION:
1104
- User: "sure, I'll give feedback"
1105
- Claude: "Perfect! Let me open the feedback form for you."
1106
- [calls tool immediately]
1107
-
1108
- No parameters are needed - just call the tool to open the form.
1109
-
1110
- ${CMD_PREFIX_DESCRIPTION}`,
1111
- inputSchema: zodToJsonSchema(GiveFeedbackArgsSchema),
1112
- annotations: {
1113
- title: "Give Feedback",
1114
- readOnlyHint: false,
1115
- openWorldHint: true,
1116
- },
1117
- },
1118
1040
  {
1119
1041
  name: "get_prompts",
1120
1042
  description: `
@@ -1194,7 +1116,7 @@ async function handleCallToolRequest(request) {
1194
1116
  // add remote flag (convert to string for telemetry)
1195
1117
  telemetryData.remote = String(metadata.remote);
1196
1118
  // Remote calls carry the originating MCP client (e.g. openai-mcp,
1197
- // claude-ai) in _meta.clientInfo. Attribute this call to that remote
1119
+ // remote client) in _meta.clientInfo. Attribute this call to that remote
1198
1120
  // client — NOT the device's own currentClient. Fall back to a sentinel
1199
1121
  // when it's absent so the call is visibly remote-but-unattributed
1200
1122
  // rather than masquerading as the local device client. We deliberately
@@ -1336,18 +1258,6 @@ async function handleCallToolRequest(request) {
1336
1258
  };
1337
1259
  }
1338
1260
  break;
1339
- case "give_feedback_to_desktop_commander":
1340
- try {
1341
- result = await giveFeedbackToDesktopCommander(args);
1342
- }
1343
- catch (error) {
1344
- capture('server_request_error', { message: `Error in give_feedback_to_desktop_commander handler: ${error}` });
1345
- result = {
1346
- content: [{ type: "text", text: `Error: Failed to open feedback form` }],
1347
- isError: true,
1348
- };
1349
- }
1350
- break;
1351
1261
  // Terminal tools
1352
1262
  case "start_process":
1353
1263
  result = await handlers.handleStartProcess(args);
@@ -8,7 +8,7 @@ import { analyzeProcessState } from './utils/process-detection.js';
8
8
  * Standard Windows PATHEXT value, used to repair a corrupted PATHEXT before
9
9
  * spawning child shells.
10
10
  *
11
- * On some Windows Claude Desktop / DXT launches the server process inherits a
11
+ * On some Windows host launches the server process inherits a
12
12
  * broken PATHEXT (observed as ".CPL" only). Because we build the child env from
13
13
  * { ...process.env }, that broken value would propagate into every spawned
14
14
  * shell, stripping ".EXE" and breaking resolution of git / node / python / rg /
@@ -65,7 +65,7 @@ export declare function getConfig(): Promise<{
65
65
  availableShells: string[];
66
66
  };
67
67
  entries: {
68
- key: "defaultShell" | "blockedCommands" | "allowedDirectories" | "telemetryEnabled" | "fileReadLineLimit" | "fileWriteLineLimit";
68
+ key: "blockedCommands" | "defaultShell" | "allowedDirectories" | "telemetryEnabled" | "fileWriteLineLimit" | "fileReadLineLimit";
69
69
  value: unknown;
70
70
  valueType: "string" | "number" | "boolean" | "array";
71
71
  editable: boolean;
@@ -84,10 +84,10 @@ function buildPermissionError(filePath, errCode) {
84
84
  ` 5. The app does not have permission to access this location (macOS Full Disk Access).`,
85
85
  ];
86
86
  if (isMac) {
87
- lines.push(` → Go to System Settings → Privacy & Security → Full Disk Access and enable Claude.`);
87
+ lines.push(` → Go to System Settings → Privacy & Security → Full Disk Access and enable the terminal or runtime hosting MCP Device.`);
88
88
  lines.push(` → To open that pane directly, run in terminal:`);
89
89
  lines.push(` open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"`);
90
- lines.push(` Then find "Claude" in the list and enable the toggle next to it.`);
90
+ lines.push(` Then enable the toggle for the application that launches MCP Device.`);
91
91
  }
92
92
  else {
93
93
  lines.push(` → Check that the app has permission to access this file location.`);
@@ -265,7 +265,7 @@ export async function validatePath(requestedPath) {
265
265
  const pathForNextCheck = resolvedRealPath ?? absoluteOriginal;
266
266
  // Direct Gateway device workers are already authenticated and policy-gated by
267
267
  // the central gateway. In that dedicated remote context, do not inherit a
268
- // workstation's historical Desktop Commander directory allowlist. An optional
268
+ // workstation's historical directory allowlist. An optional
269
269
  // MCP_GATEWAY_ALLOWED_ROOTS restriction is enforced by GatewayToolAdapter before
270
270
  // calls reach this filesystem layer.
271
271
  const remoteGatewayContext = process.env.MCP_DEVICE_REMOTE === 'true';
@@ -9,7 +9,7 @@ const isUrl = (source) => source.startsWith('http://') || source.startsWith('htt
9
9
  let cachedChromePath = null; // null = not checked yet
10
10
  let chromeCheckPromise = null;
11
11
  /**
12
- * Get Desktop Commander's private Puppeteer cache directory.
12
+ * Get the local engine's private Puppeteer cache directory.
13
13
  */
14
14
  function getPuppeteerCacheDir() {
15
15
  return join(dirname(CONFIG_FILE), 'puppeteer-cache');
@@ -117,15 +117,15 @@ export declare const WriteFileArgsSchema: z.ZodObject<{
117
117
  mode: z.ZodDefault<z.ZodEnum<["rewrite", "append"]>>;
118
118
  origin: z.ZodOptional<z.ZodEnum<["ui", "llm"]>>;
119
119
  }, "strip", z.ZodTypeAny, {
120
+ mode: "rewrite" | "append";
120
121
  path: string;
121
122
  content: string;
122
- mode: "rewrite" | "append";
123
123
  origin?: "ui" | "llm" | undefined;
124
124
  }, {
125
125
  path: string;
126
126
  content: string;
127
- origin?: "ui" | "llm" | undefined;
128
127
  mode?: "rewrite" | "append" | undefined;
128
+ origin?: "ui" | "llm" | undefined;
129
129
  }>;
130
130
  export declare const PdfInsertOperationSchema: z.ZodObject<{
131
131
  type: z.ZodLiteral<"insert">;
@@ -348,7 +348,6 @@ export declare const InteractWithProcessArgsSchema: z.ZodObject<{
348
348
  wait_for_prompt?: boolean | undefined;
349
349
  }>;
350
350
  export declare const GetUsageStatsArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
351
- export declare const GiveFeedbackArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
352
351
  export declare const StartSearchArgsSchema: z.ZodObject<{
353
352
  path: z.ZodString;
354
353
  pattern: z.ZodString;
@@ -153,15 +153,6 @@ export const InteractWithProcessArgsSchema = z.object({
153
153
  });
154
154
  // Usage stats schema
155
155
  export const GetUsageStatsArgsSchema = z.object({});
156
- // Feedback tool schema - no pre-filled parameters, all user input
157
- export const GiveFeedbackArgsSchema = z.object({
158
- // No parameters needed - form will be filled manually by user
159
- // Only auto-filled hidden fields remain:
160
- // - tool_call_count (auto)
161
- // - days_using (auto)
162
- // - platform (auto)
163
- // - client_id (auto)
164
- });
165
156
  // Search schemas (renamed for natural language)
166
157
  export const StartSearchArgsSchema = z.object({
167
158
  path: z.string(),
@@ -236,7 +227,6 @@ export const toolArgSchemas = {
236
227
  kill_process: KillProcessArgsSchema,
237
228
  get_usage_stats: GetUsageStatsArgsSchema,
238
229
  get_recent_tool_calls: GetRecentToolCallsArgsSchema,
239
- give_feedback_to_desktop_commander: GiveFeedbackArgsSchema,
240
230
  get_prompts: GetPromptsArgsSchema,
241
231
  track_ui_event: TrackUiEventArgsSchema,
242
232
  };
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Desktop Commander Config Editor</title>
6
+ <title>MCP Device Config Editor</title>
7
7
  <link rel="stylesheet" href="./styles.css" />
8
8
  </head>
9
9
  <body>
@@ -6,7 +6,7 @@
6
6
  <head>
7
7
  <meta charset="utf-8" />
8
8
  <meta name="viewport" content="width=device-width, initial-scale=1" />
9
- <title>Desktop Commander File Preview</title>
9
+ <title>MCP Device File Preview</title>
10
10
  <link rel="stylesheet" href="./styles.css" />
11
11
  </head>
12
12
  <body>
@@ -141,7 +141,7 @@ body.dc-ready {
141
141
 
142
142
 
143
143
  /*
144
- * App-specific styling for File Preview — tuned to blend with Claude's UI.
144
+ * App-specific styling for File Preview — tuned for the MCP Device UI.
145
145
  */
146
146
  :root {
147
147
  --code-bg: var(--panel);
@@ -166,7 +166,7 @@ body.dc-ready {
166
166
  --toc-rail-width: 320px;
167
167
  }
168
168
 
169
- /* ── Panel (Claude-style card) ── */
169
+ /* ── Panel (compact card) ── */
170
170
 
171
171
  .panel {
172
172
  margin-top: 6px;
@@ -1,35 +1,12 @@
1
1
  export declare function runInUiOriginCallContext<T>(fn: () => T): T;
2
2
  export declare function isInsideUiOriginCall(): boolean;
3
- /**
4
- * Hard kill-switch for telemetry via environment variable.
5
- *
6
- * Independent of the persisted `telemetryEnabled` config so that tests, CI and
7
- * one-off runs can suppress all analytics without mutating the user's config.
8
- * Set DESKTOP_COMMANDER_DISABLE_TELEMETRY to 1/true/yes/on to disable.
9
- */
10
3
  export declare function isTelemetryDisabledByEnv(): boolean;
11
- /**
12
- * Sanitizes error objects to remove potentially sensitive information like file paths
13
- * @param error Error object or string to sanitize
14
- * @returns An object with sanitized message and optional error code
15
- */
16
4
  export declare function sanitizeError(error: any): {
17
5
  message: string;
18
6
  code?: string;
19
7
  };
20
- /**
21
- * Send an event to telemetry
22
- * @param event Event name
23
- * @param properties Optional event properties
24
- */
25
- export declare const captureBase: (captureURL: string, event: string, properties?: any) => Promise<void>;
26
- export declare const capture: (event: string, properties?: any) => Promise<void>;
27
- export declare const capture_call_tool: (event: string, properties?: any) => Promise<void>;
28
- export declare const capture_ui_event: (event: string, properties?: any) => Promise<void>;
29
- /**
30
- * Wrapper for capture() that automatically adds remote flag for device telemetry
31
- * Also adds additional privacy filtering to remove sensitive identity information
32
- * @param event Event name
33
- * @param properties Optional event properties
34
- */
35
- export declare const captureRemote: (event: string, properties?: any) => Promise<void>;
8
+ export declare const captureBase: (_captureURL: string, _event: string, _properties?: any) => Promise<void>;
9
+ export declare const capture: (_event: string, _properties?: any) => Promise<void>;
10
+ export declare const capture_call_tool: (_event: string, _properties?: any) => Promise<void>;
11
+ export declare const capture_ui_event: (_event: string, _properties?: any) => Promise<void>;
12
+ export declare const captureRemote: (_event: string, _properties?: any) => Promise<void>;