Skip to main content
Glama
mingovvv

tlc-portal-mcp

by mingovvv
README.md
# tlc-portal-mcp

TwolineCloud 포털의 휴가와 타임테이블 기능을 Claude Code, Codex 같은 MCP 클라이언트에서 사용할 수 있게 만든 `stdio` 기반 MCP 서버입니다.

패키지를 `npx`로 실행하면 브라우저 로그인, 휴가 조회/신청, 타임테이블 조회/입력, 버전 진단 같은 작업을 MCP 도구로 사용할 수 있습니다.

## 현재 지원 기능

- 포털 로그인과 인증 상태 확인
- 휴가 유형, 잔여 휴가, 휴가 신청 이력 조회
- 휴가 신청, 취소
- 타임테이블 관리 정보, 입력 가능 기간, 일별 상세 조회
- 타임테이블 프로젝트 목록 조회
- 휴가를 반영한 일별 입력 가능 시간 계산
- 타임테이블 단건/기간 입력 준비 및 제출
- 타임테이블 일별 전체 삭제
- 현재 서버 버전 확인 및 npm 최신 버전 비교

## 요구 사항

- Node.js `18+`
- 포털 로그인이 가능한 브라우저 환경

## 설치 및 등록

### Claude Code

```bash
# 사용자 전역 등록
claude mcp add tlc-portal-mcp --scope user -- npx -y tlc-portal-mcp

# 현재 프로젝트에만 등록
claude mcp add tlc-portal-mcp -- npx -y tlc-portal-mcp
```

### Codex CLI

```bash
# 사용자 전역 등록
codex mcp add tlc-portal-mcp -- npx -y tlc-portal-mcp
```

Codex는 현재 프로젝트 전용 `add` 명령이 별도로 없으므로, 필요하면 프로젝트 루트의 `.codex/config.toml`에 직접 추가할 수 있습니다.

```toml
[mcp_servers.tlc-portal-mcp]
command = "npx"
args = ["-y", "tlc-portal-mcp"]
```

## 실행 방식 메모

- `mcp add ... -- npx -y tlc-portal-mcp`는 전역 설치가 아니라 실행 명령 등록입니다.
- 실제 패키지 다운로드는 클라이언트가 서버를 처음 실행할 때 일어납니다.
- 매번 새로 설치하는 것은 아니고, 실행 환경에 따라 캐시된 버전이 재사용될 수 있습니다.
- 그래서 서버에는 현재 버전과 최신 버전을 확인하는 `system.*` 도구가 포함되어 있습니다.

## 인증 방법

### 권장: `auth.login`

브라우저를 열어 사용자가 직접 로그인하면 `localStorage['vuex']`의 JWT를 자동 저장합니다.

1. `auth.login` 실행
2. 브라우저에서 포털 로그인과 MFA 완료
3. 로그인 성공 후 토큰 자동 저장
4. `auth.status`로 인증 상태 확인

로그인 성공 후 브라우저에는 안내 오버레이가 표시됩니다.

### 대체: `auth.import_vuex`

자동 로그인 흐름을 쓰기 어렵다면 브라우저에서 `vuex` 값을 직접 가져와 붙여넣을 수 있습니다.

1. 브라우저에서 포털 로그인
2. DevTools에서 `Application > Local Storage > https://portal.twolinecloud.com` 이동
3. `vuex` 값 복사
4. `auth.import_vuex` 실행 후 붙여넣기

## 도구 목록

### 시스템

| Tool | 설명 |
|------|------|
| `system.info` | 현재 실행 중인 서버 이름, 버전, 등록된 도구 목록 반환 |
| `system.check_update` | npm 최신 버전과 현재 버전을 비교 |

### 인증

| Tool | 설명 |
|------|------|
| `auth.login` | 브라우저 로그인 후 JWT 자동 저장 |
| `auth.import_vuex` | `localStorage['vuex']`를 붙여넣어 인증 |
| `auth.status` | 현재 인증 상태 확인 |
| `auth.clear` | 로컬 세션 삭제 |

### 휴가

| Tool | 설명 |
|------|------|
| `leave.list_types` | 지원하는 휴가 유형 조회 |
| `leave.get_balances` | 잔여 휴가 조회 |
| `leave.list_requests` | 휴가 신청 이력 조회 |
| `leave.prepare_request` | 휴가 신청 payload 준비 |
| `leave.submit_prepared_request` | 준비된 휴가 신청 제출 |
| `leave.cancel_request` | 기존 휴가 신청 취소 |

### 타임테이블

| Tool | 설명 |
|------|------|
| `timetable.get_manage_info` | 타임테이블 관리/마감 정보 조회 |
| `timetable.get_user_summary` | 현재 사용자의 타임테이블 현황 조회 |
| `timetable.get_available_range` | 입력 가능 기간 조회 |
| `timetable.get_day` | 특정 날짜 타임테이블 상세 조회 |
| `timetable.get_range_overview` | 날짜 범위 전체를 타임테이블 + 공휴일/휴가 capacity와 함께 요약 |
| `timetable.list_projects` | 타임테이블에 입력 가능한 프로젝트 목록 조회 |
| `timetable.get_day_capacity` | 휴가를 반영한 해당 날짜 입력 가능 시간 계산 |
| `timetable.prepare_day_entry` | 단일 날짜 타임테이블 입력 준비 |
| `timetable.submit_prepared_day_entry` | 준비된 단일 날짜 입력 제출 |
| `timetable.prepare_bulk_entries` | 기간 기준 일괄 입력 준비 |
| `timetable.submit_prepared_bulk_entries` | 준비된 일괄 입력 제출 |
| `timetable.clear_day` | 특정 날짜 타임테이블 전체 삭제 |

