Waple Worklog MCP Server

Waple Worklog MCP Server

Automatically collects work data from Git history and Claude Code session logs to generate daily worklog drafts, and registers approved logs to the Waple HR platform.

Category
Visit Server

README

Waple 업무일지 MCP 서버

개발자가 하루 동안 수행한 작업을 Git 기록과 Claude Code 세션 로그에서 자동으로 수집하여 업무일지 초안을 만들고, 사용자가 승인한 내용만 HR SaaS 플랫폼(Waple)에 등록하는 MCP 서버입니다.

8주 인턴 팀 프로젝트(4인) 중 MCP 서버 파트를 담당하여 개발하였습니다. 코드 리뷰는 팀원이 수행하였으며, PR #13에서 지적받은 인증 처리 결함을 반영해 구조를 수정하였습니다.


1. 왜 만들었는가

업무일지는 매일 써야 하지만, 하루가 끝날 무렵에는 무엇을 했는지 정확히 기억나지 않습니다. 그 결과 "개발 진행함" 같은 내용 없는 기록이 쌓이고, 인사 데이터로서의 가치를 잃습니다.

이미 커밋 메시지와 변경 파일에 하루의 기록이 남아 있는데도 다시 손으로 쓰고 있다는 점에 주목하였습니다. 그래서 이미 존재하는 근거를 모아 초안을 만들고, 사람은 확인만 하는 방향으로 설계하였습니다.


2. 시연

로컬 시연 (3분 51초) — 초안 생성부터 승인·등록까지 전체 흐름

https://github.com/user-attachments/assets/11a2e83e-085b-435b-8d98-cd3bad4a6dc9

등록 결과 (1분 43초) — Waple 웹 화면에서 등록된 업무일지 확인

https://github.com/user-attachments/assets/4606369c-0ba7-4db5-b42f-f2e1ab72ff88

실제 생성된 초안 (2026-07-25)

오늘 한 일
- test_connector.py 의 import 문을 파일 상단으로 정리하였습니다. [커밋 97a822d9]
- 포트폴리오용 시연 자료를 촬영하였습니다. [사용자 메모]
- 오늘 사용한 토큰: 세션 로그에서 자동 집계[Claude Code 세션 로그]

각 항목 끝의 대괄호가 작성 근거입니다. 커밋에서 나온 내용인지, 사용자가 직접 적은 메모인지, 세션 로그에서 집계한 값인지 구분됩니다. 근거가 없는 내용은 지어내지 않고 "사용자 확인 필요" 항목으로 분리합니다.


3. 동작 구조

[Claude Code / Claude 데스크톱 앱]
            │  MCP 프로토콜
            ▼
    ┌───────────────────┐
    │   MCP 서버        │
    │  (server.py)      │
    ├───────────────────┤
    │ 근거 수집          │ ← git log / git diff / 세션 로그(JSONL)
    │ 업무 단위 분류     │
    │ 초안 생성          │
    │ 승인 확인          │ ← 여기서 멈춤. 승인 전에는 등록하지 않음
    │ Waple API 호출     │ ──▶ POST /api/mcp/diary
    └───────────────────┘

이중 transport 구조

방식 용도 인증
stdio 로컬 Claude Code .env 파일의 키
Streamable HTTP 원격 접속 (nginx + HTTPS) 요청 헤더 x-api-key

HTTP 하나로 통일하지 못한 이유가 있습니다. 원격 서버는 사용자 PC의 Claude Code 세션 로그(~/.claude/projects)에 접근할 수 없어 토큰 사용량 집계가 불가능합니다. 기능을 유지하려면 두 경로가 모두 필요하였습니다.


4. 제공 도구

도구 역할
waple_login API 키 검증
tasklog Git 기록 기반 초안 생성 (로컬 전용)
chat_tasklog 대화 내용 기반 초안 생성 (원격 지원)
submit_worklog 승인된 초안만 Waple에 등록

초안 생성과 등록을 의도적으로 다른 도구로 분리하였습니다. 하나로 합치면 "정리해줘"라는 말에도 등록이 실행될 수 있기 때문입니다.


5. 설계 시 신경 쓴 부분

승인 없이는 등록하지 않는다

정리해줘, 초안 만들어줘, 검토해줘 는 승인으로 보지 않습니다. 등록해, 승인, 이 내용으로 올려 처럼 명확한 표현이 있을 때만 API를 호출합니다.

요청별 키 격리

원격 모드에서는 여러 사용자가 같은 서버 프로세스를 공유합니다. ContextVar 로 요청마다 키를 분리하고, 초안 캐시도 키의 해시값으로 사용자별 스코핑하여 다른 사용자의 초안이 섞이지 않도록 하였습니다.

HTTP 모드에서는 키를 저장하지 않는다

.env 저장 로직은 stdio 모드에서만 동작합니다. 원격 사용자의 키가 서버 파일에 남는 것을 막기 위함입니다.


6. 빠른 시작

git clone https://github.com/psy0635-ctrl/waple-worklog-mcp-portfolio.git
cd waple-worklog-mcp-portfolio

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt

cp .env.example .env             # 실제 값을 채워 넣습니다

로컬 실행 (Claude Code)

