Skip to content

Repository files navigation

mytime

Agent interaction demo - mytime CLI behind the scenes

One terminal app for tasks, calendar, and meetings. Keep work in your Backlog, sync with Google Calendar or Apple Calendar, and create Google Meet events with invitations and RSVP support.

Site: mytime.apvl.dev

Install

From source (requires Node 20+ and pnpm):

pnpm install
pnpm build
pnpm link --global   # optional: global `mytime` command

Homebrew (macOS) — slim prebuilt pack (~15MB); uses Homebrew Node 20 (installed automatically if needed):

brew tap alexapvl/mytime https://github.com/alexapvl/mytime && brew install mytime
mytime setup google   # Google Calendar
# or: mytime setup apple   # Apple Calendar, macOS 14+
mytime setup --agent-onboarding-prompt   # copy → paste into agent

The tap is one-time; later upgrades are brew upgrade mytime. Bleeding edge from source: brew install mytime --HEAD.

Portable standalone build (includes vendored Node, ~40MB): see releases (*-standalone.tar.gz).

The TUI checks GitHub once per day for updates and shows an upgrade command when a newer main commit is available.

Dev mode (no build):

pnpm dev

Calendar setup

Choose one writable calendar provider. mytime only syncs with the currently active provider, while other calendars from that provider can be fetched read-only.

mytime setup google           # Google OAuth setup
mytime setup apple            # Apple Calendar via EventKit, macOS 14+
mytime setup                  # show both provider paths
mytime doctor                 # check the active provider
mytime setup --links                    # print Google Cloud Console URLs
mytime setup --agent-prompt             # Google OAuth setup prompt for your agent
mytime setup --agents                   # AI agent + MCP integration guide
mytime setup --agent-onboarding-prompt  # paste into Cursor / Claude after install

If an agent is helping and the provider is not already known from the conversation, it must ask whether you want Google Calendar or Apple Calendar before running setup.

Apple Calendar

Apple Calendar support uses the calendars already configured in Calendar.app. It requires macOS 14 or newer and does not need Google credentials or a separate Apple CLI.

mytime setup apple
mytime sync

macOS asks you to grant Calendar access. mytime then selects or creates a dedicated calendar named for its actual backend, such as "mytime-icloud" or "mytime-google". Other visible calendars can be fetched read-only for Daily, Week, and Month views.

An agent can start setup, inspect permission status, and run sync, but you must approve the macOS Calendar permission prompt yourself. If your Apple Account or another calendar account is not yet in Calendar.app, add it in System Settings → Internet Accounts first.

Google Calendar

Run mytime setup google for a checklist, Console links, and next steps.

Google sync needs two local files under ~/.mytime/:

File Created by Purpose
credentials.json You (from Google Cloud) OAuth client ID + secret
token.json mytime auth Your signed-in Google account

Tasks sync to a dedicated calendar named "mytime-google". Google Meet events are created on your primary calendar so you are the organizer and invitations come from your Google account. Other Google calendars can be pulled read-only for display in Daily, Week, and Month views.

Create a Meet event in the TUI with Shift+A, or from an agent:

mytime agent event add \
  --title "Sync with Sam" \
  --start "2026-07-16T15:30:00+03:00" \
  --end "2026-07-16T16:00:00+03:00" \
  --guests sam@example.com \
  --google-meet

Google Calendar sends the invitations. In the TUI, respond to incoming invitations with yes, maybe, or no, and press o on an event to open its meeting link.

Switching providers

Only one provider is writable at a time. When switching, mytime stops syncing the old provider, removes its fetched external events from the local cache, preserves your local tasks and events, then fetches from the newly active provider.

Calendar names follow the backend: "mytime-google", "mytime-icloud", or "mytime-local". If EventKit accesses the same Google calendar as the Google API, mytime adopts that calendar and changes only the sync adapter. It never copies or deletes the shared calendar.

