Calgent is a terminal-first natural-language Google Calendar CLI.
Type an event in plain English, review the parsed result, and let Calgent create the event in Google Calendar after confirmation.
calgent lunch with damien tomorrow 6pmCalgent uses Gemini for structured parsing, deterministic Python validation for safety, and the Google Calendar API for event creation.
- Parse natural-language event requests from the terminal.
- Resolve relative dates like
tomorrowusing the current date, time, and system timezone. - Ask clarification questions when the request is ambiguous.
- Confirm inferred recurrence before creating recurring events.
- Infer importance and map it to calendar colors.
- Create Google Calendar events through OAuth.
- Support dry runs for parser and workflow testing.
- Python 3.12+
uvfor dependency and tool management- A Gemini API key
- A Google Cloud OAuth desktop client with Google Calendar API enabled
Clone the repository:
git clone https://github.com/curtischang2510/calgent.git
cd calgentInstall dependencies:
uv sync --extra devRun checks:
uv run pytest
uv run ruff check .Install the CLI globally with uv tool:
uv tool install --editable . --forceAfter that, calgent should work from any directory:
calgent --helpCreate a local environment file:
cp .env.example .envEdit .env and set:
GEMINI_API_KEY=your_gemini_api_key
CALGENT_MODEL=gemini-2.5-flash-lite
CALGENT_FALLBACK_MODELS=gemini-2.0-flash-lite,gemini-2.0-flash
CALGENT_GEMINI_TIMEOUT_SECONDS=30Check that the key is present and formatted correctly:
calgent --check-gemini-keyThis check does not make an API call.
- Open Google Cloud Console.
- Create or select a project.
- Enable the Google Calendar API.
- Configure the OAuth consent screen.
- If the app is in testing mode, add your Google account as a test user.
- Create an OAuth client ID.
- Choose
Desktop appas the application type. - Download the JSON credentials file.
- Rename it to
credentials.json. - Place it in the project root next to
pyproject.toml.
credentials.example.json shows the expected shape, but it is not a real credential file.
The first real calendar write opens a browser OAuth flow and creates token.json. Both credentials.json and token.json are ignored by git.
Optional calendar target:
CALGENT_CALENDAR_NAME=primaryBy default, Calgent writes to Google Calendar's primary calendar unless CALGENT_CALENDAR_NAME is set.
Dry run without creating a calendar event:
calgent lunch with damien tomorrow 6pm --dry-runCreate an event after confirmation:
calgent lunch with damien tomorrow 6pmSkip the confirmation prompt:
calgent lunch with damien tomorrow 6pm --yesMore examples:
calgent CS3210 exam 26th June 2026 3-5pm
calgent anniversary 30th January recurring yearly
calgent anniversary 30th Jan
calgent pay bills on 30th of monthIf Gemini infers recurrence that the user did not explicitly request, Calgent asks before accepting that recurrence:
Should this be a monthly recurring event?
Calgent separates the workflow into testable harness boundaries:
terminal input -> Gemini parser -> deterministic validation -> clarification/confirmation -> Google Calendar writer
The model does not write to Google Calendar directly. It only returns structured event data. Python then validates the event, applies product rules, asks clarifying questions, and only calls Google Calendar after confirmation.
When a clarification is needed, Calgent keeps an in-memory transcript for the current command. Each Gemini call includes:
- the original request,
- the current date and time,
- the system timezone,
- the previous parsed event,
- and the clarification turns so far.
This keeps the interaction closer to a terminal assistant while still preserving deterministic safety checks around side effects.
Run tests:
uv run pytestRun lint:
uv run ruff check .Run formatter:
uv run ruff format .Refresh the globally installed CLI after dependency or metadata changes:
uv tool install --editable . --forceNever commit these files:
.envcredentials.jsontoken.json
They are ignored by .gitignore.