cp .mcp.json.example .mcp.json
claude                           # 실행 후 /mcp 로 연결 확인

원격 실행 (Streamable HTTP)

python server.py --transport streamable-http --port 8010
claude mcp add --transport http waple-remote \
  https://[SERVER_URL]/llm/mcp --header "x-api-key: 발급받은키"

자세한 배포·연동 절차는 docs/integration-manual.md 를 참고하십시오.


7. 테스트

python -m pytest -q
22 passed, 1 skipped

skipped 1건은 로그 폴더 대소문자 혼재 케이스입니다. Windows 파일시스템에서는 대소문자만 다른 폴더를 동시에 만들 수 없어 건너뛰고, 리눅스에서 별도로 실행해 통과를 확인하였습니다.

파일 검증 내용
test_connector.py 원격 커넥터, 사용자별 초안 스코핑
test_cache.py 초안 캐시 동작
test_guideline17.py 승인 절차·필수값 누락·중복 등록 방지
test_login_retry.py 인증 실패 시 재시도 안내
test_token_usage.py 세션 로그 기반 토큰 집계
test_draft_cleanup.py 초안 캐시 누적 방지 (등록 후 삭제, TTL 정리)

8. 검증 현황

사실과 추정을 구분하기 위해 항목마다 검증 수준을 표기하였습니다.

항목 결과 검증 수준
로컬(stdio) 전체 흐름 초안 생성 → 승인 → Waple 등록 성공 실물 검증
원격(HTTP) 연동 Claude Code 에서 호출, 서버 로그에 기록 확인 실물 검증
자동 재시작 프로세스 강제 종료 후 PID 변경 확인 실물 검증
재부팅 후 자동 기동 systemctl --user is-enabled, Linger=yes 확인 설정 확인 (재부팅 미실시)
claude.ai 웹 커넥터 도구 목록 조회 19건 / 실호출 0건 (서버 로그 대조) 실물 검증 (로그 인접성 기반)

웹 커넥터가 되지 않는 이유는 추정이 아니라 서버 로그로 확인하였습니다. 5일간(2026.07.21 ~ 07.25) 누적된 요청을 발신 경로별로 대조한 결과입니다.

발신 경로 도구 목록 조회 도구 호출
claude.ai 웹 커넥터 19건 0건
설정 파일 기반 클라이언트 (Claude Code, 데스크톱 앱) 26건 12건

웹 커넥터 쪽 응답 코드는 200과 202뿐이고 4xx·5xx는 없었습니다. 연결·TLS·프록시·목록 조회까지는 정상이었고, 도구 호출 요청 자체가 도달하지 않았습니다. 같은 서버·같은 엔드포인트인데 한쪽만 호출이 성립하며, 두 경로의 차이는 인증 키를 요청 헤더에 실을 수단이 있는가 하나뿐입니다. 이 서버는 x-api-key 헤더로 인증하는데, 웹 UI 에서는 해당 헤더를 지정할 방법을 찾지 못했습니다.

마스킹한 로그 발췌는 docs/evidence/webconnector_evidence_masked.txt 에 있습니다.


9. 막혔던 부분

문제 원인 해결
원격 접속 시 421 반환 FastMCP 의 DNS Rebinding 방지로 허용 Host 가 127.0.0.1 로 잠김 nginx 에서 Host 헤더를 재작성해 우회
커넥터 연결 실패 HTTPS 인증서 체인에 중간 인증서 누락 브라우저는 자동 보완되지만 서버 간 통신은 실패함을 확인, fullchain 적용
서버 재부팅 후 중단 nohup 프로세스가 재부팅과 함께 소멸 sudo 권한이 제한된 환경이라 사용자 systemd + linger 로 해결
API 키 터미널 노출 키 확인 과정에서 값이 평문 출력됨 키 삭제 후 재발급. 이후 키를 다루는 명령은 값이 표시되지 않는 방식으로 변경

마지막 항목이 가장 뼈아팠습니다. 키를 재발급하기만 해서는 기존 키가 살아 있다는 점을 뒤늦게 알았고, 반드시 기존 키를 삭제해야 무효화된다는 것을 확인하였습니다.

각 사례의 판단 과정은 docs/development-notes.md 에 정리해 두었습니다.


10. 기술 스택

Python · MCP Python SDK (FastMCP) · requests · pytest nginx (리버스 프록시, HTTPS) · systemd (사용자 서비스)


11. 문서

문서 내용
docs/waple-worklog-mcp-상세설명.pdf 프로젝트 전체 과정 상세 설명 (인쇄용)
docs/integration-manual.md 설치·배포·연동 절차
docs/connector-design.md 근거 수집 설계
docs/development-notes.md 개발 기록, 오류 사례, 설계 편차와 근거
deploy/README.md systemd 운영 가이드
docs/evidence/ 웹 커넥터 검증에 사용한 서버 로그 발췌 (마스킹)

12. 남은 과제

  • server.py 에 transport_security 를 명시하여 nginx 우회 없이 Host 검증 통과
  • 원격 모드에서 Git·토큰 수집이 불가능한 구조적 한계

회사 도메인·서버 주소·포트 등 인프라 정보는 [SERVER_URL] 형태의 플레이스홀더로 대체하였습니다.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured