Waple Worklog MCP Server
Integrates with Git repositories to collect commit history, diffs, and session logs for automatic worklog draft generation.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Waple Worklog MCP Servergenerate today's worklog draft from git and session logs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Waple 업무일지 MCP 서버
개발자가 하루 동안 수행한 작업을 Git 기록과 Claude Code 세션 로그에서 자동으로 수집하여 업무일지 초안을 만들고, 사용자가 승인한 내용만 HR SaaS 플랫폼(Waple)에 등록하는 MCP 서버입니다.
8주 인턴 팀 프로젝트(4인) 중 MCP 서버 파트를 담당하여 개발하였습니다. 코드 리뷰는 팀원이 수행하였으며, PR #13에서 지적받은 인증 처리 결함을 반영해 구조를 수정하였습니다.
1. 왜 만들었는가
업무일지는 매일 써야 하지만, 하루가 끝날 무렵에는 무엇을 했는지 정확히 기억나지 않습니다. 그 결과 "개발 진행함" 같은 내용 없는 기록이 쌓이고, 인사 데이터로서의 가치를 잃습니다.
이미 커밋 메시지와 변경 파일에 하루의 기록이 남아 있는데도 다시 손으로 쓰고 있다는 점에 주목하였습니다. 그래서 이미 존재하는 근거를 모아 초안을 만들고, 사람은 확인만 하는 방향으로 설계하였습니다.
Related MCP server: Povio Worklog MCP Server
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 |
|
Streamable HTTP | 원격 접속 (nginx + HTTPS) | 요청 헤더 |
HTTP 하나로 통일하지 못한 이유가 있습니다. Git 기록과 세션 로그는 사용자 PC에 있는 자료입니다. 원격 서버는 이 자료에 접근할 수 없으므로, 자동 수집 기능을 유지하려면 로컬 경로가 함께 필요하였습니다.
이 구분이 실제로 얼마나 중요한지는 프로젝트가 끝난 뒤에야 드러났습니다(9절 참고).
원격의 tasklog 는 "아무것도 읽지 못하는" 상태가 아니라 서버 자신의 저장소를
읽는 상태였고, 그래서 지금은 HTTP 모드에서 호출을 차단합니다.
4. 제공 도구
도구 | 역할 |
| API 키 검증 |
| Git 기록 기반 초안 생성 (로컬 전용, 원격 호출은 차단) |
| 대화 내용 기반 초안 생성 (원격 지원) |
| 승인된 초안만 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 8010claude mcp add --transport http waple-remote \
https://[SERVER_URL]/llm/mcp --header "x-api-key: 발급받은키"자세한 배포·연동 절차는 docs/integration-manual.md 를 참고하십시오.
7. 테스트
python -m pytest -q70 passed, 1 skippedskipped 1건은 로그 폴더 대소문자 혼재 케이스입니다.
Windows 파일시스템에서는 대소문자만 다른 폴더를 동시에 만들 수 없어 건너뛰고,
리눅스에서 별도로 실행해 통과를 확인하였습니다.
파일 | 검증 내용 |
| 원격 커넥터, 사용자별 초안 스코핑, 원격 |
| 초안 캐시 동작 |
| 승인 절차·필수값 누락·중복 등록 방지 |
| 인증 실패 시 재시도 안내 |
| 세션 로그 기반 토큰 집계 |
| 초안 캐시 누적 방지 (등록 후 삭제, TTL 정리) |
| 여러 줄 입력 시 불릿·근거 라벨 정규화 ( |
8. 검증 현황
사실과 추정을 구분하기 위해 항목마다 검증 수준을 표기하였습니다.
항목 | 결과 | 검증 수준 |
로컬(stdio) 전체 흐름 | 초안 생성 → 승인 → Waple 등록 성공 | 실물 검증 |
원격(HTTP) 연동 | Claude Code 에서 호출, 서버 로그에 기록 확인 | 실물 검증 |
자동 재시작 | 프로세스 강제 종료 후 PID 변경 확인 | 실물 검증 |
재부팅 후 자동 기동 |
| 설정 확인 (재부팅 미실시) |
claude.ai 웹 커넥터 | 연결·도구 목록·도구 호출은 성공, 인증은 불가 (헤더 지정 수단 없음) | 실물 검증 (직접 호출 + 설정 화면 확인) |
원격 | 배포 서버에서 호출 → 차단 응답 반환, 서버 로그에 호출 기록 | 실물 검증 (9절) |
웹 커넥터가 되지 않는 이유는 추정이 아니라 서버 로그로 확인하였습니다. 5일간(2026.07.21 ~ 07.25) 누적된 요청을 발신 경로별로 대조한 결과입니다.
발신 경로 | 도구 목록 조회 | 도구 호출 |
claude.ai 웹 커넥터 | 19건 | 0건 |
설정 파일 기반 클라이언트 (Claude Code, 데스크톱 앱) | 26건 | 12건 |
웹 커넥터 쪽 응답 코드는 200과 202뿐이고 4xx·5xx는 없었습니다. 연결·TLS·프록시·목록 조회까지는 정상이었고, 이 기간에는 도구 호출이 성립하지 않았습니다.
이후 2026-07-28 에 웹 커넥터로 도구를 직접 호출해 서버 응답을 받았습니다. 관찰에서 추론하던 원인을 실물로 확정한 것입니다.
시점 | 도구 목록 조회 | 도구 호출 | 인증 |
2026.07.21 ~ 07.25 | 19건 | 0건 | (판단 불가) |
2026.07.28 | 정상 (4개 인식) | 성공 | 실패 |
07.28 호출 시 서버가 반환한 것은 "요청에 x-api-key 헤더가 없다"는 안내였습니다.
즉 연결과 도구 호출은 되지만 인증 수단이 없어 실사용이 불가능한 상태입니다.
claude.ai 웹 커넥터의 설정 화면에서 제공되는 인증 항목은 고급 설정을 펼쳐도
OAuth 클라이언트 ID·시크릿 두 가지뿐이며, 임의의 요청 헤더를 지정하는 입력란은
제공되지 않습니다(2026-07-28 화면 확인). 이 서버는 x-api-key 헤더로 인증하므로
웹 커넥터 경로로는 인증이 성립하지 않습니다.
설정 파일 기반 클라이언트(Claude Code --header, 데스크톱 앱 mcp-remote 브리지)는
헤더를 지정할 수 있어 정상 동작합니다.
검토했으나 원인이 아니었던 것: FastMCP 의 DNS Rebinding 방어가 Origin 헤더를 검증해
https://claude.ai를 403 으로 거부할 가능성을 확인하였습니다. 그러나 위 로그에서 웹 커넥터 요청의 응답 코드는 200·202 뿐이고 403 이 한 건도 없었으므로, Origin 차단은 실제로 발생하지 않았습니다. 현재 허용 목록에 해당 Origin 이 포함되어 있으나 이는 버그 수정이 아니라 예방적 조치입니다.
webconnector_0728_evidence_masked.txt의 139행에 403 이 한 건 있으나 이는 Origin 차단 동작을 확인하기 위해 직접 실행한 curl 요청이며, 웹 커넥터 발신 요청(160.79.106.x)의 응답은 200·202 뿐입니다. 차단 기능은 정상 동작하되 웹 커넥터 실패의 원인은 아니었음을 같은 파일에서 확인할 수 있습니다.
마스킹한 로그 발췌는 두 파일로 나누어 두었습니다.
docs/evidence/webconnector_evidence_masked.txt — 2026.07.21~07.25 구간, 웹 커넥터 발신 요청 0건 확인
docs/evidence/webconnector_0728_evidence_masked.txt — 2026.07.28 구간, 도구 호출 도달 및 응답 코드 기록
9. 막혔던 부분
문제 | 원인 | 해결 |
원격 접속 시 421 반환 | FastMCP 의 DNS Rebinding 방지로 허용 Host 가 | 우선 nginx 에서 Host 헤더를 재작성해 우회. 이후 |
커넥터 연결 실패 | HTTPS 인증서 체인에 중간 인증서 누락 | 브라우저는 자동 보완되지만 서버 간 통신은 실패함을 확인, fullchain 적용 |
서버 재부팅 후 중단 |
| sudo 권한이 제한된 환경이라 사용자 systemd + linger 로 해결 |
API 키 터미널 노출 | 키 확인 과정에서 값이 평문 출력됨 | 키 삭제 후 재발급. 이후 키를 다루는 명령은 값이 표시되지 않는 방식으로 변경 |
프로젝트 종료 후 개선 (2026-07-28)
421 은 nginx 우회로 이미 해결된 상태였지만, 근본 원인을 다시 확인한 결과 SDK 가 방어를 켜주는 조건이 실행 옵션에 달려 있다는 점을 발견하였습니다.
FastMCP 는 생성자의 host 가 127.0.0.1/localhost/::1 일 때만 DNS Rebinding
방어를 자동 활성화합니다. 그런데 이 서버의 실행 인자 도움말은 "외부 공개 배포 시
0.0.0.0" 을 안내하고 있었습니다. 안내대로 실행하면 보안 기능이 경고 한 줄 없이
꺼지는 구조였습니다.
허용 Host·Origin 을 코드에 직접 명시해 실행 옵션·SDK 버전과 무관하게 동일한 설정이 적용되도록 수정하였습니다. 배포 서버에서 적용 전후를 측정한 결과입니다.
측정 조건 | before | after |
정상 요청 | 406 | 406 |
위조 Host | 421 | 421 (방어 유지) |
도메인 Host | 421 | 406 |
| 403 | 406 |
외부 HTTPS 경유 | 406 | 406 |
허용 목록을 SDK 자동 기본값의 상위집합으로 구성하여, 기존에 동작하던 경로가 막히지 않도록 하였습니다. 적용 후 MCP 핸드셰이크와 도구 호출까지 실측하였습니다. nginx 의 Host 재작성은 이중 안전망으로 그대로 유지하였습니다.
프로젝트 종료 후 개선 (2026-07-29) — 내가 남긴 기록이 틀렸던 사례
원격 환경에서 tasklog 를 호출하면 어떻게 되는지, 문서에는 이렇게 적혀 있었습니다.
초안 자체는 생성되지만 Git 커밋·변경 파일·토큰 사용량이 모두 비어 있습니다. (2026-07-21 기록)
원격 서버가 사용자 PC 에 접근할 수 없으니 당연히 비어 있으리라 여겼고, 실제로 비어 있는 초안을 한 번 보고 그대로 기록하였습니다. 그러나 실사용 중 다시 확인해 보니 초안에 커밋이 채워져 있었습니다. 제가 그날 하지 않은 작업이었습니다.
원인은 서비스 설정 한 줄에 있었습니다.
WorkingDirectory=%h/2026-uxis-mirae/llm팀tasklog 는 git rev-parse --show-toplevel 로 저장소 루트를 찾는데, 이 명령이
기준으로 삼는 것은 프로세스가 실행 중인 디렉터리입니다. 원격 모드에서 그
디렉터리는 사용자의 작업 폴더가 아니라 배포 서버가 체크아웃해 둔 저장소였습니다.
즉 원격 사용자의 업무일지에 배포 서버의 커밋 이력이 실리는 구조였습니다.
토큰 집계도 같은 이유로 서버 계정의 ~/.claude 를 읽고 있었습니다.
이 문제가 위험한 이유는 틀린 결과가 정상처럼 보인다는 점입니다. 수집이 비어 있으면 사용자가 이상을 눈치채지만, 그럴듯한 커밋 목록이 채워져 있으면 그대로 승인하게 됩니다. 이 프로젝트가 처음부터 지켜 온 원칙 — 확인되지 않은 내용을 사실처럼 쓰지 않는다 — 이 정면으로 깨지는 경로였습니다.
수정은 수집이 시작되기 이전에 차단하는 방식으로 하였습니다.
요청이 HTTP 인지 판별하는 값(ContextVar)은 사용자별 키 격리를 위해 이미
만들어 둔 것이라, 도구 진입점 한 곳에서 조기 반환하는 것으로 충분하였습니다.
조기 반환이므로 초안 캐시가 오염되지 않아, 등록 도구가 잘못된 초안을 집어갈
경로도 함께 사라집니다.
확인 항목 | 결과 |
원인 |
|
차단 동작 | 배포 서버에 도구 호출 → 차단 응답 반환, 서버 로그에 호출 기록 |
초안 캐시 | 조기 반환으로 미오염 (단위 테스트) |
로컬 경로 회귀 | 기존대로 초안 생성 (단위 테스트) |
테스트 | 3케이스 추가, 22 → 25 passed |
함께 정정한 것은 코드만이 아닙니다. "수집 항목이 비어 있다" 는 서술이 README·연동 매뉴얼 여러 곳에 퍼져 있었고, 그 문장들을 모두 찾아 실제 동작으로 고쳤습니다. 잘못된 관찰 하나가 문서 전체로 번지면 나중에는 어디까지가 사실인지 알 수 없게 된다는 것을 확인한 사례입니다.
프로젝트 종료 후 개선 (2026-07-29) — 막다른 길을 알려주던 안내
인증에 실패했을 때 서버가 돌려주던 안내는 이랬습니다.
커넥터 설정 → Request Headers → x-api-key 항목에 Waple API 키를 입력해 주세요.
그런데 8절에 적은 대로, claude.ai 웹 커넥터에는 그 입력란이 없습니다. 인증에 실패한 사용자에게 존재하지 않는 화면을 찾아가라고 안내하고 있었던 것입니다.
실제로 헤더를 지정할 수 있는 세 경로(Claude Code --header, 데스크톱 앱
mcp-remote 브리지, 로컬 stdio)와 웹 커넥터로는 불가능하다는 사실을 함께
안내하도록 교체하였습니다.
고치면서 원인을 하나 더 확인하였습니다. 같은 문구가 waple_login 과
submit_worklog 두 곳에 복사되어 있었습니다. 한쪽만 고치면 두 안내가 서로
다른 말을 하게 되므로, 상수로 분리하고 두 도구가 같은 상수를 참조하는지를
테스트로 고정하였습니다. 문구 자체보다 이 중복이 재발 지점이었습니다.
배포 서버에 키 없이 등록 도구를 호출해 새 안내가 반환되는 것까지 확인하였습니다.
프로젝트 종료 후 개선 (2026-07-30)
tomorrow_plan·memo·activities·created_files에 개행이 포함된 값을
넣으면, "- "와 근거 라벨이 조립된 문자열의 첫 줄 또는 마지막 줄에만 붙고
중간 줄은 아무 표시 없이 남는 문제를 확인하였습니다. tomorrow_plan은
글머리 기호만 깨지지만, memo·activities는 라벨이 사라진 줄이 Git에서
확인된 사실처럼 보이게 되어, 확인되지 않은 내용을 사실처럼 쓰지 않는다는
이 프로젝트의 원칙을 정면으로 어기는 경로였습니다.
원인은 같은 조립 로직(f"- {값} [라벨]")이 두 함수에 복사되어 있었던
것입니다. _format_bullet_lines 헬퍼로 로직을 통합해, 값을 줄 단위로
분해한 뒤 각 줄마다 독립적으로 "- "와 근거 라벨을 붙이도록 수정하였습니다.
수정 전(ad8ce45)과 수정 후(47e38ba) 상태에서 같은 재현 스크립트를
실행한 결과를 한 파일에서 대조할 수 있도록 근거로 남겼습니다
(docs/evidence/multiline_input_evidence.txt).
이 근거 파일을 처음 만드는 과정에서 셸을 혼용해 캡처에 실패한 사고가
있었는데, 그 경위는 docs/development-notes.md
13절 "기록 무결성"에 정리하였습니다.
확인 항목 | 결과 |
원인 | 조립 로직 복붙 (코드 확인) |
재현 | 수정 전( |
수정 |
|
테스트 | 13케이스 추가, 28 → 41 passed |
(부수 정정) 이 정리 과정에서 위 7절의 테스트 총계가 실제로는 이미 7/29에
28이었어야 하는데 25로 방치되어 있던 것을 확인하여, 41로 갱신하며 함께
정정하였습니다(test_connector.py import 정리 항목도 이미 완료 상태로
남아 있던 것을 development-notes.md에서 함께 정리하였습니다).
마지막 항목이 가장 뼈아팠습니다. 키를 재발급하기만 해서는 기존 키가 살아 있다는 점을 뒤늦게 알았고, 반드시 기존 키를 삭제해야 무효화된다는 것을 확인하였습니다.
각 사례의 판단 과정은 docs/development-notes.md 에 정리해 두었습니다.
10. 기술 스택
Python · MCP Python SDK (FastMCP) · requests · pytest nginx (리버스 프록시, HTTPS) · systemd (사용자 서비스)
11. 문서
문서 | 내용 |
프로젝트 전체 과정 상세 설명 (인쇄용) | |
설치·배포·연동 절차 | |
근거 수집 설계 | |
개발 기록, 오류 사례, 설계 편차와 근거 | |
systemd 운영 가이드 | |
웹 커넥터 검증에 사용한 서버 로그 발췌 (마스킹) |
12. 남은 과제
원격 모드에서는 Git 기록·토큰 사용량 자동 수집이 원리상 불가능한 구조적 한계 (현재는 차단 후
chat_tasklog로 안내하며, 대체 수집 경로는 없음)
회사 도메인·서버 주소 등 인프라 정보는
[SERVER_URL]형태의 플레이스홀더로 대체하였습니다. 서비스 포트는 nginx 설정과 배포 구조를 설명하는 데 필요하여 그대로 두었습니다. 도메인·주소가 가려져 있어 포트만으로는 접근 경로가 성립하지 않습니다.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- -licenseAquality-maintenanceEnables natural language time tracking through Claude with markdown file storage. Supports multi-company tracking, flexible time parsing, auto-calculated summaries, and commitment warnings all through conversational input.1
- AlicenseAqualityDmaintenanceAutomates the generation of professional worklogs by analyzing git commits with AI enhancement and seamlessly posting them to the Povio dashboard. It enables users to list projects, extract ticket numbers, and manage worklog entries through natural language commands.4142MIT
- AlicenseBqualityDmaintenanceGenerates standup reports from git history by analyzing recent commits across configured repositories. Enables users to query their development activity, such as what they worked on yesterday or over multiple days, through natural language interactions with Claude.2MIT
- Flicense-qualityFmaintenanceEnables logging time to Tempo (Jira time tracker) via natural language in Claude Desktop or OpenCode.
Related MCP Connectors
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Persistent context for Claude. Your AI always knows your projects and next actions across sessions.
Connect Claude to Fathom meeting recordings, transcripts, and summaries
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/psy0635-ctrl/waple-worklog-mcp-portfolio'
If you have feedback or need assistance with the MCP directory API, please join our Discord server