curl -L -o ics-calendar-parser.skill "https://aiskillstore.io/v1/agent/skills/e92421db-5a43-423e-9ff8-349ca57a747b/download?platform=ClaudeCode"
{
"tool": "download_skill",
"arguments": {
"skill_id": "e92421db-5a43-423e-9ff8-349ca57a747b",
"platform": "ClaudeCode"
}
}
{
"mcpServers": {
"skill-store": {
"url": "https://aiskillstore.io/mcp/"
}
}
}
RFC 5545 .ics / iCalendar string parser — event extraction, RRULE expansion, timezone normalization, conflict detection
Compatible Platforms any
Findings: ["메타데이터 경고: 권장 필드 없음: 'requirements' (SKILL.md v2 권장)", "메타데이터 경고: 권장 필드 없음: 'changelog' (SKILL.md v2 권장)"]
✅ No security risks found.
AI Review Stage
스킬 메타데이터와 코드 파일을 종합적으로 검토한 결과, 다음과 같은 판단 근거를 도출했습니다. 1. **권한 일치 여부**: 스킬 메타데이터에 `network: false`, `filesystem: false`, `subprocess: false`로 명확히 선언되어 있습니다. 제공된 `main.py` 및 `lib/parser.py` 코드 스니펫을 분석한 결과, `os` 모듈은 `sys.path` 조작을 위한 용도로만 사용되었으며, 네트워크 통신(`requests`, `socket` 등), 파일 시스템 접근(`open` 등), 외부 프로세스 실행(`subprocess`, `os.system` 등)과 관련된 코드는 발견되지 않았습니다. 이는 선언된 권한과 실제 코드가 완벽하게 일치함을 의미합니다. 2. **악의적 코드 여부**: 코드는 iCalendar 데이터 파싱, 이벤트 추출, 반복 규칙 확장, 시간대 정규화 등 스킬의 목적에 충실하게 작성되어 있습니다. 데이터 탈취, 시스템 파괴, 난독화 등 악의적인 목적으로 의심될 만한 코드는 전혀 발견되지 않았습니다. `icalendar` 및 `dateutil`과 같은 널리 사용되고 신뢰할 수 있는 라이브러리를 활용하고 있습니다. 3. **외부 통신 여부**: `network: false`로 선언되었으며, 코드에서도 외부 네트워크 통신을 시도하는 부분이 없습니다. 4. **사용자 데이터 수집/전송**: 스킬은 `stdin`으로 입력받은 `ics_content`를 처리하여 `stdout`으로 결과를 반환하는 `stdin_stdout` 패턴을 따릅니다. 선언된 권한에 따라 외부 통신이나 파일 시스템 접근이 없으므로, 사용자 데이터를 무단으로 수집하거나 전송할 가능성은 없습니다. 5. **코드 품질**: 코드는 명확하고 구조적이며, 오류 처리 로직(`make_error`)도 잘 구현되어 있습니다. 스킬의 목적에 부합하는 기능을 안정적으로 수행할 것으로 판단됩니다. 정적 분석 결과 또한 'approved' 상태로, 어떠한 위험 요소도 발견되지 않았음을 확인했습니다. 결론적으로, 이 스킬은 보안 검수 기준을 모두 충족하며 안전하게 배포될 수 있습니다.
Representative input/output examples for this skill. Agents can use these to understand how to invoke the skill and what output to expect.
Parse a simple ICS calendar and extract all events (basic use case)
{
"action": "parse_events",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Example//EN\nX-WR-CALNAME:Work\nBEGIN:VEVENT\nUID:meeting-001@example.com\nSUMMARY:Team Meeting\nDTSTART:20260623T090000Z\nDTEND:20260623T100000Z\nLOCATION:Room A\nSTATUS:CONFIRMED\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "UTC"
}
{
"calendar_name": "Work",
"conflicts": [],
"events": [
{
"description": "",
"dtend": "2026-06-23T10:00:00+00:00",
"dtstart": "2026-06-23T09:00:00+00:00",
"is_recurring": false,
"location": "Room A",
"rrule": "",
"status": "CONFIRMED",
"summary": "Team Meeting",
"uid": "meeting-001@example.com"
}
],
"freebusy": [],
"total_events": 1
}
Expand a weekly recurring meeting (FREQ=WEEKLY;BYDAY=MO) across a 3-month date range
{
"action": "expand_recurring",
"expand_end": "2026-09-30",
"expand_start": "2026-07-01",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Corp//EN\nX-WR-CALNAME:Standups\nBEGIN:VEVENT\nUID:standup-recur@corp.com\nSUMMARY:Daily Standup\nDTSTART:20260601T090000Z\nDTEND:20260601T091500Z\nRRULE:FREQ=WEEKLY;BYDAY=MO\nSTATUS:CONFIRMED\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "UTC"
}
{
"calendar_name": "Standups",
"conflicts": [],
"events": [
{
"description": "",
"dtend": "2026-07-06T09:15:00+00:00",
"dtstart": "2026-07-06T09:00:00+00:00",
"is_recurring": true,
"location": "",
"rrule": "FREQ=WEEKLY;BYDAY=MO",
"status": "CONFIRMED",
"summary": "Daily Standup",
"uid": "standup-recur@corp.com"
}
],
"freebusy": [],
"total_events": 13
}
Detect scheduling conflicts between two overlapping events in a combined calendar
{
"action": "detect_conflicts",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//HR//EN\nBEGIN:VEVENT\nUID:event-a@hr.com\nSUMMARY:Board Meeting\nDTSTART:20260701T140000Z\nDTEND:20260701T160000Z\nSTATUS:CONFIRMED\nEND:VEVENT\nBEGIN:VEVENT\nUID:event-b@hr.com\nSUMMARY:Client Call\nDTSTART:20260701T150000Z\nDTEND:20260701T170000Z\nSTATUS:CONFIRMED\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "UTC"
}
{
"calendar_name": "",
"conflicts": [
{
"event_a_summary": "Board Meeting",
"event_a_uid": "event-a@hr.com",
"event_b_summary": "Client Call",
"event_b_uid": "event-b@hr.com",
"overlap_end": "2026-07-01T16:00:00+00:00",
"overlap_start": "2026-07-01T15:00:00+00:00"
}
],
"events": [
{
"description": "",
"dtend": "2026-07-01T16:00:00+00:00",
"dtstart": "2026-07-01T14:00:00+00:00",
"is_recurring": false,
"location": "",
"rrule": "",
"status": "CONFIRMED",
"summary": "Board Meeting",
"uid": "event-a@hr.com"
},
{
"description": "",
"dtend": "2026-07-01T17:00:00+00:00",
"dtstart": "2026-07-01T15:00:00+00:00",
"is_recurring": false,
"location": "",
"rrule": "",
"status": "CONFIRMED",
"summary": "Client Call",
"uid": "event-b@hr.com"
}
],
"freebusy": [],
"total_events": 2
}
Parse events from a UTC-based calendar and normalize all datetimes to Asia/Seoul timezone
{
"action": "parse_events",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//App//EN\nX-WR-CALNAME:Personal\nBEGIN:VEVENT\nUID:lunch-tz@personal.com\nSUMMARY:Lunch with Client\nDTSTART:20260615T030000Z\nDTEND:20260615T040000Z\nSTATUS:CONFIRMED\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "Asia/Seoul"
}
{
"calendar_name": "Personal",
"conflicts": [],
"events": [
{
"description": "",
"dtend": "2026-06-15T13:00:00+09:00",
"dtstart": "2026-06-15T12:00:00+09:00",
"is_recurring": false,
"location": "",
"rrule": "",
"status": "CONFIRMED",
"summary": "Lunch with Client",
"uid": "lunch-tz@personal.com"
}
],
"freebusy": [],
"total_events": 1
}
Extract busy time blocks from a calendar for scheduling assistants
{
"action": "get_freebusy",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Cal//EN\nBEGIN:VEVENT\nUID:busy-1@cal.com\nSUMMARY:Focus Time\nDTSTART:20260710T090000Z\nDTEND:20260710T120000Z\nSTATUS:CONFIRMED\nEND:VEVENT\nBEGIN:VEVENT\nUID:busy-2@cal.com\nSUMMARY:Team Sync\nDTSTART:20260710T140000Z\nDTEND:20260710T150000Z\nSTATUS:CONFIRMED\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "UTC"
}
{
"calendar_name": "",
"conflicts": [],
"events": [],
"freebusy": [
{
"end": "2026-07-10T12:00:00+00:00",
"start": "2026-07-10T09:00:00+00:00"
},
{
"end": "2026-07-10T15:00:00+00:00",
"start": "2026-07-10T14:00:00+00:00"
}
],
"total_events": 2
}
Return a structured error when an empty or missing ICS content is provided
{
"action": "parse_events",
"ics_content": ""
}
{
"calendar_name": "",
"conflicts": [],
"error": {
"code": "EMPTY_ICS",
"message": "ics_content is empty. Provide a valid BEGIN:VCALENDAR block."
},
"events": [],
"freebusy": [],
"total_events": 0
}
Return a structured error when an unrecognized IANA timezone name is given
{
"action": "parse_events",
"ics_content": "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Test//EN\nBEGIN:VEVENT\nUID:tz-err@test.com\nSUMMARY:TZ Test\nDTSTART:20260601T090000Z\nDTEND:20260601T100000Z\nEND:VEVENT\nEND:VCALENDAR",
"timezone": "Mars/Olympus_Mons"
}
{
"calendar_name": "",
"conflicts": [],
"error": {
"code": "INVALID_TIMEZONE",
"message": "Unknown timezone: Mars/Olympus_Mons. Use a valid IANA timezone name (e.g. Asia/Seoul, America/New_York)."
},
"events": [],
"freebusy": [],
"total_events": 0
}
All examples are also available via the agent API:
/v1/agent/skills/e92421db-5a43-423e-9ff8-349ca57a747b/schema
No reviews yet. Be the first to leave one!