Skip to main content
Glama
volokovartem12-a11y

MCP Scheduler

День 18. MCP-планировщик и фоновые задачи

Готовый учебный проект: MCP-сервер принимает задания, фоновый worker выполняет их по расписанию, а все данные и результаты сохраняются в SQLite.

Проект работает локально и не требует API-ключей или платных запросов.

Что реализовано

  • одноразовые и повторяющиеся напоминания;

  • периодический сбор числовых метрик;

  • регулярная агрегированная сводка;

  • хранение заданий, запусков, метрик и уведомлений в SQLite;

  • восстановление просроченных заданий после перезапуска;

  • атомарный захват заданий и защита от повторной записи результата двумя worker-процессами;

  • управление заданиями: список, просмотр, пауза, продолжение и отмена;

  • MCP через stdio или Streamable HTTP;

  • режим постоянной работы с автоматическим перезапуском;

  • полностью локальные тесты и короткая демонстрация.

Related MCP server: Schedule Task MCP

Как это устроено

MCP-клиент
    │ создаёт задания / читает результаты
    ▼
MCP-сервер ───────► SQLite ◄─────── фоновый worker
                       │                 │
                       ├─ задания        ├─ проверяет расписание
                       ├─ метрики        ├─ выполняет задания
                       ├─ запуски        └─ сохраняет результаты
                       └─ уведомления

Если MCP-клиент отключён, напоминание или сводка не теряются. Worker сохраняет их в SQLite, а клиент получает их при следующем вызове get_notifications.

Быстрый запуск в PowerShell

Откройте PowerShell и выполните:

cd "$env:USERPROFILE\Desktop\day-18-mcp-scheduler"

# Нужно только если Windows запрещает запуск локальных ps1-файлов.
Set-ExecutionPolicy -Scope Process Bypass

.\scripts\setup.ps1
.\scripts\test.ps1
.\scripts\demo.ps1

Что произойдёт:

  1. setup.ps1 создаст отдельное Python-окружение .venv и установит зависимости.

  2. test.ps1 проверит базу, расписание, агрегацию и восстановление.

  3. demo.ps1 за несколько секунд создаст reminder, сборщик и summary, затем покажет JSON-результат.

Запуск MCP-сервера

Вариант 1: Streamable HTTP

.\scripts\run-mcp.ps1

Адрес MCP-сервера:

http://127.0.0.1:8000/mcp

В этом режиме MCP-сервер и worker работают вместе. Пока окно PowerShell открыто, задания выполняются по расписанию.

Вариант 2: stdio

.\scripts\run-mcp.ps1 -Transport stdio

stdio обычно запускает сам MCP-клиент. Такой процесс остановится вместе с клиентом, поэтому для постоянной работы удобнее HTTP-режим.

Только фоновый worker

.\scripts\run-worker.ps1

Это полезно, если MCP-сервер и worker нужно держать в разных процессах. Они используют один файл data\scheduler.db.

Режим 24/7

.\scripts\run-24x7.ps1

Скрипт держит HTTP-сервер и worker запущенными и перезапускает процесс после сбоя. Для остановки нажмите Ctrl+C.

Важно: на обычном компьютере «24/7» означает, что Windows включена, не находится в спящем режиме и окно PowerShell не закрыто. Для сервера или Docker используйте:

docker compose up -d --build
docker compose logs -f

В compose.yaml включён restart: unless-stopped, а SQLite хранится в отдельном Docker volume.

Сервер по умолчанию доступен только на 127.0.0.1. Не публикуйте его через 0.0.0.0 в интернет без аутентификации на reverse proxy и правил firewall. Защита от DNS rebinding включена явно. Для разрешённого внешнего домена задайте SCHEDULER_ALLOWED_HOSTS и SCHEDULER_ALLOWED_ORIGINS списками через запятую.

Проверка живого MCP-запроса

В первом окне PowerShell запустите сервер:

.\scripts\run-mcp.ps1

Во втором окне выполните:

.\scripts\smoke-live.ps1

Проверка подключится к /mcp, покажет список инструментов, создаст быстрое напоминание и дождётся сохранённого уведомления.

Чтобы вызывать отдельные MCP-инструменты прямо из PowerShell, используйте обёртку scripts\call-tool.ps1. Сервер должен быть запущен в другом окне.

.\scripts\call-tool.ps1 -Tool list-tools
.\scripts\call-tool.ps1 -Tool scheduler_status

Команды PowerShell для функций программы

1. Отложенное напоминание

Напоминание через 60 секунд:

.\scripts\call-tool.ps1 -Tool schedule_reminder -Arguments '{"message":"Проверить отчёт","delay_seconds":60}'

Или в заданное время (нужен часовой пояс):

.\scripts\call-tool.ps1 -Tool schedule_reminder -Arguments '{"message":"Начать встречу","run_at":"2026-09-24T10:00:00+03:00"}'

2. Повторяющееся напоминание

Повторять каждые 3600 секунд, всего 5 раз:

.\scripts\call-tool.ps1 -Tool schedule_reminder -Arguments '{"name":"Перерыв","message":"Пора размяться","delay_seconds":10,"repeat_seconds":3600,"max_runs":5}'

3. Периодический сбор метрики

Собирать значение orders раз в 10 секунд; значения будут 10, 12, 14 и 16:

.\scripts\call-tool.ps1 -Tool schedule_metric_collection -Arguments '{"metric":"orders","interval_seconds":10,"initial_value":10,"increment":2,"max_runs":4}'

4. Регулярная сводка

Сводка по orders каждые 60 секунд за последний час:

.\scripts\call-tool.ps1 -Tool schedule_summary -Arguments '{"metric":"orders","interval_seconds":60,"lookback_seconds":3600}'

5. Записать метрику вручную

.\scripts\call-tool.ps1 -Tool record_metric -Arguments '{"metric":"orders","value":42,"labels":{"source":"manual"}}'

6. Посмотреть список заданий

.\scripts\call-tool.ps1 -Tool list_jobs -Arguments '{"limit":100}'

В ответе каждого задания есть поле id; оно понадобится для управления.

7. Посмотреть, приостановить, возобновить или отменить задание

Скопируйте UUID из поля id и вставьте его без символов < и >. Например, возьмём активное задание из списка:

$jobId = "3c3ee3ac-22ea-4326-aa62-c82e0a1b5a21"
$jobArgs = @{ job_id = $jobId } | ConvertTo-Json -Compress

.\scripts\call-tool.ps1 -Tool get_job -Arguments $jobArgs
.\scripts\call-tool.ps1 -Tool pause_job -Arguments $jobArgs
.\scripts\call-tool.ps1 -Tool resume_job -Arguments $jobArgs
.\scripts\call-tool.ps1 -Tool cancel_job -Arguments $jobArgs

Возобновить можно только задание в статусе paused. Выполненное (completed) или отменённое (cancelled) задание повторно запустить нельзя. cancel_job отменяет следующие запуски периодического задания.

8. Получить уведомления и готовые сводки

.\scripts\call-tool.ps1 -Tool get_notifications -Arguments '{"unread_only":true,"limit":100}'

Чтобы сразу пометить полученные уведомления прочитанными, добавьте "mark_read":true.

9. Посчитать агрегат

.\scripts\call-tool.ps1 -Tool get_aggregate -Arguments '{"metric":"orders"}'

Можно ограничить период, передав since и until в ISO 8601 с часовым поясом.

10. История запусков и статус базы

.\scripts\call-tool.ps1 -Tool get_executions -Arguments '{"limit":100}'
.\scripts\call-tool.ps1 -Tool scheduler_status
.\scripts\status.ps1

11. Восстановление после перезапуска

Worker запускается вместе с HTTP MCP-сервером. Нажмите Ctrl+C, чтобы его остановить, затем снова выполните run-mcp.ps1 или run-24x7.ps1. Задания, метрики и уведомления останутся в data\scheduler.db.

12. Очистка старой истории

Worker автоматически очищает метрики и историю запусков старше 30 дней; старые прочитанные уведомления тоже удаляются. Чтобы изменить срок в текущем окне PowerShell перед запуском сервера:

$env:SCHEDULER_RETENTION_DAYS = "7"
.\scripts\run-mcp.ps1

Значение 0 выключает автоматическую очистку.

MCP-инструменты

Инструмент

Что делает

schedule_reminder

Создаёт reminder на дату или через указанное число секунд

schedule_metric_collection

Периодически записывает тестовую числовую метрику

schedule_summary

Периодически считает и сохраняет сводку за окно времени

record_metric

Записывает числовую метрику вручную

list_jobs

Показывает задания

get_job

Показывает одно задание

pause_job

Ставит задание на паузу

resume_job

Возобновляет задание

cancel_job

Отменяет будущие запуски

get_notifications

Возвращает накопленные reminders и summaries

get_aggregate

Возвращает count, sum, average, minimum, maximum, последнее значение

get_executions

Показывает историю запусков и результаты

scheduler_status

Показывает общую статистику SQLite

Все ответы инструментов структурированы как JSON.

Пример сценария для агента

Попросите подключённого MCP-агента:

1. Создай сбор метрики orders каждые 5 секунд:
   initial_value=10, increment=2, max_runs=5.
2. Создай summary по orders каждые 15 секунд за последние 60 секунд.
3. Через 20 секунд покажи get_notifications и get_aggregate для orders.

Ожидаемый рост метрики:

10 → 12 → 14 → 16 → 18

Итоговый агрегат:

{
  "count": 5,
  "sum": 70.0,
  "average": 14.0,
  "minimum": 10.0,
  "maximum": 18.0
}

Формат времени

Для run_at, recorded_at, since и until нужен ISO 8601 с часовым поясом:

2026-09-23T18:00:00+03:00
2026-09-23T15:00:00Z

Время без Z или смещения отклоняется, чтобы напоминание не сработало в неверный момент. В SQLite всё хранится в UTC.

Что происходит после простоя

  • одноразовое просроченное задание выполнится после запуска worker;

  • у периодического задания выполняется один актуальный запуск;

  • сотни пропущенных интервалов не создают «лавину» запусков;

  • следующий запуск рассчитывается от расписания, а не от времени окончания, поэтому интервалы не дрейфуют;

  • lease в SQLite позволяет другому worker продолжить задание после аварии первого процесса.

По умолчанию worker раз в час удаляет метрики и историю запусков старше 30 дней, а также старые прочитанные уведомления. Непрочитанные reminders и summaries не удаляются. Срок меняется через SCHEDULER_RETENTION_DAYS; значение 0 отключает очистку. Демо использует очень короткие интервалы только для быстрой проверки — для постоянной работы выбирайте разумный интервал и max_runs.

Файлы данных

По умолчанию база находится здесь:

data\scheduler.db

Можно указать другой файл только для текущего окна PowerShell:

$env:SCHEDULER_DB_PATH = "C:\scheduler-data\scheduler.db"
.\scripts\run-mcp.ps1

Текущий статус базы:

.\scripts\status.ps1

Файлы .db, .db-wal и .db-shm исключены из Git.

Выгрузка на GitHub

Создайте на GitHub пустой репозиторий, затем в PowerShell выполните команды. В последней команде замените ВАШ_ЛОГИН на свой логин GitHub:

cd "$env:USERPROFILE\Desktop\day-18-mcp-scheduler"
git init
git add .
git commit -m "Day 18: add persistent MCP scheduler"
git branch -M main
git remote add origin https://github.com/ВАШ_ЛОГИН/day-18-mcp-scheduler.git
git push -u origin main

Папка .venv, SQLite-файлы и локальные настройки исключены из Git. Не добавляйте API-ключи в проект: для этой работы они не нужны.

Соответствие заданию

  • сохраняет данные: SQLite;

  • выполняется по расписанию: отдельный async worker;

  • отложенный запуск: schedule_reminder;

  • периодический запуск: collector, recurring reminder и summary;

  • возвращает агрегат: get_aggregate и summary-уведомления;

  • работает постоянно: Streamable HTTP + worker, PowerShell restart loop или Docker;

  • результат не пропадает: история и уведомления остаются в SQLite после перезапуска.

Технологии

  • Python 3.11+;

  • официальный MCP Python SDK 2.2.0;

  • SQLite из стандартной библиотеки Python;

  • asyncio для фонового цикла;

  • pytest для тестов.

Официальные материалы MCP

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables recording, querying, and summarizing daily work entries with tags using a local SQLite database. Supports work logging, search, timeline queries, tag management, and automated reminders for tracking daily tasks.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables creation and management of scheduled tasks with interval, cron, or one-time triggers. Persists tasks in SQLite and supports MCP sampling to automatically invoke AI agents when schedules trigger.
    5 npm
    3
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Integrates simulated health data and task management to provide energy-aware scheduling based on calculated readiness scores. It allows users to query health summaries, manage tasks, and generate optimized daily schedules through a local SQLite database.
    5
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to schedule and manage reminders across platforms like email, Slack, Discord, and webhooks. It provides tools to create, list, update, and cancel notifications to automate task reminders and agent wake-ups.
    4
    4 npm
    1
    MIT