
Claude Code 스킬로 TimeTree의 빈 시간 추출 자동화하기
요약
Claude Code의 커스텀 스킬 기능을 활용하여 TimeTree의 빈 시간을 자동으로 추출하는 방법을 소개합니다. Playwright MCP를 통해 브라우저를 조작함으로써 API가 종료된 서비스에서도 효율적인 일정 자동화가 가능합니다.
핵심 포인트
- Claude Code의 SKILL.md를 이용한 커스텀 명령어 생성 방법
- Playwright MCP를 활용한 브라우저 기반 데이터 추출 원리
- API 미지원 서비스(TimeTree)에 대한 자동화 우회 전략
- 반복적인 일정 확인 및 메시지 작성 작업의 자동화 구현
서론
친구들이나 영업처와 일정을 맞출 때, 매번 "TimeTree를 열어서 비어 있는 시간을 눈으로 확인하고, 메시지에 적는" 작업이 발생하고 있습니다.
이 작업을 Claude Code의 커스텀 스킬로 분리하여, /timetree-free-slots 명령 한 번으로 완료할 수 있도록 만들었기에 이를 소개합니다.
예상 독자
- Claude Code로 독자적인
/명령어를 만들어보고 싶은 사람 - Playwright MCP로 브라우저 조작을 동반하는 스킬을 만들고 싶은 사람
- 일정 조정과 같은 단순 반복 작업을 자동화하고 싶은 사람
Claude Code, Playwright MCP, TimeTree 계정(로그인 완료 상태)이 있다면, 기사 내의 SKILL.md를 거의 그대로 활용할 수 있습니다.
As-Is / To-Be
As-Is: TimeTree의 위클리 뷰(Weekly View)를 눈으로 보고, 일정 사이의 시간을 계산하여 메시지에 적음
To-Be: /timetree-free-slots를 실행하는 것만으로, 다음과 같은 텍스트가 그대로 출력됨
6/24(수) 09:00-09:30 / 11:30-12:00 / 17:00-18:00
6/25(목) 09:00-09:30 / 12:00-15:00 / 15:15-18:00
6/26(금) 09:00-09:30 / 10:30-11:00 / 15:00-18:00
...
코드 블록으로 반환되므로, 그대로 LINE이나 메일에 복사하여 붙여넣을 수 있습니다. 시간대를 생략하면 9:00-18:00, 범위를 생략하면 "오늘부터 1주일 후까지"가 기본값입니다.
원리
Claude Code에는 SKILL.md를 한 장 작성하는 것만으로 /명령어이름을 만들 수 있는 메커니즘이 있습니다. 절차로서 작성된 내용을 Claude가 도구(브라우저 조작 등)를 실행하며 따라갑니다.
/timetree-free-slots 실행
↓
① Playwright MCP로 TimeTree Web을 열기
...
브라우저 조작에는 Playwright MCP (browser_navigate / browser_snapshot / browser_handle_dialog)를 사용하며, https://timetreeapp.com/calendars/<calendar_id>/weekly/<YYYY-MM-DD>에 접속하여 주 단위 뷰를 가져옵니다. TimeTree 로그인만은 자동화하지 않았으며, ② 단계에서 로그인 화면이 나타날 경우 사용자에게 수동 로그인을 요청하고 일단 정지합니다.
왜 이 구성으로 했는가
TimeTree는 2023년 12월에 공식 API 제공을 종료했기 때문에, 이번에는 로그인된 브라우저 세션을 그대로 사용할 수 있는 Playwright MCP로 웹 화면을 읽는 방식을 선택했습니다.
로그인 자동화도 일부러 하지 않았습니다. ID와 비밀번호를 파일에 쓰고 싶지 않았기 때문에, 세션이 끊겨 있다면 처리를 멈추고 사용자에게 재로그인을 맡기는 설계로 했습니다.
실제 SKILL.md
일정 조정 시마다 몇 번이고 사용하는 것을 전제로 하기에, 매번 동일한 동작이 되도록 확인 과정이나 개인차가 생길 여지를 줄였습니다. 실제로 작동하고 있는 SKILL.md의 전문을 참고용으로 첨부합니다. 캘린더 ID나 문구 등은 자신의 환경에 맞춰 적절히 조정해 주세요.
실제 SKILL.md 전문
---
name: timetree-free-slots
description: TimeTree의 위클리 화면에서 빈 시간(지정 시간대)을 추출하여 「x/xx(요일) HH:MM-HH:MM」 형식으로 출력한다. 영업·친구 등 일정 조정 전반에 사용한다. 범위는 미지정 시 「오늘부터 1주일 후까지」이며, 그 외에 「이번 주(캘린더 기준)」, 「오늘부터 N일간」을 선택할 수 있다. 사용법: /timetree-free-slots [시간대(예: 9:00-18:00)] [range=week|next<N>(예: next10)]
...
```)로 감싼다. 메일이나 채팅에 그대로 붙여넣을 수 있는 형태로 만든다.
- 포맷은 `M/D(요일) HH:MM-HH:MM / HH:MM-HH:MM` 형태의 순수 텍스트(앞부분의 `- `는 붙이지 않음)
- 이미 TimeTree에 로그인되어 있고 위클리 뷰(Weekly View)가 표시되어 있는 상황을 가정하여 동작한다. 로그인되어 있지 않으면 사용자에게 요청하고 중단한다.
---
## 사전에 파악해야 할 경로·URL
- TimeTree Web 캘린더: `https://timetreeapp.com/calendars/<calendar_id>/weekly/<YYYY-MM-DD>`
- 이용 도구: `mcp__playwright__browser_navigate`, `mcp__playwright__browser_snapshot`, `mcp__playwright__browser_handle_dialog`
---
## Workflow
### Step 1: 인자 파싱 (Argument Parsing)
- `HH:MM-HH:MM` 형식이 있으면 시간대로 파싱한다. 미지정 시 `START=9:00, END=18:00`으로 설정한다.
- `range=week` 또는 `range=next<N>`(N은 일수)을 확인한다. 미지정 시 「오늘부터 1주일 후까지」(= `오늘~오늘+7일`, 8일간)로 한다. 과거 날짜를 포함하는 `week`(캘린더 기준 월요일 시작)는 명시적으로 지정되었을 때만 사용한다.
- `week`: 이번 주 월요일~일요일(7일). 과거 요일도 포함되므로 명시적 지정이 없는 한 사용하지 않는다.
- `next<N>`: 오늘~오늘+(N-1)일(N일간) — 「오늘부터 N일간」을 반환하고 싶을 때 사용한다.
- 사용자가 「오늘부터」와 같은 자연어로 요청한 경우에도 미지정 시와 동일한 기본값(오늘~오늘+7일, 8일간)을 사용한다. 「오늘부터 N일간」이라고 일수가 명시되면 `range=next<N>`(today~today+(N-1)일, N일간)으로 처리한다.
### Step 2: 대상 날짜 특정
```bash
# 오늘
date +%Y-%m-%d
# 이번 주 월요일
...
- 미지정(기본값) →
TARGET_DATES = 오늘~오늘+7일(8일간) range=week→TARGET_DATES = 이번 주 월요일~일요일(7일)range=next<N>→TARGET_DATES = 오늘~오늘+(N-1)일(N일간)
TARGET_DATES가 커버하는 위클리 뷰(Weekly View, =월요일 시작 주)를 열거한다:TARGET_DATES의 시작일이 속한 주의 월요일부터 종료일이 속한 주의 월요일까지, 1주일씩 진행하며 열거한다.- 예: 오늘이 수요일이고
next10(종료일은 오늘+9일)인 경우, 이번 주·다음 주·다다음 주 총 3주 분량의 뷰가 필요할 수 있다.
Step 3: TimeTree의 위클리 뷰 열기
필요한 주 수만큼 https://timetreeapp.com/calendars/<id>/weekly/<Monday>로 순차적으로 내비게이션하여 browser_snapshot을 가져온다.
이미 목적의 주가 열려 있다면 재내비게이션은 불필요하다.
로그인 화면이 표시된 경우에만: snapshot이 위클리 뷰가 아니라 로그인 화면(이메일 주소/비밀번호 입력 폼 등)이라면, "TimeTree에 로그인한 후 다시 실행해 주세요"라고 사용자에게 알리고 처리를 중단한다. 위클리 뷰가 표시되어 있다면 이 체크는 수행하지 않는다.
「캘린더를 하나 이상 선택해 주세요」 다이얼로그가 뜨면 browser_handle_dialog accept:true로 닫는다.
Step 4: 스냅샷에서 일정 추출
snapshot 내의 button "<제목> <시작 시간> - <종료 시간> avatar of ..." 요소로부터 각 요일의 일정 목록을 가져온다.
TimeTree는 요일별로 generic 블록이 나누어져 있으므로, 월요일부터 일요일 순으로 일정을 수집한다.
시간 표기는 오전 9:00 / 오후 3:00 형식이므로 24시간제(24-hour format)로 변환한다:
오전 X:YY→0X:YY(오전 12시는00:YY)오후 0:YY→12:YY오후 X:YY (X≥1)→(X+12):YY
Step 5: 각 요일의 빈 시간(空き時間) 산출
각 요일에 대해:
- 지정된 시간대
[START, END]를 초기 빈 시간 범위로 설정한다. - 해당 날의 일정 중
[START, END]와 겹치는 구간을 모두 제외한다. - 남은 연속 구간이 빈 시간이다.
주의사항:
- 일정의 종료 시각 == 시작 시각인 점 형태의 일정(예: 마감 표시)은 무시한다.
- 일정의 종료 시각이
END를 초과하더라도,END까지의 부분만 고려한다. - 일정이
START이전부터 시작되더라도,START이후의 부분만 고려한다. - 「종일」 일정(제목만 있고 시작/종료 시각이 없는 일정)은 빈 시간 판정에 사용하지 않는다. 완전히 무시하며, 해당 날짜를 일정이 있는 것으로 처리하지 않는다.
Step 6: 출력
복사하여 붙여넣기 용이하도록 코드 블록으로 감싸서 출력한다:
```
M/D(월) HH:MM-HH:MM / HH:MM-HH:MM
M/D(화) HH:MM-HH:MM
M/D(수) 빈 시간 없음
...
```
요일 기호: 월화수목금토일 (일본어 1글자)
빈 시간이 전혀 없는 날은 M/D(요일) 빈 시간 없음이라고 출력한다. 맨 앞의 - 등은 붙이지 않는다 (이메일에 그대로 붙여넣을 수 있는 순수 텍스트).
엣지 케이스 (Edge Case)
- 캘린더 미선택 다이얼로그가 나타난 경우: 한 번
accept하고 스냅샷(snapshot)을 다시 찍는다. - 스냅샷에 일정이 하나도 없는 경우: 해당 주는 모든 시간대가 비어 있는 것으로 출력한다 (오독이 아닌지 확인하기 위해, 만약을 대비해 사용자에게 "일정이 없는 것이 맞습니까?"라고만 답변한다).
## 사용 후기
실제 일정 조정 시 몇 번 사용해 보았는데, TimeTree를 눈으로 직접 확인하며 계산하는 시간이 제로(0)가 된 것이 가장 큰 수확이었습니다.
지루한 작업일수록 "매번 같은 절차를 반복할 뿐"이 되기 쉬우므로, 스킬화(Skill化)의 효과가 나타나기 쉬운 부류라고 느꼈습니다.
## 요약
- TimeTree와 같이 눈으로 확인해야 하는 반복 작업일수록, 스킬화의 비용 대비 효과(ROI)가 높다.
- Claude Code의 `SKILL.md`는 반복 작업을 `/command`로 고정할 수 있다.
- 브라우저 조작이 포함된 태스크도 Playwright MCP + 스킬화를 통해 자동화할 수 있다.
일상 속에서 "매번 같은 절차를 수행하는 것"을 찾아 꼭 스킬화해 보세요!
### Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기