No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Mike 'Fuzzy' Partin e9cd7f534b
All checks were successful
CI / test (pull_request) Successful in 51s
CI / lint (pull_request) Successful in 1m20s
fix(engine): remove redundant str() wrapping around call_tool return
call_tool() already returns str, so the str() wrapper was
unnecessary. Added type: ignore for mypy's no-any-return.
Closes #146
2026-07-05 11:13:50 -07:00
.forgejo/workflows ci: remove upload-artifact step (not supported on GHES) 2026-07-05 06:15:53 -07:00
docs feat(config): support KRONAI_CONFIG env var for config path 2026-07-05 17:24:21 +00:00
src/kronai fix(engine): remove redundant str() wrapping around call_tool return 2026-07-05 11:13:50 -07:00
tests feat(notifications): add SMTP_SSL support for implicit TLS 2026-07-05 11:01:43 -07:00
.editorconfig chore: add project foundation files 2026-07-05 05:24:15 -07:00
.gitignore chore: add project foundation files 2026-07-05 05:24:15 -07:00
.pre-commit-config.yaml chore: add comprehensive pre-commit configuration 2026-07-05 05:24:23 -07:00
kronai.toml.example feat(config): support KRONAI_LLM_API_KEY env var as secure alternative 2026-07-05 09:01:32 -07:00
LICENSE docs: add MIT license 2026-07-05 05:28:01 -07:00
pyproject.toml feat(cli): implement full CLI interface with list/run/interval commands 2026-07-05 07:30:49 -07:00
README.md docs: fix pip install reference (not on PyPI yet) 2026-07-05 10:47:33 -07:00
requirements-dev.txt chore: add dependency files for virtual environment 2026-07-05 05:34:39 -07:00
requirements.txt chore: add dependency files for virtual environment 2026-07-05 05:34:39 -07:00
ROADMAP.md docs: mark Phase 5 Task 2 complete 2026-07-05 08:49:55 -07:00

KronAI

AI-powered cron job scheduler. KronAI watches a jobs directory, discovers job configurations, and sends prompts to LLM APIs (OpenAI-compatible) on a schedule. Supports MCP (Model Context Protocol) servers for tool-augmented completions.

Installation

pip install kronai  # Not yet on PyPI — install from source below

Or from source:

git clone https://git.lan.thwap.org/thwap/kronai.git
cd kronai
python -m venv .venv
source .venv/bin/activate
pip install -e .

Quick Start

1. Create a jobs directory

/var/lib/kronai/jobs/
  hourly/
    1/
      prompt.md          # The prompt to send to the LLM
      config.toml         # Optional job config
      name                # Optional human-readable name
      description         # Optional description

2. Write a prompt

What is the current weather in San Francisco?

3. Run it

# Run a single job by ID
kronai run 1

# Run all hourly jobs
kronai hourly

4. Schedule with cron

0 * * * * kronai hourly >> /var/log/kronai/cron.log 2>&1
0 3 * * * kronai daily >> /var/log/kronai/cron.log 2>&1

See docs/cron-integration.md for systemd and detailed cron setup.

Configuration

Search paths (first found wins):

  1. /etc/kronai/config.toml
  2. ~/.config/kronai/config.toml
  3. ./kronai.toml
  4. --config PATH flag

Example kronai.toml

jobs_dir = "/var/lib/kronai/jobs"
log_dir = "/var/lib/kronai/logs"
log_level = "INFO"
json_logs = false
# log_max_bytes = 10485760
# log_backup_count = 5

llm_endpoint = "https://api.openai.com/v1"
llm_api_key = "sk-..."        # Or set via env
default_model = "gpt-4o"
default_temperature = 0.7
default_max_tokens = 2048

[mcp_servers]
# [mcp_servers.filesystem]
# command = "npx"
# args = ["-y", "@modelcontextprotocol/server-filesystem"]

Job-specific config.toml

Placed inside a job directory, overrides global config:

model = "gpt-4o-mini"
temperature = 0.3
max_tokens = 1024
system_prompt = "You are a helpful coding assistant."
mcp_servers = ["filesystem"]
env = { DEBUG = "true" }

Usage

kronai list              # List all jobs with IDs, names, descriptions
kronai run <id|name>     # Run a job by numeric ID or symlink name
kronai hourly            # Run all hourly jobs
kronai daily             # Run all daily jobs
kronai weekly            # Run all weekly jobs
kronai monthly           # Run all monthly jobs
kronai --config PATH     # Use explicit config file
kronai --log-level DEBUG # Override log level

Job Directories

Structure

jobs/
  hourly/
    1/
      prompt.md           # Required: prompt text
      config.toml         # Optional: job-specific config
      name                # Optional: human-readable name
      description         # Optional: description (shown in list)
      .ephemeral          # Optional: marker for run-once jobs
      .recurring          # Optional: marker for persistent jobs (default)
    my-report -> 1/       # Symlink: named alias to job ID
  daily/
    1/
      prompt.md

Create symlinks in the interval directory to give jobs friendly names:

ln -s 1 /var/lib/kronai/jobs/hourly/my-report

Then run by name:

kronai run my-report

Job Types

  • Recurring (default): Job persists after running. Results saved to results/TIMESTAMP/output.md.
  • Ephemeral: Job directory is deleted after successful run. Add a .ephemeral marker file:
touch /var/lib/kronai/jobs/hourly/1/.ephemeral

MCP Servers

KronAI supports MCP servers for tool-augmented LLM completions. Configure servers in kronai.toml and reference them in job configs.

[mcp_servers]
[mcp_servers.filesystem]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem"]

In your job's config.toml:

mcp_servers = ["filesystem"]

Logging

  • Console output to stderr
  • File logging with rotation to {log_dir}/kronai.log
  • JSON structured logs via json_logs = true
  • Configurable via log_level, log_max_bytes, log_backup_count

API

Supported LLM APIs

Any OpenAI-compatible API endpoint:

  • OpenAI
  • Anthropic (via API proxy)
  • Local models (Ollama, vLLM, LM Studio, etc.)
  • Azure OpenAI

Set the endpoint and key in config:

llm_endpoint = "http://localhost:11434/v1"  # Ollama example
llm_api_key = ""                              # Not needed for local
default_model = "llama3"

Development

git clone https://git.lan.thwap.org/thwap/kronai.git
cd kronai
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pre-commit install
pytest

License

MIT — see LICENSE. Copyright (c) 2026 T.H.W.A.P. Labs and Mike 'Fuzzy' Partin.