Skip to main content
Glama
README.md
# timetree-mcp

A personal-use MCP server that lets Claude write events into your shared TimeTree calendar.
Typical flow: paste an event poster → Claude extracts date / location / title and writes a
short description → calls `create_event` → event shows up in the TimeTree app.

## ⚠️ Disclaimer (read before using)

- TimeTree's **official Connect API was shut down on 2023-12-22**. This MCP talks to
  TimeTree's *internal* web API (the same one the web app uses), reverse-engineered.
- This is **unofficial and not affiliated with TimeTree, Inc.** It may break at any time
  if TimeTree changes the internal API. Using it may **violate TimeTree's Terms of Service**.
- **Use a dedicated TimeTree account**, not your main one. Invite that account to the
  shared calendar(s) you want to manage. If TimeTree flags the account, only the dedicated
  one is at risk.
- **Personal use only.** Don't publish this, don't run it at scale, don't make commercial
  use of it.

Endpoint mapping informed by [ehs208/TimeTree-MCP](https://github.com/ehs208/TimeTree-MCP) (MIT)
and [eoleedi/TimeTree-Exporter](https://github.com/eoleedi/TimeTree-Exporter).

## Install

Requires Node.js 18+.

```powershell
cd C:\Users\user\Desktop\timetree-mcp
npm install
npm run build
```

## Configure

Copy `.env.example` to `.env` and fill in your dedicated account:

```
TIMETREE_EMAIL=dedicated-bot@example.com
TIMETREE_PASSWORD=...
LOG_LEVEL=INFO
```

The server reads `.env` from the project root at startup, so you do NOT need
to pass credentials on the `claude mcp add` command line (that would put them
in PowerShell history). Just register the binary:

```powershell
claude mcp add timetree node "C:\Users\user\Desktop\timetree-mcp\dist\index.js"
```

Or, if you prefer editing config directly (e.g. `~/.claude/settings.json`):

```json
{
  "mcpServers": {
    "timetree": {
      "command": "node",
      "args": ["C:\\Users\\user\\Desktop\\timetree-mcp\\dist\\index.js"]
    }
  }
}
```

Restart Claude Code. `/mcp` should show `timetree` with the TimeTree tools,
including `list_calendars`, `list_events`, `create_event`, `update_event`,
`poster_workspace_status`, and `mark_poster_processed`.

Process-level env vars still override the `.env` file, so CI / one-off
invocations can set `TIMETREE_PASSWORD=xxx node dist/index.js` to bypass it.

## Usage

### Poster folder workflow

Use a single poster workspace folder, defaulting to:

```text
C:\Users\daan\Desktop\timetree海報更新
```

The MCP manages this structure:

```text
timetree海報更新
├─ 00_待處理
├─ 10_已新增
├─ 20_已更新既有事件
├─ 90_需人工確認
└─ _log
```

Rules:

1. Put new poster images in `00_待處理`.
2. Start by calling `poster_workspace_status`; it creates missing folders and lists only pending images.
3. When `create_event` succeeds with an `image_path` from `00_待處理`, the poster is moved to `10_已新增`.
4. When `update_event` succeeds with an `image_path` from `00_待處理`, the poster is moved to `20_已更新既有事件`.
5. Use `mark_poster_processed` with `status: "needs_review"` for unclear posters; they move to `90_需人工確認`.
6. Every move appends a CSV record under `_log`.

If someone drops images directly into the workspace root, `poster_workspace_status`
moves them into `00_待處理` by default so future runs still process only new items.

The intended workflow:

1. Drop an event poster (image) into a Claude Code conversation.
2. Ask Claude something like: *"請把這張海報的活動加到我的家庭共用行事曆。"*
3. Claude reads the poster, calls `list_calendars` to find the right calendar_id,
   writes a short description, and calls `create_event` with an ISO date.
4. Open TimeTree on your phone — the event is there.

## Tools

### `list_calendars`

No arguments. Returns `{calendars: [{calendar_id, name, members}], total}`.
Use this first to know which `calendar_id` to write into.

### `create_event`

Required: `calendar_id` (number), `title` (string), `start` (ISO 8601 string).

Optional:
- `end` — ISO 8601. Defaults to `start + 1h` for timed events, `start` (same day) for all-day.
- `all_day` — boolean (default `false`).
- `timezone` — IANA timezone (default `Asia/Taipei`).
- `location` — string.
- `description` — short note, shows up as the event note in TimeTree.
- `label_id` — 1-10. 1=Emerald 2=Cyan 3=Blue 4=Brown 5=Black 6=Red 7=Rose 8=Pink 9=Orange 10=Violet.

Returns the created event with its `uuid` (useful if you later add `update_event` / `delete_event`).

### `poster_workspace_status`

Creates/checks the poster workspace folders, moves loose root-level images into
`00_待處理` by default, and returns pending image paths.

### `mark_poster_processed`

Moves a poster out of `00_待處理` and writes the CSV log. This is automatic for
successful `create_event` and `update_event` calls when `image_path` points into
`00_待處理`, so this tool is mainly for manual corrections and `needs_review`.

## Troubleshooting

- **`Invalid email or password`** — TimeTree returned 401. Check the dedicated account
  credentials. If the account uses social login (Google / Apple), it won't have an
  email/password and this MCP can't authenticate it. Use a TimeTree account created
  with email/password signup.
- **`CSRF token missing or invalid`** — usually means the session expired between
  calls. The client auto-reauths once on 403; if you see this twice in a row,
  TimeTree may have changed the CSRF token location.
- **Empty `list_calendars` result** — make sure the dedicated account is actually a
  member of at least one shared calendar.
- **Build fails on Windows with esbuild ENOENT** — known npm 10.8.x bug. Try
  `npm install --no-package-lock` or upgrade npm to 10.9+.

## Project structure

```
src/
  index.ts      # MCP server entry (stdio transport)
  timetree.ts   # auth + HTTP + API client + logger
  tools.ts      # MCP tools: list_calendars, create_event
  types.ts      # Zod schemas and TS types
```

Four files, ~700 LOC. MVP scope. Extend by adding more handlers to `buildTools` in `tools.ts`.

TDQS

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: calendar listing, event listing, event creation, event updating, poster workspace inspection, and poster processed marking. No two tools overlap in function, and the descriptions reinforce the boundaries.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (list_calendars, list_events, create_event, update_event, mark_poster_processed). The exception is poster_workspace_status, which uses a noun_noun structure, but it is still understandable and does not create confusion.

Tool Count5/5

Six tools is well-scoped for the server's dual purpose of TimeTree calendar management and local poster workflow. Each tool earns its place without redundancy or unnecessary bloat.

Completeness4/5

The server covers the core lifecycle of events (list, create, update) and the poster workflow (status, mark processed, integrated image upload). Minor gaps include no delete_event or get_single_event, but these can be worked around with list_events and update_event, so the coverage is adequate for typical use.

Maintenance

ActivityInactive
ResponsivenessNo issues