file-analysis
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., "@file-analysisScan the reports folder and summarize the key findings from the PDFs."
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.
A personal local MCP that reads unstructured documents (pdf docx pptx svg png) in a specified folder and helps summarize key content and analyze file structure. It plugs into Claude Code · Codex · Claude Desktop.
Document | What it contains |
README.md (this document) | How to use it |
What is being built — data contracts · tool contracts · guardrails · permanent refusal list | |
Coding agent workflow — workflow · review checklist · common mistakes |
If the same fact appears in two places, AGENTS.md is the source of truth.
This server does not summarize
This is the most important design decision.
Layer | What it does |
MCP server | Extraction · structure analysis · grounding anchor attachment · summary verification |
Host model (Claude Code / Codex) | Writes the summary — citing anchors while doing so |
Human | Approval |
If the server also summarized, it would have to call a model again with its own API key, and the host would receive only the summary result, making it impossible to verify the grounding. That opens a path for incorrect summaries to pass silently. So the server only outputs the source text and anchors.
Related MCP server: file-analyzer-mcp
Quick start
Prerequisites: Python 3.11+, uv
uv sync --extra devuv run python scripts/make_samples.pyuv run python scripts/smoke_stdio.pyIf smoke_stdio.py prints PASS, the server is working — it launches the server over the real MCP protocol, checks all 17 harness contracts, and runs a full cycle from DISCOVER to SAVED.
To visually inspect the tools with MCP Inspector:
uv run mcp dev src/file_mcp/server.pySpecifying the folder to analyze
Edit allowed_roots in config/roots.toml. This file is the server's security boundary.
allowed_roots = [
"data/samples",
"C:/Users/<사용자>/Desktop/분석대상",
]Do not add an entire parent folder like C:/Users/<user> — that is effectively no guard at all. The server will never open a path outside this list under any circumstances.
Host connection
Claude Code
claude mcp add file-analysis -- uv --directory "<이-저장소를-클론한-절대경로>" run python src/file_mcp/server.pyCodex — paste the contents of config/codex-config.example.toml into ~/.codex/config.toml.
Claude Desktop — see config/claude_desktop_config.example.json.
Pipeline
flowchart LR
S["scan_folder<br/><i>추정 등급 B?</i>"] --> I["inspect_document<br/><i>확정 등급 A/B/C</i>"]
I --> P["build_analysis_prompt<br/><i>앵커 붙은 원문</i>"]
P --> D(["초안 작성<br/><i>호스트 모델</i>"])
D --> G["check_summary_grounding<br/><i>GR-01 … GR-04</i>"]
G --> V["preview_save_report<br/><i>승인 토큰 발급</i>"]
V --> H{{"사람의 승인"}}
H --> W["save_approved_report<br/><i>유일한 쓰기</i>"]
classDef server fill:#ddf4ff,stroke:#54aeff,color:#1f2328
classDef notserver fill:#ffffff,stroke:#afb8c1,stroke-dasharray:5 4,color:#656d76
classDef write fill:#fff8c5,stroke:#d4a72c,color:#1f2328
class S,I,P,G,V server
class D,H notserver
class W writeThe dashed line marks what the server does not do. The draft is written by the host model, and approval is done by a human.
Step | Tool | Read/Write |
DISCOVER |
| Read |
DISCOVER |
| Read |
INSPECT |
| Read |
READ |
| Read |
READ |
| Read |
DRAFT |
| Read |
CHECK |
| Read |
PREVIEW |
| Read |
APPROVE | (human) | — |
SAVED |
| Write |
save_approved_report is the only write tool. It never writes without an approval token.
scripts/smoke_stdio.py checks the write tool list, so if you add more tools, you must update the smoke test as well.
Grades are determined by content, not file extension
flowchart TD
X["파일"] --> Y{"확장자"}
Y -->|"docx · pptx"| A["<b>등급 A</b><br/>구조까지"]
Y -->|"png"| C1["<b>등급 C</b><br/>이미지 판독"]
Y -->|"pdf"| PQ{"공백 제거 후 페이지 텍스트<br/>8자 이상?"}
Y -->|"svg"| SQ{"내용 있는<br/>text 노드?"}
PQ -->|"있음"| B1["<b>등급 B</b><br/>본문만"]
PQ -->|"없음"| C2["<b>등급 C</b><br/>스캔 PDF"]
SQ -->|"있음"| B2["<b>등급 B</b><br/>본문만"]
SQ -->|"없음"| C3["<b>등급 C</b><br/>그림"]
classDef ga fill:#dafbe1,stroke:#2da44e,color:#1f2328
classDef gb fill:#ddf4ff,stroke:#54aeff,color:#1f2328
classDef gc fill:#fff8c5,stroke:#d4a72c,color:#1f2328
class A ga
class B1,B2 gb
class C1,C2,C3 gcGrade | Meaning | How to read |
A | Extracts structure too (heading levels · tables · slide units) |
|
B | Extracts body text only |
|
C | No text |
|
| Undetermined. You have to open it to know | Exists only in |
scan_folder does not open files, so it cannot confirm the grade. pdf·svg remain B?, and inspect_document opens them to confirm. Do not read B? in scan results as a confirmed value.
The samples are arranged to prove this — 흐름도.svg has text nodes so it is B, while 도형만.svg has only shapes so it is C. Same extension, different grades.
Read it with the host model's vision. No additional dependencies, and Korean accuracy is better than tesseract. If offline batch processing becomes necessary, an extract_text_ocr tool will be added separately.
Scanned PDFs are also read without a rasterizer. A scanned page is entirely one embedded image, so you can extract that image with pypdf — no PyMuPDF (AGPL) or poppler binaries needed.
Pages drawn purely as vectors cannot be extracted, and in that case the PDF_PAGE_HAS_NO_IMAGE error tells the human to "capture the screen." It does not silently return an empty result.
It only gives the table of contents · block count · character count · confirmed grade, and estimated_read_calls (the number of calls needed to read the whole document). Its reason for existing is to prevent dumping the body of a 300-page PDF into the context just to see what it looks like.
The cost of opening a file is the same as read_document — what is saved is not time but context.
Citation anchor contract
Format | Anchor | Meaning |
|
| 14th block (paragraph or table row) |
|
| 7th slide, 2nd line / speaker notes |
|
| page 3 |
|
| 2nd |
| (none) | no text, so no anchor |
Each format has a different unit, but read_document's interface is one. All formats are flattened into a 1-dimensional list of blocks, so you only need start/end. The response's unit tells you what a single block is.
If you change the anchor format, you must update grounding.ANCHOR_PATTERN and the golden set together. If they fall out of sync, valid citations will all be blocked by GR-02.
What grounding verification can and cannot check
Whether the sentence cites an anchor —
GR-01Whether that anchor exists in the document —
GR-02Whether figures and dates exist in the cited block's source text —
GR-03Whether direct quotes (inside quotation marks) match the source —
GR-04
Whether the summary faithfully conveys the source's meaning
Whether something important was omitted
Whether the cited anchor is an appropriate anchor (
GR-05is only a lexical overlap hint)
Passing does not mean 'correct.' The response's not_verifiable states this limitation every time — if you pretend to verify what cannot be verified, people will believe "it passed, so it must be right," and that is more dangerous than no verification at all.
Paraphrasing the source is normal. Verification only looks at anchors, figures, and direct quotes.
Save gate
preview_save_report checks both structure (ST-*) and grounding (GR-*), and issues an approval token only when there are zero errors. The token is sha256(original relative path + draft), so changing even one character of the draft invalidates it — this blocks the path of previewing with a clean draft and saving a different one.
save_approved_report re-checks every gate. It does not trust the model's claim that the preview passed.
Order | Check | On failure |
0 | Is |
|
1 | Structure ( |
|
2 | Grounding ( |
|
3 | Approval token |
|
If an existing artifact exists, it is overwritten, and the hash of the previous content is recorded in the audit log. The audit log (data/outputs/_audit.jsonl) is append-only.
Harness layers (CAR)
Divided into three axes: Control–Agency–Runtime. First decide which axis the file you are changing belongs to. If the axis is unclear, that is a sign the design is wrong.
Axis | Question | Files |
Control | What is it preventing? |
|
Agency | What does the model choose and how? |
|
Runtime | What happened is recorded? |
|
Per-axis detailed contracts and dependency directions are in AGENTS.md chapter 2.
The server does not track progress (how much has been read). The model owns it, and the server only tells next_actions to "continue with start=N." That is why the server is stateless, and the write tool stays as a single save.
Self-verification
Invariants are checked right before returning a response; if they break, the server returns an error instead of a wrong answer.
Check | What it prevents |
Anchor uniqueness and non-emptiness | Grounding verification pointing at the wrong block |
Body line ↔ block consistency | Truncation cutting mid-block, causing grounding verification to fail |
Aggregate sum = row count | The code not counting or double-counting numbers |
Grade ↔ block contradiction | Reporting grade B but no blocks to read |
What gets caught here is not a user input problem but a server bug. That is why the error message says "this is a server defect — stop the task and report it," not "please check the file."
Observability
Each tool call is recorded as one line in data/traces/YYYY-MM-DD.jsonl.
uv run python scripts/trace_report.pyWhat is not recorded is more important. When analyzing real internal documents, traces could become copies of those documents.
Rule | Enforcement |
No body, excerpt, or TOC text |
|
No draft body | Not registered in |
No absolute paths | Folded as |
No error | Only |
This is enforced by code, not by convention, and verified by tests (tests/test_trace.py).
If trace_dir is inside allowed_roots, tracing turns itself off — to avoid polluting the analyzed folder with its own records.
All 8 read tools have readOnlyHint: True, yet traces write files.
That hint means the analyzed documents are not modified. Traces are instrumentation logs outside allowed_roots and are not exposed through any tool. The only thing exposed through a write tool is save_approved_report, and the smoke test checks that list.
Evaluation
uv run python scripts/eval_extract.pyCompares the expected values in evals/golden/samples.json against actual extraction results and records the results in evals/reports/. pytest only tells you "does it pass right now," while this report records when and what passed.
The expected values are hand-written by looking at what scripts/make_samples.py put into the files. They are not copies of the extractor's output. If you adjust the golden set to match the results, the evaluation passes itself. The only legitimate reasons to change them are when the anchor contract, grade definitions, or sample contents change.
Dependencies
Package | License | Purpose |
MIT | FastMCP server | |
BSD | pdf text and embedded images | |
MIT | docx | |
MIT | pptx | |
MIT-CMU | png metadata and image downscaling |
svg is read with the standard xml.etree — zero dependencies.
Why not use
PyMuPDF(fitz): performance is better, but it is AGPL-3.0, which imposes distribution conditions if included in an internal tool. If table extraction actually becomes necessary, addpdfplumber(MIT).
What is not committed
Path | Reason |
| Generated by |
| Analysis results and audit log. Contains summaries of real documents |
| Execution logs. No body text, but filenames and paths remain |
| Local run results. The golden set is committed |
| Personal paths |
Do not place real documents to be analyzed inside this repository.
Available Tools
9 toolsbuild_analysis_promptARead-onlyIdempotent
초안을 쓰기 위한 재료를 한 번에 받습니다 — 템플릿 + 앵커 붙은 원문 + 목차.
read_document를 따로 부를 필요가 없습니다. 초안은 당신이 씁니다 —
이 도구는 형식과 원문을 주기만 합니다.
source_with_anchors에 있는 앵커만 인용하세요. 여기 없는 앵커를 쓰면
preview_save_report가 GR-02로 막습니다.
required_sections의 절을 빠뜨리면 저장이 막힙니다.
ungrounded_sections의 절에는 앵커를 붙이지 않아도 됩니다.
Args: path: 분석할 파일. start: 시작 블록 번호. end: 끝 블록 번호(포함).
Returns: BuildPromptResponse: 템플릿·목차·앵커 붙은 원문·확정 등급·절 목록.
Examples: - 사용: "이 문서 분석해 줘" 를 받은 직후 - 사용하지 않음: 본문 일부만 다시 보고 싶을 때 → read_document - 사용하지 않음: 등급 C 문서 → read_document_image로 판독한 뒤 초안을 씁니다
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | 끝 블록 번호(포함). None이면 글자 수 상한까지 | |
| path | Yes | 분석할 파일 | |
| start | No | 시작 블록 번호(1부터) |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | |
| path | Yes | |
| unit | Yes | |
| grade | Yes | |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| start | Yes | |
| status | Yes | 이 호출의 결과 상태 |
| outline | Yes | 제목 트리 (앵커 포함). 없으면 '목차 없음' |
| template | Yes | 채워야 하는 고정 형식 |
| file_name | Yes | 초안 제목 줄에 넣어야 하는 원본 파일명 |
| truncated | Yes | True면 원문이 다 실리지 않았습니다 |
| unit_count | Yes | |
| grade_reason | Yes | |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| total_blocks | Yes | |
| required_sections | Yes | 빠뜨리면 저장이 막히는 절 |
| source_with_anchors | Yes | 앵커가 붙은 원문. 여기서만 인용하세요 |
| ungrounded_sections | Yes | 앵커를 요구하지 않는 절 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with annotations carrying readOnlyHint/idempotentHint/destructiveHint, the description adds substantial behavioral context: only anchors in source_with_anchors are citable, missing required_sections blocks saving, ungrounded_sections need no anchors, and the tool forces the agent to write the draft itself. It also discloses the GR-02 error consequence with preview_save_report — meaningful behavioral detail that annotations cannot convey. No contradiction with the stated read-only, idempotent profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat long but front-loaded with the core purpose before constraints, and organized into clear sections (purpose, constraints, args, returns, examples). Every sentence earns its place given the tool's complex blocking rules and sibling differentiation needs; the use/not-use examples are especially economical. Slightly heavier than ideal but well-structured for the complexity it must carry.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema (BuildPromptResponse) covering the return values, the description properly focuses on usage, differentiation, and constraints. It covers when to invoke, what blocks downstream saving, how anchoring works, and the grade-C fallback path. Nothing an agent needs to call this tool correctly and avoid downstream failures is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description's Args section largely duplicates schema text (path = file to analyze, start/end = block numbers, end inclusive, None = text length limit). It adds essentially no new meaning beyond the schema — the Args block is a near-verbatim restatement, so it earns the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens by stating the tool collects all draft materials at once — template, anchored source text, and table of contents — establishing a clear verb-resource relationship. It further distinguishes itself from siblings by explicitly declaring 'no need to call read_document separately' and clarifying the tool only supplies format and source while the agent writes the draft. This unambiguous differentiation makes sibling confusion unlikely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance: use it right after receiving an 'analyze this document' request; use read_document when viewing partial text; use read_document_image for grade C documents before drafting. It also specifies downstream blocking consequences (GR-02 for unlisted anchors, save blocked for missing required_sections), giving the agent concrete decision criteria for selecting this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_summary_groundingARead-onlyIdempotent
초안의 각 문장이 원문 앵커에 근거하는지 대조합니다.
확인하는 것: 앵커를 인용했는가(GR-01) · 그 앵커가 있는가(GR-02) · 수치·날짜가 원문에 있는가(GR-03) · 직접 인용이 원문과 같은가(GR-04).
확인하지 못하는 것: 요약이 뜻을 제대로 옮겼는가 · 중요한 것을 빠뜨렸는가 ·
인용한 앵커가 적절한가. GR-05는 어휘 겹침 힌트일 뿐이고 판단은 사람이 합니다.
응답의 not_verifiable이 이 한계를 명시합니다 — 통과했다는 것이 맞다는
뜻은 아닙니다.
원문을 다듬어 쓰는 것은 정상입니다. 대조는 앵커·수치·직접 인용만 봅니다.
Args: path: 원본 파일. draft: 초안 전문.
Returns: GroundingResponse: 규칙 위반 목록, 검사·면제 통계, 인용 범위(coverage).
Examples: - 사용: 초안을 쓴 직후, 저장 전 - 사용하지 않음: 저장 계획과 승인 토큰이 필요할 때 → preview_save_report
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | 초안이 근거로 삼은 원본 파일 | |
| draft | Yes | 검증할 초안 (마크다운 전문) |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| grade | Yes | |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| counts | Yes | severity별 건수. 코드가 센 값입니다 |
| status | Yes | 이 호출의 결과 상태 |
| coverage | Yes | 어느 블록이 인용되지 않았는지. **누락은 오류가 아닙니다** |
| findings | Yes | |
| verifiable | Yes | 이 검사가 기계적으로 확인한 것 |
| anchors_used | Yes | |
| exempt_lines | Yes | 앵커를 요구하지 않아 건너뛴 줄 수 |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| not_verifiable | Yes | 이 검사가 확인할 수 없는 것. 사람이 판단해야 합니다 |
| unknown_anchors | Yes | 초안이 인용했지만 문서에 없는 앵커 |
| checked_sentences | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds valuable limitations: what cannot be verified (meaning, omissions, anchor appropriateness), that GR-05 is only a hint, and that passing the check does not imply correctness. This goes well beyond the structured fields and sets correct expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear headers and bullets, front-loading the core purpose and limitations. It includes useful examples and explicit caveats. It repeats the parameter definitions already present in the schema, which is minor redundancy, but overall it remains efficient and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only validation tool, this description is complete: it states what is verified, what is not verifiable, the meaning of not_verifiable, the normal handling of reworded text, and provides both usage and non-usage examples. The output schema (GroundingResponse) already defines the return structure, so no further details are needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters already include meaningful descriptions in the schema (path as 'original file', draft as 'full draft to verify'). The Args section in the description only repeats this information, adding no new semantic meaning. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource – 'checks whether each sentence of the draft is grounded on original anchors' – and enumerates the four concrete rules (GR-01 to GR-04). This clearly differentiates it from siblings like preview_save_report, which handle saving and approval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides both positive and negative usage conditions: 'use right after writing the draft, before saving' and 'do not use when a save plan and approval token are needed', naming the alternative tool preview_save_report. This leaves no ambiguity about when to invoke the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_documentARead-onlyIdempotent
본문 없이 구조와 확정 등급만 돌려줍니다.
read_document 전에 부르세요. 300페이지 PDF에서 "이게 어떻게 생긴 문서인지"를
알려고 본문 전체를 컨텍스트에 붓는 일을 막는 도구입니다.
scan_folder의 expected_grade는 확장자 추정값이라 pdf·svg가 B?로
남습니다. 이 도구가 파일을 열어서 확정합니다. 스캔 PDF와 텍스트 PDF가
여기서 갈립니다.
파일을 여는 비용은 read_document와 같습니다. 절약되는 것은 시간이 아니라
컨텍스트입니다.
Args: path: 분석할 파일.
Returns: InspectResponse: 확정 등급과 근거, 제목 트리, 블록 수, 본문 글자 수, 전체를 읽는 데 필요한 호출 횟수 추정, 이미지 판독이 필요한 블록 앵커, 형식별 메타.
Examples: - 사용: 큰 PDF를 읽기 전에 페이지 수와 목차를 확인할 때 - 사용: scan_folder가 'B?'를 돌려줬고 스캔 여부를 알아야 할 때 - 사용하지 않음: 본문 내용이 필요할 때 → read_document
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | scan_folder가 돌려준 상대 경로, 또는 root 안의 절대 경로 |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | 형식별 메타 (표 개수, 슬라이드 수 등) |
| path | Yes | |
| unit | Yes | 이 형식에서 블록 하나가 무엇인지 |
| grade | Yes | **확정된** 추출가능등급. A=구조까지, B=본문만, C=텍스트 없음. scan_folder의 expected_grade와 달리 파일을 열어서 판정한 값입니다 |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| status | Yes | 이 호출의 결과 상태 |
| outline | Yes | 제목 트리. 없는 형식은 빈 목록 |
| modified | Yes | 마지막 수정 시각 (ISO 8601) |
| extension | Yes | |
| size_bytes | Yes | |
| text_chars | Yes | 본문 총 글자 수 (앵커 제외) |
| unit_count | Yes | 원래 단위의 개수 (총 페이지·슬라이드 수 등) |
| grade_reason | Yes | 그 등급으로 판정한 근거 |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| total_blocks | Yes | read_document로 읽을 수 있는 블록 수 |
| outline_truncated | Yes | True면 제목이 너무 많아 잘렸습니다 |
| blocks_needing_image | Yes | 텍스트가 없어 read_document_image로 판독해야 하는 블록의 앵커. 예: ['p3', 'p7']. 최대 50개까지 |
| estimated_read_calls | Yes | 전체를 읽는 데 필요한 read_document 호출 횟수 (상한 기준 추정) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint=true, idempotentHint=true, destructiveHint=false, covering the safety profile. The description adds valuable context beyond these: it discloses that opening the file costs the same as read_document but saves context, not time, and that it distinguishes scanned vs text PDFs. It doesn't describe pagination or response size details, but the output schema exists and the safety profile is already covered by annotations, so the added disclosure is meaningful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with front-loaded purpose ('본문 없이 구조와 확정 등급만 돌려줍니다'), followed by usage guidance, cost disclosure, args, return types, and examples. Every sentence earns its place – the cost disclosure and the scan-vs-text distinction are critical differentiators that an agent needs. The examples section with explicit 사용/사용하지 않음 cases is particularly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a single-parameter read-only inspection tool. The output schema lists the return fields (grade, rationale, title tree, block count, char count, estimated call count, image-required anchors, format metadata), so the description needn't explain return values further. The cost/context tradeoff, the B? resolution flow, and the scan-vs-text distinction are all covered. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents the single path parameter, including that it must be a relative path from scan_folder or an absolute path within root. The description's Args section adds nothing beyond the schema. Baseline 3 is appropriate since the schema carries the load and the description repeats it without adding new semantic detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: inspects a document to return only its structure and confirmed grade, without the body text. It clearly differentiates from read_document by emphasizing it is to be called before it, and from scan_folder by explaining that it replaces extension-based 'B?' guesses with a confirmed grade. The purpose cannot be confused with siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use instructions ('read_document 전에 부르세요'), specific use cases with examples (checking page count/TOC before reading a large PDF, resolving a 'B?' from scan_folder), and a clear when-not-to-use case (when body text is needed, use read_document). Alternatives are named directly, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_allowed_rootsARead-onlyIdempotent
이 서버가 열 수 있는 폴더와 제한값을 조회합니다.
모든 작업의 출발점입니다. 경로를 추측해서 다른 도구를 부르지 말고, 여기서 얻은 root 아래의 경로만 넘기세요. root 밖은 전부 거부됩니다.
Returns:
AllowedRootsResponse: roots[](경로·존재여부), 여는 확장자 목록,
파일 크기 상한, 스캔 개수 상한, 그리고 이 제한들이 적힌 설정 파일 경로.
Examples: - 사용: "어떤 폴더를 분석할 수 있나요?" / 다른 도구가 PATH_OUTSIDE_ROOT로 거부했을 때 - 사용하지 않음: 이미 root를 알고 파일 목록이 필요할 때 → scan_folder
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| roots | Yes | scan_folder에 넘길 수 있는 root 목록 |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| status | Yes | 이 호출의 결과 상태 |
| workflow | Yes | 이 서버의 단계 순서. tools/list는 도구 목록만 주고 순서를 주지 않으므로 여기서 알려 줍니다 |
| config_path | Yes | 이 제한들이 적힌 설정 파일. 넓히려면 사람이 직접 고쳐야 합니다. |
| max_file_mb | Yes | 한 파일 크기 상한(MB) |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| observability | Yes | 트레이스 상태 (run_id, 켜짐 여부, 기록 줄 수, 쓰기 실패 수). 본문은 트레이스에 남지 않습니다 |
| max_scan_entries | Yes | scan_folder가 한 번에 돌려줄 최대 파일 수 |
| allowed_extensions | Yes | 이 서버가 여는 확장자 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey readOnly, idempotent, and non-destructive behavior. The description adds valuable behavioral context by stating that paths outside the returned roots are rejected, and clarifies that the response includes limits (file size, scan count) and config file path. This goes beyond the annotations to inform the agent of critical scope constraints, though it does not cover all potential behaviors (e.g., rate limits), so a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct and well-structured. It opens with the core purpose, immediately follows with a critical usage warning, then lists the return fields, and concludes with concrete usage examples. Every sentence serves a distinct purpose—providing purpose, constraints, return info, or usage guidance—with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema exists, the description is complete. It covers the tool's role, usage constraints, and return contents, while the examples clarify edge cases. The agent has all necessary information to decide when and how to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema is empty with 100% coverage (trivially). The description compensates by explaining the output structure (roots, extensions, limits, config path), which is useful for understanding the tool's effect. Since there are no parameters to document, the description adds meaning beyond the schema by clarifying the return payload, meriting a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 조회 (retrieve/list) the folders the server can open and the associated limits. It identifies the specific verb and resource, and explicitly differentiates itself from scan_folder by specifying when to use each. The examples further clarify its distinct role as the starting point for all operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: it declares itself as '모든 작업의 출발점' (starting point for all operations), instructs users not to guess paths and to only use paths under roots, and gives concrete scenarios for when to use (e.g., when another tool rejects with PATH_OUTSIDE_ROOT) and when not to (when you already have roots and need a file list, use scan_folder). This fully addresses when and when-not, with a named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_save_reportARead-onlyIdempotent
저장 게이트를 통과하는지 확인하고 승인 토큰을 발급합니다. 쓰지 않습니다.
구조(ST-)와 근거(GR-)를 모두 보고, 오류가 하나도 없을 때만
approval_token이 발급됩니다.
토큰은 이 초안 내용에 묶여 있습니다. 초안을 한 글자라도 고치면 토큰이 달라지므로 다시 미리보기해야 합니다. 깨끗한 초안으로 미리보기하고 다른 초안을 저장하는 경로를 막기 위한 것입니다.
will_overwrite가 True면 기존 산출물을 덮어씁니다. previous_hash와
line_delta로 무엇이 바뀌는지 확인하고 사람에게 알린 뒤 진행하세요.
Args: path: 원본 파일. draft: 초안 전문.
Returns: PreviewResponse: 게이트 결과, 저장 위치, 덮어쓰기 여부, 승인 토큰.
Examples: - 사용: 근거 대조를 통과한 뒤, 저장 직전 - 사용하지 않음: 근거만 보고 싶을 때 → check_summary_grounding
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | 원본 파일 | |
| draft | Yes | 저장할 초안 (마크다운 전문) |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| grade | Yes | |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| counts | Yes | |
| status | Yes | 이 호출의 결과 상태 |
| findings | Yes | |
| draft_hash | Yes | |
| line_delta | Yes | 기존 대비 줄 수 변화 |
| draft_lines | Yes | |
| output_name | Yes | |
| output_root | Yes | |
| exempt_lines | Yes | |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| approval_note | No | |
| previous_hash | Yes | |
| approval_token | No | 게이트를 통과했을 때만 발급됩니다. **이 초안 내용에 묶여 있어서** 초안을 고치면 무효가 됩니다 |
| blocked_reason | No | |
| previous_lines | Yes | |
| will_overwrite | Yes | True면 기존 산출물을 덮어씁니다 |
| checked_sentences | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, and non-destructive hints. The description adds significant behavioral context: the token is bound to the exact draft content, any edit invalidates it, and the tool prevents saving a different draft after preview. It also discloses overwrite behavior and the need to alert a human, going well beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear lead stating the core purpose and the 'does not write' caveat, followed by crucial token-binding and overwrite warnings, then an Args/Returns/Examples block. Every sentence adds value; it's thorough without being bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a gate-check tool with an output schema, the description covers all necessary context: the gate logic (structure and grounds checks), token binding, overwrite implications, and usage timing. It distinguishes from the sibling that covers grounds only, and the return type is mentioned. Nothing critical is missing for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes both parameters (path and draft) fully, so the baseline is 3. The description adds meaningful context about the draft parameter—namely that the token is sensitive to any change in its content, which affects how the agent should treat it. It also clarifies path as the original file, matching the schema but reinforcing usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: it verifies that a draft passes the save gate and issues an approval token, explicitly noting it does not write. It distinguishes itself from siblings by naming check_summary_grounding as the alternative for when only grounds are needed, and the context implies it precedes save_approved_report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: use it after passing grounds comparison and right before saving; do not use it when only grounds are needed, pointing to check_summary_grounding. It also warns about overwriting and instructs to inform a human first, covering both when-to-use and when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_documentARead-onlyIdempotent
문서 본문을 인용 앵커를 붙여 범위 지정으로 읽습니다.
형식이 달라도 인터페이스는 하나입니다. 모든 형식을 블록의 1차원 목록으로
평탄화하므로 start/end만 쓰면 됩니다. 블록 하나가 무엇인지는 응답의
unit이 알려 줍니다 (pdf=페이지, pptx=슬라이드 줄, docx=문단·표행).
등급이 C면 텍스트가 없다는 뜻입니다. 그때는 read_document_image로
넘어가세요 — 이 도구가 빈 본문을 돌려주는 것을 "내용이 없다"로 읽으면 안 됩니다.
요약할 때 앵커를 그대로 인용하세요. Phase 4의 check_summary_grounding이
그 앵커로 원문 대조를 합니다. 앵커 없는 문장은 근거 없는 문장으로 처리됩니다.
Args: path: 읽을 파일. start: 시작 블록 번호(1부터). end: 끝 블록 번호(포함). 생략하면 글자 수 상한까지.
Returns: ReadDocumentResponse: 확정 등급, 앵커 붙은 본문, 구조화 블록, 형식별 메타.
Examples: - 사용: "이 PDF 3~8페이지에 뭐가 있나요?" → start=3, end=8 - 사용하지 않음: 페이지 수·제목 구조만 필요할 때 → inspect_document - 사용하지 않음: 등급 C 파일 → read_document_image
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | 읽기를 끝낼 블록 번호(포함). None이면 글자 수 상한까지 읽습니다. 블록의 뜻은 응답의 unit 필드가 알려 줍니다 | |
| path | Yes | scan_folder가 돌려준 상대 경로, 또는 root 안의 절대 경로 | |
| start | No | 읽기 시작할 블록 번호(1부터) |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | Yes | 이 응답이 담은 마지막 블록 번호 |
| meta | Yes | 형식별 메타 (페이지 수, 표 개수 등) |
| path | Yes | |
| unit | Yes | 이 형식에서 블록 하나가 무엇인지 (페이지/슬라이드/문단) |
| grade | Yes | 확정된 추출가능등급. A=구조까지, B=본문만, C=텍스트 없음 |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| start | Yes | 이 응답이 담은 첫 블록 번호 (1부터) |
| blocks | Yes | 같은 내용의 구조화 형태 |
| status | Yes | 이 호출의 결과 상태 |
| content | Yes | 앵커가 붙은 본문. 'p3 | 내용' 형태로 한 줄씩 이어집니다 |
| unit_count | Yes | 원래 단위의 개수 (총 페이지 수 등) |
| grade_reason | Yes | 그 등급으로 판정한 근거 |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| total_blocks | Yes | 문서 전체의 블록 수 |
| truncated_by_chars | Yes | True면 글자 수 상한 때문에 범위 안에서도 잘렸습니다 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds rich behavioral context: the unified interface flattening all formats to a 1D block list, the 'unit' field clarifying block semantics per format, the grade C null-text signal and how to interpret it, and the anchor-citation contract for grounding. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and key behavior (anchors + range), uses bold labels and bullet-style separators for readability, and includes examples without padding. Every sentence earns its place—no fluff or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (ReadDocumentResponse), the description doesn't need to detail return structure—it summarizes the key fields. It covers edge cases (grade C), cross-tool interactions (inspect_document, read_document_image, check_summary_grounding), and parameter semantics. For a tool with 3 params and rich sibling relationships, this is fully complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter has a description, so the baseline is 3. The description adds practical meaning beyond the schema: it explains the block concept (via 'unit'), gives a concrete example mapping 'PDF 3~8 pages' to start=3,end=8, and clarifies that end omitted reads to a character limit. This elevates it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (read) and resource (document body) with a key qualifier (citation anchors), and explicitly distinguishes itself from siblings: 'inspect_document' for metadata-only needs and 'read_document_image' for grade C files. An agent can immediately tell what this tool does and why it exists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit 'when to use' (reading content with anchors), 'when not to use' (inspect_document for page count/title, read_document_image for grade C), and even explains the downstream dependency on check_summary_grounding that requires anchors. This leaves zero ambiguity about selection conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_document_imageARead-onlyIdempotent
텍스트가 없는 문서를 이미지로 받아 직접 판독합니다.
png는 원본을, pdf는 해당 페이지에 임베드된 이미지를 돌려줍니다.
스캔 PDF는 페이지 전체가 하나의 이미지이므로 이 방법으로 판독됩니다.
벡터로만 그려진 페이지는 꺼낼 수 없고, 그때는 오류가 사람이 할 일을 알려 줍니다.
이미지는 긴 변 1568px로 줄여서 넘어옵니다. 판독 정확도에는 영향이 없습니다.
판독한 내용은 원문 인용이 아닙니다. 요약에 쓸 때는 "(이미지 판독)"을 표기하세요. 텍스트 앵커와 같은 근거로 취급하면 안 됩니다.
Args: path: png 또는 pdf 경로. page: pdf의 페이지 번호.
Returns: list: 이미지 한 장과, 출처·크기·다음 단계를 적은 안내 문자열. (바이너리를 돌려주는 유일한 도구이므로 구조화 응답 규약에서 벗어납니다.)
Examples: - 사용: read_document가 등급 C를 돌려준 뒤 - 사용하지 않음: 등급 A·B 파일 → read_document로 텍스트를 읽는 게 정확합니다
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | pdf일 때 읽을 페이지 번호(1부터). png는 무시됩니다 | |
| path | Yes | png 파일, 또는 텍스트가 없는 pdf 파일 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly, idempotent), the description discloses that it returns binary data (the only tool to do so), resizes images to 1568px on the long side, and warns that the read content is not a direct quote, requiring the '(이미지 판독)' marker. It also describes error behavior for vector-only pages, providing rich behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear sections (intro, args, returns, examples). The core purpose is front-loaded in the first sentence, and each subsequent sentence contributes essential details (format, resizing, usage, return) without redundancy. It is appropriately sized for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by explaining the return format (a list with image and guidance string) and noting it deviates from structured responses. It covers error cases for vector-only pages, provides usage examples, and explains how to handle the result in summaries, making it complete for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides complete descriptions for both 'path' and 'page' (100% coverage), including the note that page is ignored for png. The description only paraphrases these, adding no new semantic meaning beyond the schema's existing clarity, so it meets the baseline but does not exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it reads documents without text as images, with a specific verb ('직접 판독합니다') and resource ('텍스트가 없는 문서'). It distinguishes itself from the sibling 'read_document' by explaining it is for images/scanned PDFs and specifically for grade C files, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided in the Examples section: use when 'read_document' returns grade C, and do not use for grade A/B files, where 'read_document' is more accurate. It also explains when it is applicable (scanned PDFs, embedded images) and when it is not (vector-only pages).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_approved_reportADestructiveIdempotent
승인된 초안을 output_root에 저장합니다. 이 서버의 유일한 쓰기 도구입니다.
사용자가 명시적으로 승인한 뒤에만 부르세요. 승인은 사람만 할 수 있는 단계입니다. 미리보기가 READY라는 것은 "저장해도 된다"가 아니라 "게이트를 통과했다"는 뜻입니다.
게이트를 전부 다시 확인합니다 — 구조 · 근거 · 토큰 · 저장 위치. 미리보기가
통과했다는 말을 믿지 않습니다. 오류가 남아 있으면 DRAFT_NOT_CLEAN,
초안이 바뀌었으면 APPROVAL_TOKEN_MISMATCH로 거부합니다.
기존 산출물이 있으면 덮어씁니다. 덮어쓴 사실과 이전 내용의 해시는 감사 기록에 append됩니다 — 기존 기록을 고치거나 지우지 않습니다.
Args: path: 원본 파일. draft: 초안 전문. 미리보기 때와 같아야 합니다. approval_token: 미리보기가 발급한 토큰.
Returns: SaveResponse: 저장 위치, 덮어쓰기 여부, 감사 기록 항목.
Examples: - 사용: 사람이 "저장해"라고 말한 뒤 - 사용하지 않음: 미리보기가 BLOCKED인 상태 — 저장되지 않습니다 - 사용하지 않음: 사람의 승인 없이 흐름을 이어가려 할 때
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | 원본 파일 | |
| draft | Yes | 저장할 초안. preview_save_report에 넘긴 것과 **완전히 같아야** 합니다 | |
| approval_token | Yes | preview_save_report가 발급한 토큰 |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| path | Yes | |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| status | Yes | 이 호출의 결과 상태 |
| overwrote | Yes | |
| audit_file | Yes | |
| draft_hash | Yes | |
| audit_entry | Yes | 감사 기록에 append된 한 줄 |
| draft_lines | Yes | |
| output_name | Yes | |
| output_root | Yes | |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| previous_hash | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the destructiveHint/readOnlyHint annotations: discloses that it re-validates all gates independently of the preview, specifies failure codes (DRAFT_NOT_CLEAN, APPROVAL_TOKEN_MISMATCH), explains overwrite behavior, and reveals the append-only audit log that preserves prior hashes and never modifies/deletes existing records. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the most critical facts (only write tool, approval required), then proceeds through gate re-checking, overwrite/audit behavior, and closes with a valuable use/don't-use Examples section. Every sentence earns its place; the length is justified by the destructive nature of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a destructive write tool: it ties into the preview_save_report workflow, states approval requirements, error conditions, overwrite and audit semantics. An output schema (SaveResponse) exists so return values need no elaboration, and allowed roots are covered by the list_allowed_roots sibling. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all three parameters already well documented, including the constraint that draft must exactly match what was passed to preview_save_report. The description's Args section largely mirrors the schema, adding little new meaning, so the baseline 3 applies — the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('저장합니다') + resource ('output_root') and explicitly positions itself as the only write tool on the server, clearly distinguishing it from its read-only siblings including the paired preview_save_report. An agent immediately understands what this tool does and how it differs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance ('only after the user has explicitly approved', approval is human-only) and when-not-to-use examples (preview BLOCKED, or continuing without approval). Clarifies that a READY preview is not permission to save — it only means the gate was passed — which directly prevents misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_folderARead-onlyIdempotent
폴더 안의 대상 문서를 목록화합니다. 파일을 열지 않습니다.
stat 정보만 보므로 큰 폴더에서도 빠릅니다. 대신 스캔 PDF와 텍스트 PDF를
구분할 수 없습니다 — expected_grade가 B?인 파일은 inspect_document로
확정하세요.
개수는 코드가 셉니다. total_matched와 returned가 다르면
truncated가 True이고, 범위를 좁혀 다시 호출해야 합니다.
Args: folder: root 절대경로 또는 root 기준 상대경로. recursive: 하위 폴더 포함 여부. extensions: 확장자 필터.
Returns:
ScanFolderResponse: entries[]와 확장자별·등급별 집계.
Examples: - 사용: "이 폴더에 뭐가 들어 있나요?" / 분석 대상을 고르기 전 - 사용하지 않음: 특정 파일의 페이지 수·제목 구조가 필요할 때 → inspect_document
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | 스캔할 폴더. list_allowed_roots의 root 절대경로거나, root 기준 상대경로('보고서/2026')입니다. root 자체를 훑으려면 '.' | . |
| recursive | No | 하위 폴더까지 훑을지 여부 | |
| extensions | No | 좁히고 싶을 때만 지정합니다. 예: ['.pdf', '.pptx']. None이면 서버가 여는 모든 형식 |
Output Schema
| Name | Required | Description |
|---|---|---|
| root | Yes | |
| stage | Yes | 분석 워크플로에서 지금 위치한 단계 |
| folder | Yes | root 기준 상대 경로 |
| status | Yes | 이 호출의 결과 상태 |
| entries | Yes | |
| returned | Yes | 이 응답에 실제로 담긴 개수 |
| recursive | Yes | |
| truncated | Yes | True면 total_matched만큼 다 담지 못했습니다 |
| by_extension | Yes | 확장자별 개수. 코드가 센 값입니다 |
| next_actions | No | 이어서 호출하면 좋은 도구 목록 |
| total_matched | Yes | 조건에 맞는 파일 총 개수 (절단 전) |
| unreadable_dirs | Yes | 권한 등으로 열지 못한 폴더 이름 |
| by_expected_grade | Yes | 추정등급별 개수 |
| skipped_unsupported | Yes | 다루지 않는 확장자여서 건너뛴 개수 |
| skipped_outside_root | Yes | 링크 등으로 실경로가 root 밖이거나 읽을 수 없어 제외한 개수 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only and non-destructive behavior, but the description goes beyond them by disclosing that it does not open files, uses stat info only (hence fast), cannot distinguish scanned vs text PDFs, and that truncation occurs when total_matched != returned. These are non-obvious behaviors an agent needs to know to interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Args, Returns, Examples) and front-loaded with the primary purpose and speed caveat. It is slightly longer than strictly necessary, but every sentence contributes either to usage guidance or behavioral transparency. The use of bold and code formatting aids readability without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description correctly focuses on when to use, limitations, truncation handling, and sibling routing. It covers all operational concerns an agent would have: speed, PDF-type ambiguity, pagination/truncation, and path conventions. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all three parameters with full coverage (100%). The description does not add new semantic value beyond restating parameter purposes; it does give usage context for extensions (optional filter) and the folder default, but these are also in the schema. This matches the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('list') and resource ('documents in a folder'), and immediately distinguishes itself from siblings by noting it does not open files. It also clarifies it only reads stat information, which sets it apart from inspect_document. This is a clear, non-tautological purpose statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use ('what's in this folder?' before selecting analysis targets) and when-not-to-use (when page count or title structure is needed → inspect_document). It also gives a conditional routing rule: if expected_grade is 'B?', use inspect_document. This is comprehensive usage guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
build_analysis_prompt - First observed
check_summary_grounding - First observed
inspect_document - First observed
list_allowed_roots - First observed
preview_save_report - First observed
read_document - First observed
read_document_image - First observed
save_approved_report - First observed
scan_folder
TDQS
Scored across 9 tools
Each tool has a clearly distinct purpose: listing roots, scanning folders, inspecting documents, reading text, reading images, building prompts, checking grounding, previewing saves, and saving reports. There is no overlap or ambiguity between tools; even closely related tools like read_document and read_document_image are explicitly differentiated by content type (text vs. image).
All tool names follow a consistent verb_noun pattern in snake_case: list_allowed_roots, scan_folder, inspect_document, read_document, read_document_image, build_analysis_prompt, check_summary_grounding, preview_save_report, save_approved_report. The minor compound in preview_save_report still reads predictably, and there is no mixing of conventions.
With 9 tools, the set is well-scoped for a file-analysis and report-generation server. It covers the full pipeline from discovery (list_allowed_roots, scan_folder) through inspection and reading (inspect_document, read_document, read_document_image) to authoring and publishing (build_analysis_prompt, check_summary_grounding, preview_save_report, save_approved_report), with each tool earning its place.
The tool surface provides a complete workflow for analyzing documents and producing grounded reports: it includes discovery, inspection, reading (text and images), prompt building, grounding verification, save preview, and final save. There are no obvious gaps; even edge cases like scanned PDFs are handled via read_document_image, and the save pipeline includes a human-approval gate.
Maintenance
Related MCP Connectors
Verified extraction: source-backed JSON from PDFs/URLs; honest null + signed receipt.
High-fidelity PDF to structured Markdown conversion and document field extraction.
Extract PDFs to Markdown, RAG chunks and cited tables; publish tracked Doc Links with read stats.
AI document intelligence: extract, summarize, claim-check, notarize, and signed action receipts.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables reading and extracting text from local documents (PDF, Word, Excel, PowerPoint, HWP, Markdown, CSV, etc.) without network access, and provides approval-gated summary saving and file organization.11MIT
- FlicenseNot gradedqualityCmaintenanceEnables local, read-only extraction of text and structure from PDF, DOCX, PPTX, SVG, and PNG files, including OCR for images, directory tree and metadata reporting, with strict path isolation and audit logging.-
- FlicenseNot gradedqualityCmaintenanceEnables local folder analysis of unstructured documents (PDF, DOCX, PPTX, TXT, SVG, PNG, CSV, XLSX) by extracting structure, reading content, and generating reports, with a strict approval gate before any save operation.-
- FlicenseAqualityCmaintenanceAnalyzes unstructured documents in a local folder, extracting structure and key terms, and supports generating summaries via a host LLM with validated, approval-based report saving.13-