schedule_recurring_task
Schedule automated Jules coding tasks to run on a cron schedule for recurring maintenance like bug fixes, refactoring, or tests, with server-managed offline execution.
Instructions
Schedule a Jules task to run automatically on a cron schedule. The server manages execution even when offline.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_name | Yes | Unique name for this schedule | |
| cron_expression | Yes | Cron expression (e.g., "0 9 * * 1" for Mondays at 9 AM) | |
| prompt | Yes | Task instruction | |
| source | Yes | Repository resource name | |
| branch | No | main | |
| auto_create_pr | No | ||
| require_plan_approval | No | ||
| timezone | No | Timezone for cron |
Implementation Reference
- src/mcp/tools.ts:268-322 (handler)The handler function for schedule_recurring_task. Validates input, checks for existing schedules, creates and persists a ScheduledTask, and schedules it with the CronEngine.async scheduleRecurringTask( args: z.infer<typeof ScheduleTaskSchema> ): Promise<string> { return this.executeWithErrorHandling(async () => { // Validate cron expression if (!CronEngine.validateCronExpression(args.cron_expression)) { throw new Error( `Invalid cron expression: ${args.cron_expression}. Format: minute hour day month weekday` ); } // Check for name collision const existing = await this.storage.getTaskByName(args.task_name); if (existing) { throw new Error( `A schedule named "${args.task_name}" already exists. Use delete_schedule first or choose a different name.` ); } // SECURITY: Validate repository allowlist RepositoryValidator.validateRepository(args.source); // Create scheduled task const task: ScheduledTask = { id: randomUUID(), name: args.task_name, cron: args.cron_expression, taskPayload: { prompt: args.prompt, source: args.source, branch: args.branch, automationMode: args.auto_create_pr ? 'AUTO_CREATE_PR' : 'AUTOMATION_MODE_UNSPECIFIED', requirePlanApproval: args.require_plan_approval, }, timezone: args.timezone, createdAt: new Date().toISOString(), enabled: true, }; // Persist and schedule await this.storage.upsertTask(task); this.scheduler.scheduleTask(task); const nextRun = this.scheduler.getNextInvocation(task.id); return { message: `Task "${args.task_name}" scheduled successfully`, scheduleId: task.id, cron: args.cron_expression, nextExecution: nextRun?.toISOString() || 'Unknown', }; }); }
- src/mcp/tools.ts:75-117 (schema)Zod input schema for validating parameters to the schedule_recurring_task tool.export const ScheduleTaskSchema = z.object({ task_name: z .string() .min(1, 'Task name cannot be empty') .max(100, 'Task name must not exceed 100 characters') .regex(/^[\w\s-]+$/, 'Task name can only contain letters, numbers, spaces, hyphens, and underscores') .describe('Unique name for this schedule (e.g., "Weekly Dependency Update")'), cron_expression: z .string() .regex(/^[\d\s*,/-]+$/, 'Cron expression contains invalid characters') .describe( 'Standard cron expression (e.g., "0 9 * * 1" for Mondays at 9 AM). Format: minute hour day month weekday' ), prompt: z .string() .min(10, 'Prompt must be at least 10 characters') .max(10000, 'Prompt must not exceed 10,000 characters') .describe('The coding task instruction to execute'), source: z .string() .regex( /^sources\/github\/[\w-]+\/[\w-]+$/, 'Source must be in format sources/github/owner/repo' ) .describe('Repository resource name (sources/github/owner/repo)'), branch: z .string() .regex(/^[\w/-]+$/, 'Branch name contains invalid characters') .default('main') .describe('Git branch to target'), auto_create_pr: z .boolean() .default(true) .describe('Whether to auto-create PRs'), require_plan_approval: z .boolean() .default(false) .describe('Whether to require manual plan approval'), timezone: z .string() .optional() .describe('Timezone for cron execution (e.g., "America/New_York")'), });
- src/index.ts:259-286 (registration)MCP tool registration: metadata, description, and input schema definition exposed via ListToolsRequestSchema.name: 'schedule_recurring_task', description: 'Schedule a Jules task to run automatically on a cron schedule. The server manages execution even when offline.', inputSchema: { type: 'object', properties: { task_name: { type: 'string', description: 'Unique name for this schedule', }, cron_expression: { type: 'string', description: 'Cron expression (e.g., "0 9 * * 1" for Mondays at 9 AM)', }, prompt: { type: 'string', description: 'Task instruction' }, source: { type: 'string', description: 'Repository resource name', }, branch: { type: 'string', default: 'main' }, auto_create_pr: { type: 'boolean', default: true }, require_plan_approval: { type: 'boolean', default: false }, timezone: { type: 'string', description: 'Timezone for cron' }, }, required: ['task_name', 'cron_expression', 'prompt', 'source'], }, },
- src/index.ts:334-337 (registration)Dispatch handler in CallToolRequestSchema switch that validates args with ScheduleTaskSchema and calls the tool method.case 'schedule_recurring_task': { const validated = ScheduleTaskSchema.parse(args); result = await this.tools.scheduleRecurringTask(validated); break;