For different backends, setup asks whether you also want to delete the old dedicated calendar. The safe default is to keep it. mytime never deletes or writes to unrelated calendars.

Provider switches stay explicit and agent-safe:

mytime setup apple --keep-old-calendar
mytime setup apple --delete-old-calendar
mytime setup google --keep-old-calendar
mytime setup google --delete-old-calendar

If Calendar.app contains multiple writable accounts or dedicated calendars, Apple setup lists them and asks you to rerun with --source <source-id> --calendar <calendar-id>. It never guesses which account or calendar to use.

Duplicate cleanup always starts with a read-only preview:

mytime setup apple --cleanup-duplicates
mytime setup apple --cleanup-duplicates --apply  # only after reviewing preview

Google agent-assisted setup

If you use Cursor, Claude Code, or another agent with browser access, run mytime setup --agent-prompt and paste the output, or copy this prompt:

Help me set up Google Calendar for mytime (https://github.com/alexapvl/mytime).

Goal: mytime needs a Google Cloud OAuth Desktop client saved at ~/.mytime/credentials.json, then I will run `mytime auth` and `mytime sync` locally.

Please do the following:

1. In Google Cloud Console (https://console.cloud.google.com/):
   - Create or select a project for personal mytime use.
   - Enable the Google Calendar API (APIs & Services → Library → "Google Calendar API").
   - Configure OAuth consent screen: External user type, app name "mytime", add my Google account as a Test user. Testing mode is fine.
   - Create Credentials → OAuth client ID → Application type "Desktop app".
   - Download the client JSON.

2. On my machine:
   - Create ~/.mytime if it does not exist.
   - Save the downloaded JSON as ~/.mytime/credentials.json (must have an "installed" key with client_id and client_secret).
   - Do NOT commit credentials.json to git.

3. Tell me when credentials.json is in place. I will run `mytime auth` myself in the terminal (browser OAuth — you cannot complete this step for me). After auth succeeds, I will run `mytime sync` to verify.

If you can control a browser (e.g. chrome-devtools-axi), navigate the Console for me step by step. Otherwise, give exact click-by-click instructions and pause after each step for confirmation.

After the agent finishes step 2, run mytime auth and mytime sync as described in the manual steps below.

Google Cloud Console (manual)

Prefer doing it yourself? You only do this once per machine (or per Google Cloud project).

  1. Open Google Cloud Consoleconsole.cloud.google.com

  2. Create or select a project

    • Top bar → project picker → New Project (e.g. mytime-personal) or pick an existing one.
  3. Enable the Google Calendar API

    • APIs & Services → Library (direct link)
    • Search for Google Calendar APIEnable.
  4. Configure the OAuth consent screen

    • APIs & Services → OAuth consent screen (direct link)
    • User type: External (fine for personal use) → Create.
    • App information: app name (e.g. mytime), user support email, developer contact email → Save and Continue.
    • Scopes: Save and Continue (mytime requests calendar scope at sign-in; you do not need to add scopes here).
    • Test users: Add users → your Google account email → Save and Continue.
    • Leave the app in Testing — that is enough for a single-user setup.

    Note: While the app is in Testing, only test users you add can sign in. If auth fails with access blocked, add your account under OAuth consent screen → Test users.

  5. Create OAuth credentials (Desktop app)

    • APIs & Services → Credentials (direct link)
    • Create Credentials → OAuth client ID
    • Application type: Desktop app
    • Name: e.g. mytime desktopCreate
    • Download JSON (or use the download icon on the new client).
  6. Install the credentials file

    mkdir -p ~/.mytime
    mv ~/Downloads/client_secret_*.json ~/.mytime/credentials.json

    The JSON must contain an installed object with client_id and client_secret (the default format for Desktop app downloads). Do not commit this file.

  7. Authenticate

    mytime auth

    This starts a local server on 127.0.0.1:3847, opens your browser for Google sign-in, and saves a token to ~/.mytime/token.json. Complete the flow in the browser; you can close the tab when you see mytime authenticated.

  8. Sync

    mytime sync

    mytime creates the "mytime" calendar if it does not exist and runs the first two-way sync.

  9. Choose which calendars to fetch locally

    mytime settings

    Toggle external Google calendars on or off. Disabled calendars are not pulled during sync, and their events are removed from the local database. The dedicated mytime calendar is always enabled.

Why bring your own Google Cloud project?

mytime does not ship shared Google OAuth credentials. You create a Desktop OAuth client in your Google Cloud project and keep credentials.json and token.json locally under ~/.mytime/.

That is intentional for a personal tool:

  • Privacy — Calendar tokens stay on your machine. mytime never sends them through a maintainer's server.
  • Control — You own the GCP project, API access, and test users. Revoke or rotate credentials anytime in Google Cloud Console.
  • Scope - tasks write to the dedicated "mytime" calendar. Google Meet events write to your primary calendar so you remain the organizer. Other calendars are read-only and optional in mytime settings.
  • No hosted OAuth — A shared OAuth app would need Google verification for public Calendar access, ongoing abuse monitoring, and trust that someone else's server (or embedded client secret) handles your Google account.

The one-time Cloud Console setup is the tradeoff for keeping mytime local-first and maintainer-free. Agent-assisted setup (above) or an AI agent with browser access can do most of the clicking; you still run mytime auth yourself in the terminal for the final browser sign-in.

Usage

mytime                          # interactive TUI
mytime add "review PR tomorrow 3pm @work p2 #swe"
mytime event "dentist tomorrow 2pm"   # calendar event (requires date/time)
mytime today                    # print today's blocks
mytime setup                    # choose Google or Apple Calendar
mytime setup google             # Google setup checklist and Console links
mytime setup apple              # Apple Calendar setup, macOS 14+
mytime doctor                   # verify active provider configuration
mytime sync                     # sync the active calendar provider
mytime auth                     # (re)connect the active provider
mytime settings                 # choose which active-provider calendars to fetch
mytime agent                    # agent CLI for AI assistants (preferred)
mytime mcp                      # run the MCP server (stdio) for AI agents
mytime help                     # show CLI help

TUI

Five tabs — switch with number keys or click the tab bar:

Tab Key What it shows
Backlog 1 Open tasks in P0–P3 columns (scheduled and unscheduled)
Daily 2 Hour grid + all-day row for one day
Week 3 Seven-day grid with timed blocks
Month 4 Month calendar grid; press enter to open a day in Daily
Past Due 5 Open tasks that missed their scheduled time

Global keys

Key Action
1 / 2 / 3 / 4 / 5 Backlog / Daily / Week / Month / Past Due
r Sync the active calendar provider
u Undo last delete or done toggle
esc Quit

Mouse clicks work in supported terminals (tabs, items, calendar cells).

Backlog←/→ priority column · ⇧←/→ move task between priorities · ↑/↓ navigate · a add · q quick-add (NLP) · e edit · s schedule/reschedule · x done · d delete

Opens on the lowest non-empty priority column (P0 first, then P1, P2, P3).

Daily←/→ prev/next day · t today · ↑/↓ select · a/q add task / quick-add · ⇧a/⇧q add event / quick-event · e edit · s reschedule · ⇧↑/↓ move selected task by 1h · +/- end ±15m · ⇧+/- start ±15m · x done · d delete

Defaults to the first open (not done) item for the day, including all-day tasks.

Week←/→ prev/next day · ⇧←/→ prev/next week · t this week/today · ↑/↓ select · a/q add task / quick-add · ⇧a/⇧q add event / quick-event · e edit · s reschedule · ⇧↑/↓ move 1h · +/- end ±15m · ⇧+/- start ±15m · x done · d delete

Defaults to today with the first event on that day selected.

Month←/→ prev/next day · ↑/↓ prev/next week · ⇧←/→ prev/next month · t today · enter open focused day in Daily · a/q add task / quick-add on focused day · ⇧a/⇧q add event / quick-event on focused day

Shows a month grid with event previews per day. Navigation wraps within the visible month when changing months.

Past Due↑/↓ navigate · e edit · s reschedule · x done · d delete

Schedule editor (when you press s): shows existing events on the chosen day · ←/→ change day · ↑/↓ pick slot · type digits to filter times · f free slots only · +/- slot step (15–240 min) · a all-day · enter confirm · esc cancel

External calendar events from the active provider appear in Daily/Week/Month but are read-only (s/x/d only apply to your tasks).

Agent CLI (preferred)

mytime agent is the AXI-shaped interface for AI agents. Same database and provider-aware sync as the TUI, with token-efficient TOON output and contextual next-step hints. No extra setup beyond mytime on PATH and the calendar provider you choose.

Set up with your agent:

mytime setup --agents                   # full guide
mytime setup --agent-onboarding-prompt  # copy output → paste into Cursor / Claude

The onboarding prompt tells your agent to run mytime agent, install the skill, and use the CLI for tasks/calendar.

mytime agent                              # dashboard: backlog, past due, today
mytime agent calendar                     # live adapter/backend state + effects
mytime agent calendar setup               # explain setup commands and side effects
mytime agent calendar switch              # explain keep/delete and migration effects
mytime agent calendar cleanup             # explain preview/apply safety
mytime agent backlog list
mytime agent schedule list                # today by default
mytime agent slots --date tomorrow
mytime agent task quick "review PR tomorrow 3pm @work p2"
mytime agent search meloDL
mytime agent sync

Install the agent skill (optional):

mytime setup --agent-skill
# or: npx skills add https://github.com/alexapvl/mytime --skill mytime -g

See skills/mytime/SKILL.md for the full command reference.

MCP server (legacy)

mytime mcp still runs a Model Context Protocol server over stdio for clients that only support MCP. Prefer mytime agent in Cursor and other shell-capable agents — same behavior, fewer tokens, no schema overhead.

Print ready-to-paste MCP config:

mytime setup --mcp-config

Or register manually (global mytime must be on PATH for the MCP host):

{
  "mcpServers": {
    "mytime": { "command": "mytime", "args": ["mcp"] }
  }
}

Tools

Tool Description
list_backlog List all open tasks (scheduled and unscheduled)
list_schedule List scheduled items in a time range (defaults to today)
list_past_due List open overdue tasks with an overdue label
list_free_slots List free timed slots on a day (all-day events listed separately)
get_item Get a single item by id
search_tasks Search by title / project / tags
add_task Create an unscheduled task
quick_add Add from natural language (#tag @project pN, dates)
update_task Update fields of a task
schedule_task / reschedule_task Set/change a task's start (and end or duration)
complete_task Mark done / not done (omit done to toggle)
delete_task Permanently delete a task
sync Full two-way sync with the active calendar provider

Write tools sync to the active provider automatically when configured (no-ops otherwise). External calendar events (source: external) are read-only via MCP. Call list_free_slots before scheduling to find open times. If the TUI is open at the same time, it won't reflect MCP changes until you navigate or sync.

Data

Everything is stored locally at ~/.mytime/db.sqlite. Scheduled items sync to the active Google or Apple provider; unscheduled backlog tasks stay local until you schedule them.

External calendar events are pulled into the local DB for display. Their titles are stored without emoji so terminal layout stays aligned. Tasks you create in mytime are never modified this way.

Quick-add syntax

Natural language via chrono-node:

  • buy groceries tomorrow 5pm
  • dentist Friday 10am-11am
  • review PR @work p2 #swe

Tags: #context · Projects: @name · Priority: p0p3

About

Terminal app for tasks, calendars, and meetings, with a TUI, agent CLI, Google and Apple Calendar sync, Google Meet invites, and RSVP support.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages