Skip to main content
Glama
SarjuThakkar

Skylight MCP server

by SarjuThakkar

Skylight MCP 서버

Pebble Index 링이 음성으로 Skylight 가족 캘린더에 이벤트를 추가할 수 있게 해줍니다. Pebble의 클라우드 에이전트가 MCP 클라이언트이고, 이 서버는 Skylight의 비공식 API를 대상으로 HTTP 작업을 수행합니다. Pebble은 Skylight와 직접 통신하지 않으며, Skylight도 여러분의 Pebble 계정을 볼 수 없습니다.

노출되는 유일한 도구는 create_event입니다(쓰기 전용 — Pebble이 캘린더를 다시 읽을 필요가 없고, list_events를 제외함으로써 도구 표면이 모호하지 않게 유지됩니다). 기본 가족 구성원 프로필을 자동으로 태그할 수 있고, "me"/"myself"를 그 사람으로 이해하며, 다른 구성원은 이름으로 인식합니다.

전송 방식: Streamable HTTP. 인증: Authorization 헤더의 정적 bearer 토큰(Pebble은 사용자 지정 MCP 서버에 대해 OAuth 로그인 흐름을 지원하지 않고 고정 헤더만 지원합니다).

다른 사람의 Pebble + Skylight에서도 재사용할 수 있나요?

네 — 코드 어디에도 특정 개인에 묶인 내용은 없습니다. 계정별 값(Skylight 로그인, 프레임 ID, 시간대, 기본 가족 구성원, bearer 토큰)은 모두 환경 변수에서 오며, 가족 구성원 이름은 하드코딩되지 않고 여러분의 Skylight 카테고리에서 실시간으로 확인됩니다. 자신의 Skylight 계정과 Pebble Index, 그리고 작은 Python HTTP 서비스를 호스팅할 곳만 있으면 누구나 자신의 복사본을 실행할 수 있습니다. 아래 배포를 참고하세요 — 코드를 수동으로 편집하는 것이 아니라 몇 가지 CLI 명령만으로 가능합니다.

Related MCP server: Google Calendar AutoAuth MCP Server

환경 변수

변수

필수

설명

SKYLIGHT_EMAIL

yes

app.ourskylight.com 로그인 이메일.

SKYLIGHT_PASSWORD

yes

app.ourskylight.com 로그인 비밀번호.

SKYLIGHT_FRAME_ID

yes

로그인 상태에서 app.ourskylight.com/calendar/<id>의 숫자.

MCP_BEARER_TOKEN

yes

Pebble이 Authorization: Bearer <token>으로 보내는 정적 토큰. openssl rand -hex 32로 생성하세요.

SKYLIGHT_TIMEZONE

no

naive 이벤트 시간이 해석되는 IANA 시간대. 기본값은 America/Chicago. 이 값은 도구의 docstring에도 표시되어 Pebble의 에이전트에 전달되므로 자동으로 동기화됩니다.

SKYLIGHT_DEFAULT_MEMBER

no

Skylight 가족 구성원의 프로필 이름(캘린더의 카테고리 라벨과 일치해야 함). who가 생략되었을 때 사용되며, "me"/"myself"/"i"가 이 값으로 해석됩니다. 기본 태그를 원하지 않으면 설정하지 마세요.

PORT

no

Railway/대부분의 호스트가 자동으로 설정합니다. 로컬에서는 기본값 8000.

로컬 설정

python3 -m venv .venv && source .venv/bin/activate   # needs Python 3.10+
pip install -r requirements.txt

cp .env.example .env   # then fill in real values
export $(grep -v '^#' .env | xargs)   # or use your own env loader
export MCP_BEARER_TOKEN=$(openssl rand -hex 32)

python skylight_mcp_server.py

서버는 http://0.0.0.0:8000(또는 설정된 경우 $PORT)에서 수신 대기하며, MCP 엔드포인트는 /mcp, 헬스 체크는 /healthz(인증 불필요)입니다.

MCP Inspector로 테스트하기

npx @modelcontextprotocol/inspector

Inspector UI에서:

  1. 전송 방식: Streamable HTTP

  2. URL: http://localhost:8000/mcp

  3. Authentication에서 헤더 Authorization: Bearer <your MCP_BEARER_TOKEN> 추가

  4. 연결한 다음 create_event를 테스트 제목으로 호출하고 Skylight 앱의 올바른 프로필에 반영되었는지 확인하세요.

Railway에 배포하기

옵션 A: deploy.sh 헬퍼 사용

export SKYLIGHT_EMAIL=you@example.com
export SKYLIGHT_PASSWORD=...
export SKYLIGHT_FRAME_ID=1234567
export MCP_BEARER_TOKEN=$(openssl rand -hex 32)
# optional:
export SKYLIGHT_TIMEZONE=America/Chicago
export SKYLIGHT_DEFAULT_MEMBER=YourName

./deploy.sh

