@patrick-rodgers/cron-claude 0.1.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.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Windows Task Scheduler integration
3
+ * Converts cron expressions to Task Scheduler triggers and manages scheduled tasks
4
+ */
5
+ interface ScheduleTrigger {
6
+ type: 'daily' | 'weekly' | 'monthly' | 'once' | 'startup';
7
+ time?: string;
8
+ days?: string[];
9
+ interval?: number;
10
+ }
11
+ /**
12
+ * Parse cron expression and convert to Task Scheduler trigger
13
+ * Cron format: minute hour day month weekday
14
+ */
15
+ export declare function parseCronExpression(cronExpr: string): ScheduleTrigger;
16
+ /**
17
+ * Generate PowerShell command to create scheduled task
18
+ */
19
+ export declare function generateTaskSchedulerCommand(taskId: string, taskFilePath: string, trigger: ScheduleTrigger, projectRoot: string): string;
20
+ /**
21
+ * Register a task in Windows Task Scheduler
22
+ */
23
+ export declare function registerTask(taskId: string, taskFilePath: string, cronExpr: string, projectRoot: string): void;
24
+ /**
25
+ * Unregister a task from Windows Task Scheduler
26
+ */
27
+ export declare function unregisterTask(taskId: string): void;
28
+ /**
29
+ * Enable a task in Windows Task Scheduler
30
+ */
31
+ export declare function enableTask(taskId: string): void;
32
+ /**
33
+ * Disable a task in Windows Task Scheduler
34
+ */
35
+ export declare function disableTask(taskId: string): void;
36
+ /**
37
+ * Get task status from Windows Task Scheduler
38
+ */
39
+ export declare function getTaskStatus(taskId: string): {
40
+ exists: boolean;
41
+ enabled?: boolean;
42
+ lastRunTime?: string;
43
+ nextRunTime?: string;
44
+ };
45
+ export {};
46
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CA+CrE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,GAClB,MAAM,CA8DR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,IAAI,CAqBN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAenD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAe/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAehD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAsBA"}
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * Windows Task Scheduler integration
4
+ * Converts cron expressions to Task Scheduler triggers and manages scheduled tasks
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.parseCronExpression = parseCronExpression;
11
+ exports.generateTaskSchedulerCommand = generateTaskSchedulerCommand;
12
+ exports.registerTask = registerTask;
13
+ exports.unregisterTask = unregisterTask;
14
+ exports.enableTask = enableTask;
15
+ exports.disableTask = disableTask;
16
+ exports.getTaskStatus = getTaskStatus;
17
+ const child_process_1 = require("child_process");
18
+ const path_1 = require("path");
19
+ const node_cron_1 = __importDefault(require("node-cron"));
20
+ /**
21
+ * Parse cron expression and convert to Task Scheduler trigger
22
+ * Cron format: minute hour day month weekday
23
+ */
24
+ function parseCronExpression(cronExpr) {
25
+ // Validate cron expression first
26
+ if (!node_cron_1.default.validate(cronExpr)) {
27
+ throw new Error(`Invalid cron expression: ${cronExpr}`);
28
+ }
29
+ const parts = cronExpr.split(' ');
30
+ if (parts.length !== 5) {
31
+ throw new Error(`Invalid cron expression format: ${cronExpr}`);
32
+ }
33
+ const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
34
+ // Determine trigger type and details
35
+ const trigger = { type: 'daily' };
36
+ // If hour and minute are specified
37
+ if (hour !== '*' && minute !== '*') {
38
+ const hourNum = parseInt(hour);
39
+ const minuteNum = parseInt(minute);
40
+ trigger.time = `${hourNum.toString().padStart(2, '0')}:${minuteNum.toString().padStart(2, '0')}`;
41
+ }
42
+ else {
43
+ // Default to midnight
44
+ trigger.time = '00:00';
45
+ }
46
+ // Check if it's a weekly schedule (specific day of week)
47
+ if (dayOfWeek !== '*') {
48
+ trigger.type = 'weekly';
49
+ const dayMap = {
50
+ '0': 'SUN',
51
+ '1': 'MON',
52
+ '2': 'TUE',
53
+ '3': 'WED',
54
+ '4': 'THU',
55
+ '5': 'FRI',
56
+ '6': 'SAT',
57
+ '7': 'SUN',
58
+ };
59
+ trigger.days = dayOfWeek.split(',').map((d) => dayMap[d.trim()] || 'MON');
60
+ }
61
+ // Check if it's a monthly schedule (specific day of month)
62
+ else if (dayOfMonth !== '*') {
63
+ trigger.type = 'monthly';
64
+ }
65
+ return trigger;
66
+ }
67
+ /**
68
+ * Generate PowerShell command to create scheduled task
69
+ */
70
+ function generateTaskSchedulerCommand(taskId, taskFilePath, trigger, projectRoot) {
71
+ const executorPath = (0, path_1.resolve)(projectRoot, 'dist', 'executor.js');
72
+ const absoluteTaskPath = (0, path_1.resolve)(taskFilePath);
73
+ // Build the action command
74
+ const actionCommand = `node "${executorPath}" "${absoluteTaskPath}"`;
75
+ // Build trigger XML based on type
76
+ let triggerXml = '';
77
+ if (trigger.type === 'daily') {
78
+ triggerXml = `
79
+ <CalendarTrigger>
80
+ <StartBoundary>2026-01-01T${trigger.time}:00</StartBoundary>
81
+ <Enabled>true</Enabled>
82
+ <ScheduleByDay>
83
+ <DaysInterval>1</DaysInterval>
84
+ </ScheduleByDay>
85
+ </CalendarTrigger>`;
86
+ }
87
+ else if (trigger.type === 'weekly' && trigger.days) {
88
+ const daysOfWeek = trigger.days.join('');
89
+ triggerXml = `
90
+ <CalendarTrigger>
91
+ <StartBoundary>2026-01-01T${trigger.time}:00</StartBoundary>
92
+ <Enabled>true</Enabled>
93
+ <ScheduleByWeek>
94
+ <WeeksInterval>1</WeeksInterval>
95
+ <DaysOfWeek>
96
+ ${trigger.days.map((day) => `<${day} />`).join('\n ')}
97
+ </DaysOfWeek>
98
+ </ScheduleByWeek>
99
+ </CalendarTrigger>`;
100
+ }
101
+ else if (trigger.type === 'monthly') {
102
+ triggerXml = `
103
+ <CalendarTrigger>
104
+ <StartBoundary>2026-01-01T${trigger.time}:00</StartBoundary>
105
+ <Enabled>true</Enabled>
106
+ <ScheduleByMonth>
107
+ <DaysOfMonth>
108
+ <Day>1</Day>
109
+ </DaysOfMonth>
110
+ <Months>
111
+ <January /><February /><March /><April /><May /><June />
112
+ <July /><August /><September /><October /><November /><December />
113
+ </Months>
114
+ </ScheduleByMonth>
115
+ </CalendarTrigger>`;
116
+ }
117
+ // Generate PowerShell script
118
+ const psScript = `
119
+ $taskName = "CronClaude_${taskId}"
120
+ $action = New-ScheduledTaskAction -Execute "node" -Argument '"${executorPath}" "${absoluteTaskPath}"'
121
+ $trigger = New-ScheduledTaskTrigger -Daily -At "${trigger.time || '00:00'}"
122
+ $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
123
+ $principal = New-ScheduledTaskPrincipal -UserId "$env:USERNAME" -LogonType S4U
124
+
125
+ Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force
126
+ Write-Host "Task registered: $taskName"
127
+ `.trim();
128
+ return psScript;
129
+ }
130
+ /**
131
+ * Register a task in Windows Task Scheduler
132
+ */
133
+ function registerTask(taskId, taskFilePath, cronExpr, projectRoot) {
134
+ try {
135
+ console.log(`Registering task: ${taskId}`);
136
+ console.log(`Cron expression: ${cronExpr}`);
137
+ const trigger = parseCronExpression(cronExpr);
138
+ console.log(`Trigger type: ${trigger.type}, time: ${trigger.time}`);
139
+ const psCommand = generateTaskSchedulerCommand(taskId, taskFilePath, trigger, projectRoot);
140
+ // Execute PowerShell command
141
+ (0, child_process_1.execSync)(psCommand, {
142
+ shell: 'powershell.exe',
143
+ stdio: 'inherit',
144
+ });
145
+ console.log(`✓ Task "${taskId}" registered successfully`);
146
+ }
147
+ catch (error) {
148
+ console.error(`Failed to register task "${taskId}":`, error);
149
+ throw error;
150
+ }
151
+ }
152
+ /**
153
+ * Unregister a task from Windows Task Scheduler
154
+ */
155
+ function unregisterTask(taskId) {
156
+ try {
157
+ const taskName = `CronClaude_${taskId}`;
158
+ const psCommand = `Unregister-ScheduledTask -TaskName "${taskName}" -Confirm:$false`;
159
+ (0, child_process_1.execSync)(psCommand, {
160
+ shell: 'powershell.exe',
161
+ stdio: 'inherit',
162
+ });
163
+ console.log(`✓ Task "${taskId}" unregistered successfully`);
164
+ }
165
+ catch (error) {
166
+ console.error(`Failed to unregister task "${taskId}":`, error);
167
+ throw error;
168
+ }
169
+ }
170
+ /**
171
+ * Enable a task in Windows Task Scheduler
172
+ */
173
+ function enableTask(taskId) {
174
+ try {
175
+ const taskName = `CronClaude_${taskId}`;
176
+ const psCommand = `Enable-ScheduledTask -TaskName "${taskName}"`;
177
+ (0, child_process_1.execSync)(psCommand, {
178
+ shell: 'powershell.exe',
179
+ stdio: 'inherit',
180
+ });
181
+ console.log(`✓ Task "${taskId}" enabled`);
182
+ }
183
+ catch (error) {
184
+ console.error(`Failed to enable task "${taskId}":`, error);
185
+ throw error;
186
+ }
187
+ }
188
+ /**
189
+ * Disable a task in Windows Task Scheduler
190
+ */
191
+ function disableTask(taskId) {
192
+ try {
193
+ const taskName = `CronClaude_${taskId}`;
194
+ const psCommand = `Disable-ScheduledTask -TaskName "${taskName}"`;
195
+ (0, child_process_1.execSync)(psCommand, {
196
+ shell: 'powershell.exe',
197
+ stdio: 'inherit',
198
+ });
199
+ console.log(`✓ Task "${taskId}" disabled`);
200
+ }
201
+ catch (error) {
202
+ console.error(`Failed to disable task "${taskId}":`, error);
203
+ throw error;
204
+ }
205
+ }
206
+ /**
207
+ * Get task status from Windows Task Scheduler
208
+ */
209
+ function getTaskStatus(taskId) {
210
+ try {
211
+ const taskName = `CronClaude_${taskId}`;
212
+ const psCommand = `Get-ScheduledTask -TaskName "${taskName}" | Select-Object State, @{Name="LastRunTime";Expression={(Get-ScheduledTaskInfo -TaskName "${taskName}").LastRunTime}}, @{Name="NextRunTime";Expression={(Get-ScheduledTaskInfo -TaskName "${taskName}").NextRunTime}} | ConvertTo-Json`;
213
+ const output = (0, child_process_1.execSync)(psCommand, {
214
+ shell: 'powershell.exe',
215
+ encoding: 'utf-8',
216
+ stdio: 'pipe',
217
+ });
218
+ const data = JSON.parse(output);
219
+ return {
220
+ exists: true,
221
+ enabled: data.State === 'Ready',
222
+ lastRunTime: data.LastRunTime,
223
+ nextRunTime: data.NextRunTime,
224
+ };
225
+ }
226
+ catch (error) {
227
+ return { exists: false };
228
+ }
229
+ }
230
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Core types for cron-claude system
3
+ */
4
+ export interface TaskDefinition {
5
+ id: string;
6
+ schedule: string;
7
+ invocation: 'cli' | 'api';
8
+ notifications: {
9
+ toast: boolean;
10
+ };
11
+ enabled: boolean;
12
+ instructions: string;
13
+ }
14
+ export interface TaskLog {
15
+ taskId: string;
16
+ executionId: string;
17
+ timestamp: string;
18
+ status: 'success' | 'failure' | 'running';
19
+ steps: LogStep[];
20
+ signature?: string;
21
+ }
22
+ export interface LogStep {
23
+ timestamp: string;
24
+ action: string;
25
+ output?: string;
26
+ error?: string;
27
+ }
28
+ export interface LoggerConfig {
29
+ secretKey: string;
30
+ }
31
+ export interface ExecutionResult {
32
+ success: boolean;
33
+ output: string;
34
+ error?: string;
35
+ steps: LogStep[];
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE;QACb,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Core types for cron-claude system
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/install.ps1 ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env pwsh
2
+ <#
3
+ .SYNOPSIS
4
+ Install cron-claude MCP server to Claude Code configuration
5
+
6
+ .DESCRIPTION
7
+ This script registers the cron-claude MCP server with Claude Code
8
+ so it's available in all local sessions.
9
+
10
+ .EXAMPLE
11
+ .\install.ps1
12
+ #>
13
+
14
+ $ErrorActionPreference = "Stop"
15
+
16
+ Write-Host "Installing cron-claude MCP server..." -ForegroundColor Cyan
17
+
18
+ # Get the project root directory
19
+ $ProjectRoot = $PSScriptRoot
20
+ $MCPServerPath = Join-Path $ProjectRoot "dist\mcp-server.js"
21
+
22
+ # Check if the MCP server exists
23
+ if (-not (Test-Path $MCPServerPath)) {
24
+ Write-Host "Error: MCP server not found at $MCPServerPath" -ForegroundColor Red
25
+ Write-Host "Please run 'npm run build' first" -ForegroundColor Yellow
26
+ exit 1
27
+ }
28
+
29
+ # Get Claude Code config directory
30
+ $ClaudeConfigDir = Join-Path $env:USERPROFILE ".claude"
31
+ $ClaudeConfigFile = Join-Path $ClaudeConfigDir "config.json"
32
+
33
+ # Ensure config directory exists
34
+ if (-not (Test-Path $ClaudeConfigDir)) {
35
+ Write-Host "Creating Claude config directory: $ClaudeConfigDir" -ForegroundColor Yellow
36
+ New-Item -ItemType Directory -Path $ClaudeConfigDir -Force | Out-Null
37
+ }
38
+
39
+ # Read existing config or create new one
40
+ $config = @{
41
+ mcpServers = @{}
42
+ }
43
+
44
+ if (Test-Path $ClaudeConfigFile) {
45
+ Write-Host "Reading existing Claude config..." -ForegroundColor Gray
46
+ $existingConfig = Get-Content $ClaudeConfigFile -Raw | ConvertFrom-Json
47
+
48
+ # Convert PSCustomObject to hashtable
49
+ $config = @{
50
+ mcpServers = @{}
51
+ }
52
+
53
+ if ($existingConfig.mcpServers) {
54
+ foreach ($property in $existingConfig.mcpServers.PSObject.Properties) {
55
+ $config.mcpServers[$property.Name] = $property.Value
56
+ }
57
+ }
58
+ }
59
+
60
+ # Add or update cron-claude server configuration
61
+ $config.mcpServers["cron-claude"] = @{
62
+ command = "node"
63
+ args = @($MCPServerPath)
64
+ disabled = $false
65
+ }
66
+
67
+ # Write config back
68
+ Write-Host "Updating Claude config..." -ForegroundColor Gray
69
+ $config | ConvertTo-Json -Depth 10 | Set-Content $ClaudeConfigFile -Encoding UTF8
70
+
71
+ Write-Host ""
72
+ Write-Host "✓ Successfully installed cron-claude MCP server!" -ForegroundColor Green
73
+ Write-Host ""
74
+ Write-Host "Configuration saved to: $ClaudeConfigFile" -ForegroundColor Gray
75
+ Write-Host ""
76
+ Write-Host "Available MCP tools:" -ForegroundColor Cyan
77
+ Write-Host " - cron_create_task Create new scheduled tasks"
78
+ Write-Host " - cron_register_task Register with Task Scheduler"
79
+ Write-Host " - cron_list_tasks View all tasks"
80
+ Write-Host " - cron_run_task Execute task immediately"
81
+ Write-Host " - cron_enable_task Enable a task"
82
+ Write-Host " - cron_disable_task Disable a task"
83
+ Write-Host " - cron_unregister_task Remove from scheduler"
84
+ Write-Host " - cron_view_logs View execution history"
85
+ Write-Host " - cron_verify_log Verify log signatures"
86
+ Write-Host " - cron_status System information"
87
+ Write-Host " - cron_get_task Get task details"
88
+ Write-Host ""
89
+ Write-Host "Restart Claude Code to load the MCP server" -ForegroundColor Yellow
90
+ Write-Host ""
91
+ Write-Host "Test the installation by asking Claude:" -ForegroundColor Cyan
92
+ Write-Host ' "Show me my cron-claude status"' -ForegroundColor White
93
+ Write-Host ""
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@patrick-rodgers/cron-claude",
3
+ "version": "0.1.0",
4
+ "description": "Scheduled Claude task execution system - cron jobs for Claude",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "cron-claude-mcp": "./dist/mcp-server.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc --watch",
12
+ "mcp": "node dist/mcp-server.js",
13
+ "test": "echo \"Tests coming soon\"",
14
+ "prepack": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "claude",
18
+ "automation",
19
+ "cron",
20
+ "scheduler",
21
+ "windows"
22
+ ],
23
+ "author": "Patrick Rodgers",
24
+ "license": "MIT",
25
+ "files": [
26
+ "dist/",
27
+ "README.md",
28
+ "LICENSE",
29
+ "install.ps1",
30
+ "uninstall.ps1"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/patrick-rodgers/cron-claude.git"
35
+ },
36
+ "dependencies": {
37
+ "@modelcontextprotocol/sdk": "^1.0.4",
38
+ "commander": "^12.0.0",
39
+ "gray-matter": "^4.0.3",
40
+ "node-cron": "^3.0.3",
41
+ "node-notifier": "^10.0.1"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.11.0",
45
+ "@types/node-cron": "^3.0.11",
46
+ "@types/node-notifier": "^8.0.5",
47
+ "typescript": "^5.3.3"
48
+ },
49
+ "engines": {
50
+ "node": ">=18.0.0"
51
+ }
52
+ }
package/uninstall.ps1 ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env pwsh
2
+ <#
3
+ .SYNOPSIS
4
+ Uninstall cron-claude MCP server from Claude Code configuration
5
+
6
+ .DESCRIPTION
7
+ This script removes the cron-claude MCP server from Claude Code configuration.
8
+ It does not delete task files or logs.
9
+
10
+ .EXAMPLE
11
+ .\uninstall.ps1
12
+ #>
13
+
14
+ $ErrorActionPreference = "Stop"
15
+
16
+ Write-Host "Uninstalling cron-claude MCP server..." -ForegroundColor Cyan
17
+
18
+ # Get Claude Code config
19
+ $ClaudeConfigDir = Join-Path $env:USERPROFILE ".claude"
20
+ $ClaudeConfigFile = Join-Path $ClaudeConfigDir "config.json"
21
+
22
+ if (-not (Test-Path $ClaudeConfigFile)) {
23
+ Write-Host "No Claude config found. Nothing to uninstall." -ForegroundColor Yellow
24
+ exit 0
25
+ }
26
+
27
+ # Read existing config
28
+ $config = Get-Content $ClaudeConfigFile -Raw | ConvertFrom-Json
29
+
30
+ # Check if cron-claude exists
31
+ if (-not $config.mcpServers."cron-claude") {
32
+ Write-Host "cron-claude MCP server not found in config. Nothing to uninstall." -ForegroundColor Yellow
33
+ exit 0
34
+ }
35
+
36
+ # Convert to hashtable and remove cron-claude
37
+ $configHash = @{
38
+ mcpServers = @{}
39
+ }
40
+
41
+ foreach ($property in $config.mcpServers.PSObject.Properties) {
42
+ if ($property.Name -ne "cron-claude") {
43
+ $configHash.mcpServers[$property.Name] = $property.Value
44
+ }
45
+ }
46
+
47
+ # Write config back
48
+ $configHash | ConvertTo-Json -Depth 10 | Set-Content $ClaudeConfigFile -Encoding UTF8
49
+
50
+ Write-Host ""
51
+ Write-Host "✓ Successfully uninstalled cron-claude MCP server!" -ForegroundColor Green
52
+ Write-Host ""
53
+ Write-Host "Restart Claude Code for changes to take effect" -ForegroundColor Yellow
54
+ Write-Host ""
55
+ Write-Host "Note: Task files and logs have NOT been deleted." -ForegroundColor Gray
56
+ Write-Host "To remove completely:" -ForegroundColor Gray
57
+ Write-Host " - Delete task files: $PSScriptRoot\tasks\" -ForegroundColor Gray
58
+ Write-Host " - Delete config: $env:USERPROFILE\.cron-claude\" -ForegroundColor Gray
59
+ Write-Host ""