weekly-verify
Click on "Deploy 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., "@weekly-verify verify this week's report against the original data"
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.
위클리-검증 (weekly-verify-mcp)
Compares the written weekly work report (.docx) against the source data (.xlsx) to find wrong values, missing items, and descriptions that contradict the data, then returns them to a human. A personal MCP server.
It does not fix. It only points out. Fixing is done by a human.
See docs/검증프로세스.md for the full design.
Current Status — P0~P5 Complete · Registered with Codex
Step | Content | Status |
P0 | Skeleton + contaminated dataset | ✅ |
P1 | Scorer ( | ✅ |
P2 | Source parser + 5-type judgment engine + L3 missing | ✅ |
P3 | Claim extraction + value comparison (L1·L2) + narrative conflict (L4) | ✅ |
P4 | Wrapping 10 MCP tools + smoke | ✅ |
P5 | Codex registration + startup check | ✅ |
Related MCP server: phionyx-pipeline-mcp
The 4 Verification Layers
The entire design of this tool comes from this table.
Layer | What it asks | Judgment | Severity |
L1 Existence | Does this value exist in the source? | Code |
|
L2 Consistency | Does it match that task's that field? | Code |
|
L3 Missing | Is a judgment that should appear from the source missing? | Code |
|
L4 Interpretation | The value is right but the description is off | Human |
|
L1 alone is not enough. If you copy the value of
L-18into theL-19row, both values exist in the source, so L1 passes. Only L2, which also checks the task code, catches it.L3 is the reason this tool exists. What people usually get wrong in weekly reports is not numbers but items they did not write. A wrong number is visible, but a missing row is not.
L4 structurally cannot be an
error.harness.Findingenforces this, andtests/test_harness.pylocks it in. Giving blocking authority to a check you are not sure about would block normal reports, and people would turn the checker off.
The 6 Gates
What evals/weekly-verify.yaml requires of the engine. Scored with uv run python scripts/run_eval.py.
ID | Requirement | Blocking |
G1 Detection rate | Does not miss a single C01~C07 error-grade contamination | ✅ |
G2 False positives | Does not raise an error on a normal report (C10) | ✅ |
G3 Severity | Does not raise an error on C08·C09 | ✅ |
G4 Speed | One report within 60 seconds | ✅ |
G5 Evidence | Every error fills the required coordinates per layer | ✅ |
G6 Layer accuracy | Classifies the findings into the correct layer | ⬜ Observational |
Coordinate requirements differ per layer (G5)
Layer | Report location | Source location | Reason |
L1 | ✅ | — | The value does not exist in the source, so there is no cell to point to |
L2 | ✅ | ✅ | It exists on both sides |
L3 | — | ✅ | The item does not exist in the report, so there is no location to point to |
L4 | ✅ | — |
If you force-fill coordinates that cannot be filled, a person will open the wrong place and believe they have verified it.
N/A is not a pass
Gates of the "don't do bad things" kind (G2·G3·G5) are satisfied automatically if the engine produces nothing. If you mark that as PASS, an engine with no features at all would look like it passed 5 out of 6. So when there is no basis to evaluate, mark it N/A, and N/A does not count as a pass.
Current scoring results (as of P3 — all passed)
C01 수치 조작 [OK] 1/1 C05 지연 누락 [OK] 3/3 C09 반올림 [OK] 0/0
C02 날짜 오기 [OK] 1/1 C06 미제출 은폐 [OK] 3/3 C10 정상 [OK] 오탐 0
C03 값 오배치 [OK] 1/1 C07 역행 무시 [OK] 1/1
C04 없는 과제 [OK] 1/1 C08 서술 상충 [OK] 0/0
[PASS] G1_검출률 11/11 (100%) [PASS] G4_속도 최장 0.1초 / 제한 60초
[PASS] G2_오탐 error 0건 [PASS] G5_근거 좌표 누락 0건 / error 12건
[PASS] G3_심각도 위반 0건 [PASS] G6_계층정확성 11/11 (100%)G5 examined 12 errors, but the expectation is 11. This is because C01's contamination changed one cell in each of two tables, and both must be fixed, so it is not a duplicate.
Folders
weekly-verify-mcp/
├─ docs/검증프로세스.md 설계 문서 (13개 절)
├─ src/weekly_verify/
│ ├─ harness.py 도구 응답 규약 · Finding · 두 좌표계
│ ├─ sources.py 원본 xlsx 파서 + DATA_ROOT 가드
│ ├─ findings.py 판정 5종 (원본만 보고 계산)
│ ├─ report.py 보고서 docx 파서
│ ├─ claims.py 주장 추출 (규칙 기반, LLM 미사용)
│ ├─ values.py L1 존재 · L2 정합 + 억제 규칙 3종
│ ├─ completeness.py L3 누락 검사
│ ├─ narrative.py L4 서술 상충 (warning 고정)
│ ├─ verify.py 진입점 — 네 계층 조립 + 계층 간 중복 제거
│ ├─ record.py 검증 결과 문서 생성·저장 + 승인 토큰
│ └─ server.py MCP 도구 10개 · 리소스 2 · 프롬프트 1
├─ scripts/
│ ├─ make_fixtures.py 오염 시나리오 10종 생성
│ ├─ check_fixtures.py 픽스처 자기검증 (30개 검사)
│ ├─ run_eval.py 채점기 (게이트 6종)
│ ├─ smoke_stdio.py stdio 기동 + 하네스 검사 15종
│ └─ verify_registration.py 설정 파일의 절대경로로 기동 확인
├─ tests/
│ ├─ test_harness.py 하네스 규약 잠금 (16개)
│ ├─ test_eval_contract.py 채점기 검증 — 가짜 엔진 7종 (20개)
│ ├─ test_findings.py 판정 엔진 ↔ 정답지 1건씩 대조 (27개)
│ ├─ test_completeness.py L3 누락 검사 (31개)
│ ├─ test_values.py L1·L2 + 억제 규칙 (53개)
│ ├─ test_narrative.py L4 서술 상충 (43개)
│ └─ test_server_contract.py docstring ↔ 실제 규칙 잠금 (63개)
├─ data/
│ ├─ 원본/ ← 서버가 읽는 유일한 곳
│ │ ├─ 마스터_주간보고_누적.xlsx
│ │ └─ 제출_2026-W35/ (담당자 6명)
│ ├─ 보고서/ C01~C10.docx 검증 대상
│ └─ 출력/ 검증 결과 기록 (저장 산출물)
├─ config/ 등록 설정 + README
├─ templates/ 검증 결과 문서 템플릿
└─ evals/ 🚫 서버 접근 금지 — evals/README.md 참조
├─ 정답지_2026-W35.xlsx
├─ fixtures_manifest.json 픽스처가 담고 있는 사실
└─ weekly-verify.yaml 엔진에게 요구하는 정책The reason manifest and suite are separated is that their concerns differ — the former is a fact created by the generator, so it changes together with the docx, while the latter is a policy set by a human, so it is unrelated to the docx. If merged into one file, expectations would appear in two places and drift.
The 10 Contamination Scenarios
data/보고서/C01~C10.docx. The expected detection for each file is in evals/fixtures_manifest.json.
Code | Type | What is planted | Expected |
C01 | Numeric manipulation | L-01 this week's progress 80 → 90 |
|
C02 | Wrong date | L-08 planned completion date pushed back one day |
|
C03 | Misplaced value | L-18's 60 into the L-19 row (correct answer 40) |
|
C04 | Nonexistent task | L-31 row added |
|
C05 | Missing delay | Delays 6→3, summary count adjusted together |
|
C06 | Concealed non-submission | Deleted non-submission table + filled with last week's values |
|
C07 | Ignored regression | 1 regression not mentioned |
|
C08 | Narrative conflict | 64-day delay described as "proceeding smoothly" |
|
C09 | Rounding | 62.2% → 62% |
|
C10 | Normal | No contamination |
|
C05 · C06 · C07 are the core
These three maintain internal consistency within the contaminated report. While deleting the 3 delayed items, the summary table count was also changed from 6 to 3. So reading only the report shows no contradiction — it only becomes visible when compared against the source. The deleted L-02 · L-08 · L-19 are exactly the 3 items whose owners left the 이슈리스크 (issue/risk) field blank.
C09 · C10 are just as important
They are false-positive prevention tests. No one uses a checker that raises error on a normal report.
Suppression Rules — report one mistake as one finding
Even if contamination changes only one place, derived values cascade into errors. C02 only pushed 계획완료일 (planned completion date) back one day, but 경과일 (elapsed days) also became wrong; C03 only changed 금주진척률 (this week's progress rate), but 증감 (change) also became wrong. If you point those out as-is, one miswritten value becomes two findings, forcing a person to search two places and making it impossible to gauge severity by the number of findings.
# | Rule | Cases not suppressed |
1 | If the task is not in the source, do not compare other values in that row | — (ends with 1 L1 finding) |
2 | Do not compare this week's value for non-submitted tasks | Last week's value is still compared |
3 | Skip derived values whose ingredients were already flagged | If the ingredients are correct, flag the derived value error |
4 | Suppress aggregate count findings for categories covered by L3 | If the items are correct and only the count is wrong, flag it |
Suppression is not unconditional. Each rule is tested as a pair — the suppressed side and the non-suppressed side. Suppression rules quietly collapse the moment you think "it would be nice if this were flagged too."
Columns not verified are declared
5 types are listed in claims.미검증_열 (unverified columns) with reasons (상태 (status) is a judgment label so it belongs to L3; the O (완료 2026-08-20) form in the regression table is free-form so comparison is unstable, etc.). Silently skipping would read as "everything was verified," but there are columns that were actually not examined.
Running
uv sync --extra devuv run python scripts/make_fixtures.pyuv run python scripts/check_fixtures.pyuv run python scripts/run_eval.pyuv run python -m pytest -quv run python scripts/smoke_stdio.pyuv run python scripts/verify_registration.pyThe 10 MCP Tools
# | Tool | Step | Write |
1 |
| DISCOVER | |
2 |
| SOURCE | |
3 |
| BASELINE | |
4 |
| REPORT | |
5 |
| CLAIM | |
6 |
| VERIFY (L1·L2) | |
7 |
| COMPLETE (L3) | |
8 |
| NARRATE (L4) | |
9 |
| PREVIEW | |
10 |
| SAVED | ✅ |
Fast path: tool 9 alone runs all four layers. The intermediate tools are used to show a person "why it was judged that way."
Resources template://verification · report://{보고서}, prompt verify_weekly_report.
Saving is a 'finding record' — error does not block it
The design draft said "refuse to save if there is even one error," but that was a wrong rule. What you save is a record of findings, and the time you most need a record is when there are errors. Blocking then would make the tool useless.
What should be blocked is something else.
# | Rejection condition | Reason |
1 | Approval token does not match the current findings | Prevents content the person has not reviewed from being written to a file |
2 | There is an | It becomes a falsehood, not a record |
The conclusion is one of 통과 · 보류 · 반송 (pass · hold · return). The approval token is computed from the findings, so if even one finding changes, the token mismatches and saving is rejected.
These two conditions are stated in the tool description of save_approved_verification, and tests/test_server_contract.py compares the description against the actual code to lock it in — since the model does not read code, a rule not in the description does not exist for the model.
Registration (P5)
Codex registration complete — [mcp_servers.weekly-verify] is in ~/.codex/config.toml (backup: config.toml.bak-2026-08-26). Restart Codex and the tools will appear.
Claude Desktop has %APPDATA%\Claude as a partially blocked path, so the tool cannot write into it. Merge the contents of config/claude_desktop_config.example.json manually — this is an intentional block and is not bypassed.
command must be an absolute path. Desktop apps do not inherit the login shell's PATH, so if you write only uv, it works in the terminal but the server will not start in the app.
uv run python scripts/verify_registration.pyIt checks 3 things: 2 example configs and the actually registered live config. Even if the examples are correct, if the actual registration is wrong, the tools will not appear in the app.
About the data
All data in data/ is practice-purpose fictional (fabricated) data. The assignee names are characters from classical novels, and the tasks are non-existent logistics automation topics. It contains no real internal data or personal information whatsoever, and do not put real internal files in this folder.
The source data was taken from mx-agentic-ai-day1-prd.
Available Tools
10 toolscheck_completenessARead-onlyIdempotent
원본에서 나와야 할 판정이 보고서에 빠졌는지 봅니다 (L3).
이 검사가 이 도구의 존재 이유입니다. 사람이 주간보고에서 틀리는 것은 대개 숫자가 아니라 안 쓴 항목입니다. 틀린 숫자는 눈에 띄지만 없는 줄은 눈에 띄지 않습니다.
언급 여부를 두 수준에서 봅니다. 상세 표가 있으면 표에 없는 과제코드가 누락이고, 집계만 했으면 건수가 원본과 맞는지 봅니다 — 집계만 하고 개별 항목을 나열하지 않는 것은 정상적인 보고 방식이기 때문입니다.
Returns: 지적응답: L3 지적 목록. 보고서에 없는 항목이므로 보고서 좌표는 비어 있고 원본 좌표만 채워집니다.
Examples: - 사용: "빠뜨린 지연 과제가 있나요?" - 사용하지 않음: 적힌 값이 맞는지 보려면 → verify_claims
Inputs: 보고서 (required), 전주차, 기준주차, 원본디렉터리. Returns: info, error, stage, status, +4 more
compute_baseline_findingsARead-onlyIdempotent
원본 데이터만으로 판정 5종(신규완료·지연·일정변경·역행·미제출)을 계산합니다.
이 도구는 보고서를 입력으로 받지 않습니다. 그것이 핵심입니다. 보고서를 보고 판정을 계산하면 보고서에 이끌려, 보고서에서 빠진 항목을 영영 찾지 못합니다.
판정은 날짜·완료여부 계산으로만 합니다. 담당자가 적은 이슈리스크 텍스트는
판정에 쓰지 않습니다 — 이슈를 적지 않은 지연 과제를 잡아내는 것이 이 도구의
존재 이유입니다.
Returns: 판정응답: 구분별 건수와 판정 목록. 각 판정은 원본 좌표를 갖습니다.
Examples: - 사용: "이번 주에 보고되어야 할 변동이 뭔가요?" - 사용하지 않음: 보고서와 대조하려면 → check_completeness / verify_claims
Inputs: 구분, 전주차, 기준주차, 원본디렉터리. Returns: stage, status, 구분별, 기준일, +3 more
extract_report_claimsARead-onlyIdempotent
보고서에서 원본과 대조 가능한 주장을 뽑습니다.
값은 원문 문자열 그대로 담습니다. 숫자로 바꾸거나 정규화하지 않습니다 —
62 를 62.0 으로 바꿔 놓으면 반올림 오류를 반올림 오류로 지적할 수 없습니다.
표 기반 보고서는 열 이름 → 필드 매핑으로 결정적으로 뽑힙니다. 추측이 개입하지 않으므로 같은 보고서는 항상 같은 주장을 냅니다.
미검증열 에는 의도적으로 검증하지 않는 열과 그 이유가 담깁니다. 조용히
건너뛰면 "전부 검증했다"로 읽히기 때문입니다.
Returns: 주장응답: 총 주장 수, 필드별 개수, 주장 목록(잘릴 수 있음).
Examples: - 사용: "보고서가 L-08 계획완료일을 뭐라고 적었나요?" (필드="계획완료일") - 사용하지 않음: 맞는지 틀리는지 판정하려면 → verify_claims
Inputs: 보고서 (required), 필드. Returns: stage, status, 잘림, 주장, +4 more
flag_narrative_risksARead-onlyIdempotent
값은 맞지만 서술이 데이터와 어긋나는 후보를 표시합니다 (L4).
64일 지연된 과제를 "순조롭게 진행 중"이라고 쓴 보고서는 숫자가 전부 정확합니다. L1·L2·L3 어디에도 걸리지 않는데, 읽는 사람은 완전히 잘못된 인상을 받습니다.
이 검사는 판단하지 않고 표시만 합니다. 그 서술이 부적절한지는 문맥에 달렸고
기계는 그 차이를 모릅니다. 그래서 결과는 항상 warning 이며 저장을 막지
않습니다. 확신하지 못하는 검사에 차단 권한을 주면 정상 보고서가 막히고, 사람이
검사기를 꺼 버립니다.
표는 보지 않습니다. 표의 칸은 값이고 값의 정합은 L2 소관입니다.
Returns:
지적응답: L4 후보 목록. error 는 구조적으로 나올 수 없습니다.
Examples: - 사용: "지연된 과제를 괜찮다고 써 놓은 데가 있나요?" - 사용하지 않음: 숫자 대조 → verify_claims
Inputs: 보고서 (required), 전주차, 기준주차, 원본디렉터리. Returns: info, error, stage, status, +4 more
list_verification_targetsARead-onlyIdempotent
검증할 수 있는 보고서와 대조 기준이 되는 원본 파일 목록을 조회합니다.
검증 작업의 출발점입니다. 여기서 얻은 파일명을 다른 도구에 넘깁니다.
Returns:
대상목록응답: 원본 엑셀 목록과 .docx 보고서 목록.
Examples: - 사용: "검증할 수 있는 보고서가 뭐가 있나요?" - 사용하지 않음: 이미 파일명을 알고 바로 검증할 때 → preview_verification_report
Inputs: 원본디렉터리, 보고서디렉터리. Returns: stage, status, 보고서, next_actions, +2 more
preview_verification_reportARead-onlyIdempotent
네 계층을 모두 돌려 지적 목록과 저장 대상, 승인 요청 문장을 돌려줍니다.
이 도구 하나로 L1·L2·L3·L4 전부를 검사합니다. 중간 도구들은 "왜 그렇게 판정했는지"를 사람에게 보여줄 때 씁니다.
승인토큰 은 지적 내용에서 계산됩니다. 지적이 하나라도 달라지면 토큰이 달라지므로,
사용자가 확인한 내용과 저장될 내용이 같다는 것을 보장할 수 있습니다.
approval_request 문장을 사용자에게 그대로 보여 주고, 명시적으로 승인받은
뒤에만 save_approved_verification 을 호출하십시오.
Returns: 미리보기응답: 지적 목록, 저장 경로, 승인토큰, 지금 쓸 수 있는 결론 후보.
Examples: - 사용: "이 보고서 검증해 주세요" - 사용하지 않음: 사용자 승인 없이 저장 → 절대 금지
Inputs: 보고서 (required), 전주차, 기준주차, 원본디렉터리. Returns: info, error, stage, status, +9 more
read_reportARead-onlyIdempotent
검증 대상 보고서(.docx)의 구조를 표와 문단으로 읽습니다.
각 표에 직전 제목을 붙여 돌려줍니다. "이 표가 무엇에 대한 표인가"를 알아야 지연 표에서 빠진 과제를 찾을 수 있기 때문입니다.
Returns: 보고서응답: 표별 제목·헤더·행수와 보고서에 등장한 과제코드 목록.
Examples: - 사용: "이 보고서에 어떤 표가 들어 있나요?" - 사용하지 않음: 값을 대조하려면 → extract_report_claims → verify_claims
Inputs: 보고서 (required). Returns: 표, stage, status, 파일, +4 more
read_source_dataARead-onlyIdempotent
원본 엑셀을 읽어 정규화 사실표로 만들고 그 규모를 돌려줍니다.
제출본에는 주차 열이 없으므로 기준주차를 스탬프로 찍어 적재합니다. 모든 행은 자기 좌표(파일·시트·행)를 들고 다니며, 그것이 나중에 지적의 근거가 됩니다.
Returns: 원본데이터응답: 행 수, 주차별 과제 수, 미제출 과제코드 목록.
Examples: - 사용: "원본에 몇 개 과제가 들어와 있나요?" / "누가 안 냈나요?" - 사용하지 않음: 판정 5종이 필요할 때 → compute_baseline_findings
Inputs: 전주차, 기준주차, 원본디렉터리. Returns: stage, status, 전주차, next_actions, +6 more
save_approved_verificationAIdempotent
사용자가 승인한 검증 결과를 파일로 저장합니다. 유일한 쓰기 도구입니다.
사용자가 명시적으로 승인한 뒤에만 호출하십시오. 승인 없이 호출하지 마십시오.
저장하는 것은 지적 기록입니다. 보고서를 고치지 않습니다. 그래서 error 가
있다는 이유만으로 저장을 막지는 않습니다 — 오히려 error 가 있을 때 기록이 가장
필요합니다.
두 경우에만 거부합니다.
승인토큰이 현재 지적 내용과 맞지 않을 때. 사람이 확인하지 않은 내용이 파일로 남는 것을 막습니다. preview_verification_report 를 다시 호출하십시오.
error가 있는데 결론을 '통과' 로 적으려 할 때. 그것은 기록이 아니라 거짓입니다. '보류' 또는 '반송' 을 쓰십시오.
Returns: 저장응답: 저장 경로와 기록된 결론.
Examples: - 사용: 사용자가 "보류로 저장해 주세요"라고 승인한 뒤 - 사용하지 않음: 미리보기를 보여 주기 전 / 승인 문구가 없을 때
Inputs: 결론 (required), 보고서 (required), 승인토큰 (required), 전주차, +2 more. Returns: info, error, stage, status, +4 more
verify_claimsARead-onlyIdempotent
보고서의 값을 원본과 대조합니다. L1(원본에 없음) · L2(원본과 다름).
L1 만으로는 부족합니다. L-18 의 값을 L-19 행에 옮겨 적으면 두 값 다 원본에
존재하므로 L1 은 통과합니다. 과제코드까지 맞춰 보는 L2 만이 잡습니다.
한 번의 실수가 여러 값을 틀리게 만들므로 억제 규칙이 있습니다 — 원본에 없는
과제는 그 행의 다른 값을 대조하지 않고, 미제출 과제의 금주 값은 대조하지 않으며,
파생 값(증감·경과일)은 재료가 이미 지적되면 건너뜁니다. 한 번 잘못 적은 것을
두 건으로 보고하지 않기 위한 것입니다.
반올림(0.5 이내) 차이는 error 가 아니라 warning 입니다.
Returns: 지적응답: L1·L2 지적 목록. 각 지적은 보고서 좌표와 원본 좌표를 갖습니다.
Examples: - 사용: "보고서 숫자가 원본과 맞나요?" - 사용하지 않음: 빠진 항목을 찾으려면 → check_completeness
Inputs: 보고서 (required), 전주차, 기준주차, 원본디렉터리. Returns: info, error, stage, status, +4 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
Each tool owns a distinct stage or verification level (L1/L2 vs L3 vs L4), and the descriptions explicitly cross-reference when another tool should be used instead. The aggregate preview tool is clearly positioned as a convenience wrapper over the intermediate tools, so there is no real ambiguity.
All tool names follow a consistent snake_case verb_noun pattern with specific, informative verbs: list, read, compute, extract, verify, check, flag, preview, save. The naming style is uniform and each name accurately predicts the tool's operation.
Ten tools map cleanly onto the stages of the verification pipeline: discover targets, load source, compute expected findings, parse report, extract claims, verify values, check completeness, flag narrative risks, preview, and save. The count is well-scoped and every tool has a clear purpose.
The set covers the full verification lifecycle from target discovery through source normalization, report parsing, claim extraction, multi-level checks, all-level preview, and an approval-gated save. There are no obvious dead ends: the only write tool is intentionally gated, and every intermediate tool feeds into the preview/save flow.
Maintenance
Related MCP Connectors
Checks finished AI work after it is done: figures, citations and quotations, with a signed record.
Verifies AI agent work end to end: real artifacts and outcomes checked, not self-reported success.
Agent completion verification with defects, corrections, and evidence receipts.
PDF, photo, email, and file comparison evidence checks with plain-language reports.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceThis MCP server verifies that an agent’s claimed tool output matches the actual response returned by a tool to prevent invented or distorted results. It flags mismatches, omissions, and invented fields to ensure downstream logic only processes verified tool data.-
- AlicenseAqualityBmaintenanceEnables verification of AI coding agent self-reports against git diff truth and a deterministic gate, producing pass/regenerate/reject directives to ensure claimed work matches actual changes.6AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceDeterministic verification for AI-generated analysis. Reconciliation, consistency and Excel-integrity checks that stop the line when the numbers don't add up.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables deliverable conformance and evidence-chain checks by turning requirements into executable specs, validating numbers against a provenance ledger, and auditing PDF/OOXML metadata and archive manifests.38 npm1MIT