Railway CLI가 없으면 설치하고, 로그인하라는 메시지를 표시하며(브라우저 OAuth — 이 부분은 스크립트로 자동화할 수 없음), 첫 실행 시 프로젝트를 만들고, 모든 환경 변수를 설정한 뒤 배포하고 공개 URL을 출력합니다. skylight_mcp_server.py를 수정한 후 언제든 다시 실행하면 새 빌드를 푸시합니다 — 프로젝트 링크는 이 디렉터리를 키로 하여 ~/.railway/config.json에 저장되며 저장소에는 들어가지 않으므로 Railway 관련 내용이 git에 포함되지 않습니다.

옵션 B: 수동으로

railway login                                  # browser OAuth
railway init --name skylight-mcp               # first time only
railway variable set SKYLIGHT_EMAIL=you@example.com --service skylight-mcp --skip-deploys
railway variable set SKYLIGHT_PASSWORD=... --service skylight-mcp --skip-deploys
railway variable set SKYLIGHT_FRAME_ID=1234567 --service skylight-mcp --skip-deploys
railway variable set MCP_BEARER_TOKEN=$(openssl rand -hex 32) --service skylight-mcp
railway up -c -y --service skylight-mcp        # builds the Dockerfile, deploys
railway domain --service skylight-mcp          # public HTTPS URL, real cert

나중에 다시 배포(코드 변경 후 사용자가 직접, 또는 이미 한 번 설정을 실행한 다른 사람)는 다음만 수행하면 됩니다:

railway up -c -y --service skylight-mcp

이게 재배포의 전부입니다 — 이 저장소에 이미 있는 Dockerfile 외에 추가 설정 파일도, CI 파이프라인도 없습니다. railway logs --service skylight-mcp는 실시간 로그를 따라가며 출력하는데, create_event의 인수가 모든 호출에서 기록되므로 유용합니다(문제 해결 참고).

Pebble의 MCP 클라이언트 설정이 https://<your-railway-domain>/mcp와 설정 시 생성된 bearer 토큰을 가리키게 하세요.

Pebble 앱 구성

Pebble 앱의 MCP 서버 설정에서:

  • Name: 아무 값이나 가능하지만 공백이나 특수 문자는 금지문제 해결 참고. SkylightCalendar 또는 skylight-calendar 모두 작동합니다.

  • URL: https://<your-railway-domain>/mcp

  • Transport: Streamable (드롭다운이 문자 그대로 "SSE/Streamable"입니다 — SSE가 아니라 Streamable을 선택하세요)

  • Authorization: Bearer <your MCP_BEARER_TOKEN>Bearer 접두사를 포함한 전체 문자열

사용자 지정 MCP 도구는 Pebble의 더블 클릭 녹음 모드에서만 실행됩니다(싱글 클릭은 Pebble 자체 기본 동작을 사용합니다). 이 서버가 더블 클릭에서 사용하는 샌드박스 그룹에 할당되어 있는지 확인하세요.

가족 구성원 태그 지정 방식

가족 구성원은 이 서버에 전혀 구성되어 있지 않습니다 — create_event는 실제 Skylight 계정에서 GET /frames/{id}/categories를 호출하고(프로세스당 메모리에 캐시) who 인수를 해당 라벨과 대소문자 구분 없이 매칭합니다. "me"/"myself"/"i"는 SKYLIGHT_DEFAULT_MEMBER로 해석됩니다. 정확히 일치하는 항목이 없으면 동일한 라벨에 대해 퍼지 매칭(difflib)으로 폴백합니다. Pebble의 음성 인식이 흔하지 않은 이름을 변형할 수 있기 때문입니다(예: "Metree" 또는 "May Tree" 모두 "Maitree"로 여전히 해석됨 — 실시간 검증 완료). 그래도 매칭되지 않는 이름은 이벤트를 차단하지 않습니다 — 프로필 태그 없이 생성되며, 확인 메시지에 그렇게 표시되므로 잘못 알아들은 것이 조용히 틀리게 남는 대신 눈에 보입니다.

시도해 볼 예시 문구

각각은 도구의 서로 다른 부분을 테스트합니다 — 하나를 말한 후(링을 더블 클릭) Skylight에서 날짜/시간, 종일 vs. 시간 지정, 어떤 프로필이 태그되었는지 확인하세요:

  • "Add a dentist appointment tomorrow at 2pm." 시간 지정 이벤트, SKYLIGHT_DEFAULT_MEMBER의 프로필에 기본 지정, 위치 없음.

  • "Block off next Monday as a vacation day." 시간을 말하지 않음 → 종일 이벤트로 저장됩니다(날짜만 말해도 자동 감지 — 이를 위해 "all day"라고 말할 필요 없음).

  • "Add a trip to Chicago from the 2nd to the 3rd of September." 여러 날 종일 이벤트 — 두 날짜를 모두 포함하여 걸칩니다.

  • "Add Maitree's haircut next Tuesday at 10am." 명시적 who — 기본값 대신 해당 사람의 프로필을 태그합니다.

  • "Add family movie night Friday at 7pm for Maitree and me." 다중 인물 태그 — 두 사람 모두에게 태그되어 저장됩니다.

  • "Add a dentist appointment at Dr. Smith's office next Wednesday at 3pm." location 필드가 캡처되는지 테스트합니다.