## 타임테이블 규칙

- 기본 입력 가능 시간은 하루 8시간입니다.
- 반차(`AM`, `PM`, `admitAm`, `admitPm`)가 있으면 최대 4시간만 기록할 수 있습니다.
- 종일 휴가(`allDay`, `admit`)가 있으면 해당 날짜에는 기록할 수 없습니다.
- 한국 공휴일은 기본적으로 Nager.Date API에서 조회하고, 실패 시 내장 fallback 데이터를 사용합니다.
- 주말과 회사 공통 휴무일(`PORTAL_COMPANY_HOLIDAYS`)도 입력 불가로 처리합니다.
- 개인 휴가 overlay는 포털 overview 규칙에 맞춰 `vacation-svc/request/secure`의 `requestDt` 정렬 결과를 기준으로 계산합니다.
- `workDate`와 `taskType`은 항상 필요합니다.
- `projectId`는 기본적으로 필요합니다.
- 단, `taskType === NORMAL`이면 `projectId` 없이 입력할 수 있습니다.
- 쓰기 작업은 `prepare -> submit` 흐름을 따릅니다.

## 권장 사용 순서

### 초기 진단

1. `system.info`
2. `system.check_update`
3. `auth.status`
4. 필요 시 `auth.login`

### 휴가 흐름

1. `leave.get_balances`
2. `leave.list_requests`
3. `leave.prepare_request`
4. `leave.submit_prepared_request`

### 타임테이블 흐름

1. `timetable.get_available_range`
2. `timetable.get_range_overview`
3. `timetable.list_projects`
4. `timetable.get_day_capacity`
5. `timetable.prepare_day_entry` 또는 `timetable.prepare_bulk_entries`
6. `timetable.submit_prepared_day_entry` 또는 `timetable.submit_prepared_bulk_entries`

## 사용 예시

```text
"현재 서버 버전이랑 최신 버전 비교해줘"
-> system.check_update

"내 휴가 잔여 일수 보여줘"
-> leave.get_balances

"이번 달 휴가 신청 이력 보여줘"
-> leave.list_requests

"4월 30일 오전 반차 신청 준비해줘"
-> leave.prepare_request

"오늘 입력 가능한 타임테이블 시간 계산해줘"
-> timetable.get_day_capacity

"2026년 2월 타임테이블 전체를 공휴일 포함해서 요약해줘"
-> timetable.get_range_overview

"2026-04-05에 프로젝트 274로 4시간, taskType EXECUTE로 입력 준비해줘"
-> timetable.prepare_day_entry

"오늘 일반업무 2시간, taskType NORMAL로 입력 준비해줘"
-> timetable.prepare_day_entry

"4월 1일부터 4월 3일까지 같은 내용으로 일괄 입력 준비해줘"
-> timetable.prepare_bulk_entries
```

## 환경 변수

| 변수 | 기본값 | 설명 |
|------|--------|------|
| `PORTAL_BASE_URL` | `https://portal.twolinecloud.com` | 포털 기본 주소 |
| `PORTAL_LOGIN_PATH` | `/` | 로그인 진입 경로 |
| `PORTAL_LOGIN_SUCCESS_URL` | `/dashboard/landing` | 로그인 성공 후 도달 URL |
| `PORTAL_MCP_SESSION_FILE` | `.portal-session.json` | 로컬 세션 저장 파일 |
| `PORTAL_TIMEOUT_SECONDS` | `15` | API 요청 타임아웃 초 |
| `PORTAL_COMPANY_HOLIDAYS` | `` | 쉼표로 구분한 회사 공통 휴무일 목록 (`YYYY-MM-DD,YYYY-MM-DD`) |
| `PORTAL_HOLIDAY_API_BASE_URL` | `https://date.nager.at/api/v3` | 한국 공휴일 조회 API base URL |

## 제한 사항

- JWT 유효 시간은 현재 기준 약 2시간입니다.
- 토큰이 만료되면 `auth.login` 또는 `auth.import_vuex`를 다시 실행해야 합니다.
- Refresh token은 사용하지 않습니다.
- 세션 파일은 로컬에만 저장되며 서버로 업로드되지 않습니다.
- `system.check_update`는 npm registry 접근이 가능한 환경에서만 최신 버전을 확인할 수 있습니다.
- 공휴일 조회 API가 실패하면 내장 fallback 데이터로 판정합니다.
- 타임테이블의 `NORMAL` + `projectId` 없음 조합은 문서 기준 허용 흐름으로 구현되어 있지만, 실제 포털 백엔드 수용 여부는 운영 환경에서 추가 확인이 필요합니다.

TDQS

B3.4/5.0

Scored across 10 tools

Disambiguation4/5

Most tools target distinct resources and actions, especially within the leave namespace. The only possible confusion is between auth.login and auth.import_vuex, but their descriptions clearly separate browser-based login from importing an existing Vuex auth state.

Naming Consistency4/5

Tool names consistently follow a verb_noun pattern with clear namespace prefixes like auth and leave. auth.status is a minor deviation as a noun, but overall the naming is predictable and easy to navigate.

Tool Count5/5

Ten tools is a well-scoped size for a portal MCP server covering authentication and leave management. Each tool has a clear role, and the count feels neither bloated nor thin.

Completeness4/5

The leave workflow is well covered: types, balances, listing, preparing, submitting, and cancelling requests. Minor gaps include no direct request detail view or update/edit path, but cancel-and-recreate is a reasonable workaround.

Maintenance

ActivityInactive
ResponsivenessNo issues