@wonderwhy-er/desktop-commander 0.2.14 → 0.2.15
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 +43 -0
- package/dist/custom-stdio.js +4 -2
- package/dist/index.js +28 -10
- package/dist/server.d.ts +1 -0
- package/dist/server.js +17 -5
- package/dist/types.d.ts +1 -0
- package/dist/utils/usageTracker.js +15 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,6 +86,11 @@ For debugging mode (allows Node.js inspector connection):
|
|
|
86
86
|
```
|
|
87
87
|
npx @wonderwhy-er/desktop-commander@latest setup --debug
|
|
88
88
|
```
|
|
89
|
+
|
|
90
|
+
**Command line options during setup:**
|
|
91
|
+
- `--debug`: Enable debugging mode for Node.js inspector
|
|
92
|
+
- `--no-onboarding`: Disable onboarding prompts for new users
|
|
93
|
+
|
|
89
94
|
Restart Claude if running.
|
|
90
95
|
|
|
91
96
|
**✅ Auto-Updates:** Yes - automatically updates when you restart Claude
|
|
@@ -652,6 +657,44 @@ set_config_value({ "key": "fileWriteLineLimit", "value": 25 })
|
|
|
652
657
|
|
|
653
658
|
4. **Always verify configuration after changes**: Use `get_config({})` to confirm your changes were applied correctly.
|
|
654
659
|
|
|
660
|
+
## Command Line Options
|
|
661
|
+
|
|
662
|
+
Desktop Commander supports several command line options for customizing behavior:
|
|
663
|
+
|
|
664
|
+
### Disable Onboarding
|
|
665
|
+
|
|
666
|
+
By default, Desktop Commander shows helpful onboarding prompts to new users (those with fewer than 10 tool calls). You can disable this behavior:
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
# Disable onboarding for this session
|
|
670
|
+
node dist/index.js --no-onboarding
|
|
671
|
+
|
|
672
|
+
# Or if using npm scripts
|
|
673
|
+
npm run start:no-onboarding
|
|
674
|
+
|
|
675
|
+
# For npx installations, modify your claude_desktop_config.json:
|
|
676
|
+
{
|
|
677
|
+
"mcpServers": {
|
|
678
|
+
"desktop-commander": {
|
|
679
|
+
"command": "npx",
|
|
680
|
+
"args": [
|
|
681
|
+
"-y",
|
|
682
|
+
"@wonderwhy-er/desktop-commander@latest",
|
|
683
|
+
"--no-onboarding"
|
|
684
|
+
]
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
**When onboarding is automatically disabled:**
|
|
691
|
+
- When the MCP client name is set to "desktop-commander"
|
|
692
|
+
- When using the `--no-onboarding` flag
|
|
693
|
+
- After users have used onboarding prompts or made 10+ tool calls
|
|
694
|
+
|
|
695
|
+
**Debug information:**
|
|
696
|
+
The server will log when onboarding is disabled: `"Onboarding disabled via --no-onboarding flag"`
|
|
697
|
+
|
|
655
698
|
## Using Different Shells
|
|
656
699
|
|
|
657
700
|
You can specify which shell to use for command execution:
|
package/dist/custom-stdio.js
CHANGED
|
@@ -22,14 +22,16 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
22
22
|
this.setupConsoleRedirection();
|
|
23
23
|
// Setup stdout filtering for any other output
|
|
24
24
|
this.setupStdoutFiltering();
|
|
25
|
-
//
|
|
26
|
-
|
|
25
|
+
// Note: We defer the initialization notification until enableNotifications() is called
|
|
26
|
+
// to ensure MCP protocol compliance - notifications must not be sent before initialization
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Call this method after MCP initialization is complete to enable JSON-RPC notifications
|
|
30
30
|
*/
|
|
31
31
|
enableNotifications() {
|
|
32
32
|
this.isInitialized = true;
|
|
33
|
+
// Send the deferred initialization notification first
|
|
34
|
+
this.sendLogNotification('info', ['Enhanced FilteredStdioServerTransport initialized']);
|
|
33
35
|
// Replay all buffered messages in chronological order
|
|
34
36
|
if (this.messageBuffer.length > 0) {
|
|
35
37
|
this.sendLogNotification('info', [`Replaying ${this.messageBuffer.length} buffered initialization messages`]);
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { FilteredStdioServerTransport } from './custom-stdio.js';
|
|
3
|
-
import { server } from './server.js';
|
|
3
|
+
import { server, flushDeferredMessages } from './server.js';
|
|
4
4
|
import { configManager } from './config-manager.js';
|
|
5
5
|
import { runSetup } from './npm-scripts/setup.js';
|
|
6
6
|
import { runUninstall } from './npm-scripts/uninstall.js';
|
|
7
7
|
import { capture } from './utils/capture.js';
|
|
8
8
|
import { logToStderr, logger } from './utils/logger.js';
|
|
9
|
+
// Store messages to defer until after initialization
|
|
10
|
+
const deferredMessages = [];
|
|
11
|
+
function deferLog(level, message) {
|
|
12
|
+
deferredMessages.push({ level, message });
|
|
13
|
+
}
|
|
9
14
|
async function runServer() {
|
|
10
15
|
try {
|
|
11
16
|
// Check if first argument is "setup"
|
|
@@ -18,17 +23,24 @@ async function runServer() {
|
|
|
18
23
|
await runUninstall();
|
|
19
24
|
return;
|
|
20
25
|
}
|
|
26
|
+
// Parse command line arguments for onboarding control
|
|
27
|
+
const DISABLE_ONBOARDING = process.argv.includes('--no-onboarding');
|
|
28
|
+
if (DISABLE_ONBOARDING) {
|
|
29
|
+
logToStderr('info', 'Onboarding disabled via --no-onboarding flag');
|
|
30
|
+
}
|
|
31
|
+
// Set global flag for onboarding control
|
|
32
|
+
global.disableOnboarding = DISABLE_ONBOARDING;
|
|
21
33
|
try {
|
|
22
|
-
|
|
34
|
+
deferLog('info', 'Loading configuration...');
|
|
23
35
|
await configManager.loadConfig();
|
|
24
|
-
|
|
36
|
+
deferLog('info', 'Configuration loaded successfully');
|
|
25
37
|
}
|
|
26
38
|
catch (configError) {
|
|
27
|
-
|
|
39
|
+
deferLog('error', `Failed to load configuration: ${configError instanceof Error ? configError.message : String(configError)}`);
|
|
28
40
|
if (configError instanceof Error && configError.stack) {
|
|
29
|
-
|
|
41
|
+
deferLog('debug', `Stack trace: ${configError.stack}`);
|
|
30
42
|
}
|
|
31
|
-
|
|
43
|
+
deferLog('warning', 'Continuing with in-memory configuration only');
|
|
32
44
|
// Continue anyway - we'll use an in-memory config
|
|
33
45
|
}
|
|
34
46
|
const transport = new FilteredStdioServerTransport();
|
|
@@ -63,17 +75,23 @@ async function runServer() {
|
|
|
63
75
|
process.exit(1);
|
|
64
76
|
});
|
|
65
77
|
capture('run_server_start');
|
|
66
|
-
|
|
78
|
+
deferLog('info', 'Connecting server...');
|
|
67
79
|
// Set up event-driven initialization completion handler
|
|
68
80
|
server.oninitialized = () => {
|
|
69
81
|
// This callback is triggered after the client sends the "initialized" notification
|
|
70
82
|
// At this point, the MCP protocol handshake is fully complete
|
|
71
83
|
transport.enableNotifications();
|
|
72
|
-
//
|
|
73
|
-
|
|
84
|
+
// Flush all deferred messages from both index.ts and server.ts
|
|
85
|
+
while (deferredMessages.length > 0) {
|
|
86
|
+
const msg = deferredMessages.shift();
|
|
87
|
+
transport.sendLog('info', msg.message);
|
|
88
|
+
}
|
|
89
|
+
flushDeferredMessages();
|
|
90
|
+
// Now we can send regular logging messages
|
|
91
|
+
transport.sendLog('info', 'Server connected successfully');
|
|
92
|
+
transport.sendLog('info', 'MCP fully initialized, all startup messages sent');
|
|
74
93
|
};
|
|
75
94
|
await server.connect(transport);
|
|
76
|
-
logToStderr('info', 'Server connected successfully');
|
|
77
95
|
}
|
|
78
96
|
catch (error) {
|
|
79
97
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -18,8 +18,20 @@ import { usageTracker } from './utils/usageTracker.js';
|
|
|
18
18
|
import { processDockerPrompt } from './utils/dockerPrompt.js';
|
|
19
19
|
import { VERSION } from './version.js';
|
|
20
20
|
import { capture, capture_call_tool } from "./utils/capture.js";
|
|
21
|
-
import { logToStderr } from './utils/logger.js';
|
|
22
|
-
|
|
21
|
+
import { logToStderr, logger } from './utils/logger.js';
|
|
22
|
+
// Store startup messages to send after initialization
|
|
23
|
+
const deferredMessages = [];
|
|
24
|
+
function deferLog(level, message) {
|
|
25
|
+
deferredMessages.push({ level, message });
|
|
26
|
+
}
|
|
27
|
+
// Function to flush deferred messages after initialization
|
|
28
|
+
export function flushDeferredMessages() {
|
|
29
|
+
while (deferredMessages.length > 0) {
|
|
30
|
+
const msg = deferredMessages.shift();
|
|
31
|
+
logger.info(msg.message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
deferLog('info', 'Loading server.ts');
|
|
23
35
|
export const server = new Server({
|
|
24
36
|
name: "desktop-commander",
|
|
25
37
|
version: VERSION,
|
|
@@ -57,8 +69,8 @@ server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
|
57
69
|
name: clientInfo.name || 'unknown',
|
|
58
70
|
version: clientInfo.version || 'unknown'
|
|
59
71
|
};
|
|
60
|
-
//
|
|
61
|
-
|
|
72
|
+
// Defer client connection message until after initialization
|
|
73
|
+
deferLog('info', `Client connected: ${currentClient.name} v${currentClient.version}`);
|
|
62
74
|
}
|
|
63
75
|
// Return standard initialization response
|
|
64
76
|
return {
|
|
@@ -82,7 +94,7 @@ server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
|
82
94
|
});
|
|
83
95
|
// Export current client info for access by other modules
|
|
84
96
|
export { currentClient };
|
|
85
|
-
|
|
97
|
+
deferLog('info', 'Setting up request handlers...');
|
|
86
98
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
87
99
|
try {
|
|
88
100
|
logToStderr('debug', 'Generating tools list...');
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ChildProcess } from 'child_process';
|
|
|
2
2
|
import { FilteredStdioServerTransport } from './custom-stdio.js';
|
|
3
3
|
declare global {
|
|
4
4
|
var mcpTransport: FilteredStdioServerTransport | undefined;
|
|
5
|
+
var disableOnboarding: boolean | undefined;
|
|
5
6
|
}
|
|
6
7
|
export interface ProcessInfo {
|
|
7
8
|
pid: number;
|
|
@@ -299,6 +299,21 @@ class UsageTracker {
|
|
|
299
299
|
* Check if user should see onboarding invitation - SIMPLE VERSION
|
|
300
300
|
*/
|
|
301
301
|
async shouldShowOnboarding() {
|
|
302
|
+
// Check if onboarding is disabled via command line argument
|
|
303
|
+
if (global.disableOnboarding) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
// Check if client is desktop-commander (disable for this client)
|
|
307
|
+
try {
|
|
308
|
+
const { currentClient } = await import('../server.js');
|
|
309
|
+
if (currentClient?.name === 'desktop-commander') {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
// If we can't import server, continue with other checks
|
|
315
|
+
console.log('[ONBOARDING DEBUG] Could not check client name, continuing...');
|
|
316
|
+
}
|
|
302
317
|
const stats = await this.getStats();
|
|
303
318
|
const onboardingState = await this.getOnboardingState();
|
|
304
319
|
const now = Date.now();
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.15";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.2.
|
|
1
|
+
export const VERSION = '0.2.15';
|
package/package.json
CHANGED