검증된 것 vs. 가정한 것

Skylight API는 비공식적이며 리버스 엔지니어링된 것입니다. 이 서버의 인증 흐름과 페이로드 형태는 2026-08-26/27에 실제 계정으로 실측 테스트되었습니다(정확한 로그인 단계는 skylight_mcp_server.py의 모듈 docstring 참고). 2025년 12월 OpenAPI 캡처에서 가져온 초기 가정과 모순되는 주요 발견 사항:

  • 기존 POST /api/sessions(이메일/비밀번호 → Basic auth) 로그인은 폐기되었습니다 — 이제 401 "This version of Skylight is no longer supported."를 반환합니다. 실제 흐름은 4단계 OAuth2 authorization-code 교환입니다(이 흐름이 성공하는 데 PKCE는 필요하지 않지만, PKCE 변형도 실제로 존재합니다).

  • 모든 API 호출에 skylight-api-version: 2026-05-01이 필요합니다.

  • GET .../calendar_eventsdate_max배타적 상한입니다.

  • 종일 이벤트의 ends_at도 배타적입니다 — 하루 종일 이벤트는 ends_at다음 날 자정이어야 하며(또는 동등하게 starts_at과 같아도 작동), N일 범위는 마지막 포함 날짜의 하루 뒤로 ends_at을 늘려야 합니다. create_event는 이 패딩을 내부적으로 처리하므로 호출자에게는 자체 end 인수가 계속 포함적입니다.

  • 가족 구성원은 생성 페이로드의 category_ids(배열)를 통해 태그됩니다. 카테고리 ID는 GET .../categories에서 가져오며 프로세스별로 캐시됩니다.

Skylight가 API를 다시 변경하면 가장 깨질 가능성이 높은 곳은 _login()(OAuth 단계)과 create_eventcalendar_events 페이로드 형태입니다.

문제 해결

Pebble이 "invalid tool call, action failed"라고 표시하고 캘린더에 아무것도 저장되지 않습니다. 먼저 railway logs --service skylight-mcp를 확인하세요 — 모든 create_event 호출은 원시 인수를 기록하고, Skylight API 오류도 포착되어 기록됩니다. 이 프로젝트에서 실제로 겪었던 두 가지는 다음과 같습니다:

  • Pebble 앱 구성에서 MCP 서버 이름에 공백이나 특수 문자가 있는 경우. Pebble 포럼에서 확인됨: 서버 Name 필드에 공백이 있으면 에이전트가 잘못된 복합 도구 이름을 구성하고 호출이 조용히 서버에 도달하지 못합니다(로그에는 ListToolsRequest가 보이지만 CallToolRequest는 없음). 영숫자와 하이픈으로만 이름을 바꾸세요.

  • 선택적 도구 인수를 nullable(str | None)로 타입 지정한 경우. 일부 엄격한 함수 호출 검증기는 요청을 보내기 전에 anyOf: [string, null]이 포함된 JSON 스키마를 거부합니다. 이 서버는 이를 피하기 위해 일반 str = ""(빈 문자열 = "제공되지 않음")을 사용합니다.

날짜/시간이 파싱되지 않았습니다. create_event는 이를 포착하고 크래시 대신 설명적인 오류 문자열(Pebble이 도구 결과를 표시하는 어디에서든 보임)을 반환하며, 정확히 무엇을 파싱할 수 없었는지 명시합니다.

이벤트가 잘못된 시간(예: 새벽 2시)에 저장되었습니다. 거의 확실히 naive와 UTC의 혼동입니다. create_event의 naive 시간 처리는 항상 SKYLIGHT_TIMEZONE을 가정하며 UTC를 가정하지 않습니다 — 이런 문제가 보이면 Pebble이 실수로 순수 UTC 시간을 보냈는지 확인하세요(기록된 원시 start 인수 확인).

bearer 확인 검증

# No token -> 401
curl -i https://<your-railway-domain>/healthz    # should be 200, no auth needed
curl -i https://<your-railway-domain>/mcp         # should be 401

# With token -> reaches the MCP layer
curl -i https://<your-railway-domain>/mcp \
  -H "Authorization: Bearer <your MCP_BEARER_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Transforms macOS calendar management into a conversational experience using natural language, allowing users to create, manage, and update calendar events seamlessly through an MCP-compatible client.
    327
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage Google Calendar through natural language interactions with features like creating, updating, and deleting events, searching calendars, and supporting natural language date/time inputs.
    27
    2
    MIT
  • F
    license
    Not graded
    quality
    F
    maintenance
    Enables programmatic management of Google Calendar events through natural language interactions, supporting creation, reading, updating, and deletion of events with features for recurring events, attendees, and reminders.
    2

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SarjuThakkar/skylight-mcp-pebble'

If you have feedback or need assistance with the MCP directory API, please join our Discord server