claude-code-hwp-mcp 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +409 -0
  2. package/dist/hwp-bridge.d.ts +67 -0
  3. package/dist/hwp-bridge.js +320 -0
  4. package/dist/hwpx-engine.d.ts +39 -0
  5. package/dist/hwpx-engine.js +187 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +54 -0
  8. package/dist/prompts/hwp-prompts.d.ts +2 -0
  9. package/dist/prompts/hwp-prompts.js +368 -0
  10. package/dist/resources/document-resources.d.ts +3 -0
  11. package/dist/resources/document-resources.js +109 -0
  12. package/dist/server.d.ts +12 -0
  13. package/dist/server.js +29 -0
  14. package/dist/tools/analysis-tools.d.ts +4 -0
  15. package/dist/tools/analysis-tools.js +414 -0
  16. package/dist/tools/composite-tools.d.ts +3 -0
  17. package/dist/tools/composite-tools.js +664 -0
  18. package/dist/tools/document-tools.d.ts +3 -0
  19. package/dist/tools/document-tools.js +264 -0
  20. package/dist/tools/editing-tools.d.ts +4 -0
  21. package/dist/tools/editing-tools.js +916 -0
  22. package/package.json +31 -0
  23. package/python/__pycache__/hwp_analyzer.cpython-313.pyc +0 -0
  24. package/python/__pycache__/hwp_editor.cpython-313.pyc +0 -0
  25. package/python/__pycache__/hwp_service.cpython-313.pyc +0 -0
  26. package/python/__pycache__/privacy_scanner.cpython-313.pyc +0 -0
  27. package/python/__pycache__/ref_reader.cpython-313.pyc +0 -0
  28. package/python/__pycache__/test_integration.cpython-313.pyc +0 -0
  29. package/python/hwp_analyzer.py +544 -0
  30. package/python/hwp_editor.py +933 -0
  31. package/python/hwp_service.py +1291 -0
  32. package/python/privacy_scanner.py +115 -0
  33. package/python/ref_reader.py +115 -0
  34. package/python/requirements.txt +2 -0
@@ -0,0 +1,368 @@
1
+ /**
2
+ * MCP Prompts: fill_document, edit_document, analyze_document, batch_process
3
+ */
4
+ import { z } from 'zod';
5
+ export function registerPrompts(server) {
6
+ server.prompt('fill_document', 'HWP 문서의 빈 필드와 표 셀을 사전질문→분석→미리보기→채우기→검증 흐름으로 채웁니다.', {
7
+ file_path: z.string().describe('HWP 파일 경로'),
8
+ context: z.string().optional().describe('추가 지시사항 (선택)'),
9
+ }, ({ file_path, context }) => ({
10
+ messages: [{
11
+ role: 'user',
12
+ content: {
13
+ type: 'text',
14
+ text: `다음 HWP 문서의 빈 항목을 채워주세요.
15
+
16
+ ## ⚠️ 바로 채우지 마세요. 아래 순서를 따르세요.
17
+
18
+ ### Step 1: 사전 확인
19
+ 사용자에게 먼저 확인하세요:
20
+ - "참고할 자료(엑셀, 텍스트 등)가 있으신가요?"
21
+ - "분량은 간결하게 / 표준 / 상세하게 중 어느 수준으로?"
22
+ - "확정된 수치(금액, 일정 등)가 있으면 알려주세요"
23
+
24
+ ### Step 2: 문서 분석
25
+ - hwp_smart_analyze로 구조와 빈 항목 파악
26
+ - 참고자료가 있으면 hwp_read_reference로 로드
27
+
28
+ ### Step 3: 미리보기
29
+ - "다음과 같이 채울 예정입니다:" → 내용 요약 제시
30
+ - 사용자 확인 후 진행
31
+
32
+ ### Step 4: 채우기 + 저장
33
+ - hwp_smart_fill 또는 hwp_fill_table_cells로 채우기
34
+ - hwp_save_document로 저장
35
+
36
+ ### Step 5: 검증
37
+ - 빈 항목 잔여 확인 (hwp_smart_analyze 재실행)
38
+ - "수정할 부분이 있으면 말씀해주세요"
39
+
40
+ 파일: ${file_path}
41
+ ${context ? `추가 지시: ${context}` : ''}
42
+
43
+ 규칙:
44
+ - 결재란/서명란: AI가 채우면 안 됨
45
+ - 이미 내용이 있는 셀: 변경하지 않음
46
+ - 사용자가 제공하지 않은 수치는 임의로 만들지 않음`,
47
+ },
48
+ }],
49
+ }));
50
+ server.prompt('edit_document', '현재 열린 HWP 문서의 특정 부분을 수정합니다.', {
51
+ instructions: z.string().describe('수정 지시사항'),
52
+ }, ({ instructions }) => ({
53
+ messages: [{
54
+ role: 'user',
55
+ content: {
56
+ type: 'text',
57
+ text: `현재 열린 HWP 문서를 다음 지시에 따라 수정해주세요.
58
+
59
+ 작업 순서:
60
+ 1. hwp_analyze_document 또는 hwp_get_document_text로 현재 내용 확인
61
+ 2. 지시사항에 맞게 hwp_find_replace, hwp_fill_fields, hwp_fill_table_cells 등 적절한 도구 사용
62
+ 3. 수정 후 hwp_save_document로 저장
63
+
64
+ 지시사항: ${instructions}
65
+
66
+ 규칙:
67
+ - 지시하지 않은 부분은 변경하지 않음
68
+ - 직급/부서명은 원본 그대로 유지 (변경 금지)
69
+ - 결재란은 비워둠 (AI가 채우면 안 됨)
70
+ - 날짜 형식: 마침표 구분 (예: 2026. 3. 19.)
71
+ - 금액: 한글+숫자 병기 (예: 금일백만원정(₩1,000,000))
72
+ - 수정 전후 내용을 요약해서 보고`,
73
+ },
74
+ }],
75
+ }));
76
+ server.prompt('analyze_document', '문서를 분석하고 구조, 내용, 완성도를 요약합니다.', {
77
+ file_path: z.string().describe('HWP 파일 경로'),
78
+ }, ({ file_path }) => ({
79
+ messages: [{
80
+ role: 'user',
81
+ content: {
82
+ type: 'text',
83
+ text: `다음 HWP 문서를 분석하고 요약해주세요.
84
+
85
+ 작업 순서:
86
+ 1. hwp_document_summary로 문서 완성도 확인
87
+ 2. hwp_get_document_text로 본문 내용 확인
88
+ 3. hwp_get_tables로 표 데이터 확인
89
+
90
+ 파일: ${file_path}
91
+
92
+ 다음 항목을 보고해주세요:
93
+ - 문서 종류 및 목적
94
+ - 페이지 수, 표 수, 필드 수
95
+ - 작성 완성도(%)
96
+ - 빈 항목이 있다면 목록
97
+ - 문서 내용 요약 (3-5줄)`,
98
+ },
99
+ }],
100
+ }));
101
+ server.prompt('batch_process', '디렉토리 내 모든 HWP 파일을 일괄 처리합니다.', {
102
+ directory: z.string().describe('처리할 디렉토리 경로'),
103
+ operation: z.enum(['analyze', 'fill', 'convert']).describe('작업 유형: analyze, fill, convert'),
104
+ }, ({ directory, operation }) => ({
105
+ messages: [{
106
+ role: 'user',
107
+ content: {
108
+ type: 'text',
109
+ text: `디렉토리 내의 모든 HWP 파일을 일괄 처리합니다.
110
+
111
+ 작업 순서:
112
+ 1. hwp_list_files로 '${directory}' 내 파일 목록 확인
113
+ 2. 각 파일에 대해 순차적으로 ${operation} 작업 수행
114
+ 3. 작업 완료 후 결과 요약 보고
115
+
116
+ 작업 유형: ${operation}
117
+ - analyze: 각 파일 분석 및 요약
118
+ - fill: 각 파일의 빈 항목 채우기
119
+ - convert: 각 파일을 지정 형식으로 변환
120
+
121
+ 주의: 각 파일 처리 후 반드시 hwp_close_document로 닫은 후 다음 파일 진행`,
122
+ },
123
+ }],
124
+ }));
125
+ server.prompt('fill_public_document', '공공기관 사업계획서/신청서 작성. 기본: 빠른 모드(2개 질문). context에 "--상세" 추가 시 상세 모드(5개 질문+미리보기).', {
126
+ file_path: z.string().describe('HWP 파일 경로'),
127
+ reference: z.string().optional().describe('참고자료 파일 경로 또는 내용'),
128
+ context: z.string().optional().describe('추가 지시. "--상세" 포함 시 상세 모드'),
129
+ }, ({ file_path, reference, context }) => {
130
+ const detailMode = context?.includes('--상세') || context?.includes('--detail');
131
+ return {
132
+ messages: [{
133
+ role: 'user',
134
+ content: {
135
+ type: 'text',
136
+ text: `한글 문서를 작성해주세요.
137
+
138
+ ## ⚠️ 사전 확인 (반드시 먼저 물어보세요. 바로 채우지 마세요.)
139
+
140
+ 다음 질문을 사용자에게 확인한 후 작업을 시작하세요:
141
+
142
+ 1. **참고자료**: "채울 내용의 참고자료(엑셀, 기존 문서, 회사소개서 등)가 있으신가요?"
143
+ → 있으면 hwp_read_reference로 로드
144
+ 2. **양식**: "참고할 양식 파일이 있으신가요? (서식/구조를 따를 문서)"
145
+ → 있으면 hwp_extract_style_profile로 서식(글꼴/크기/자간/들여쓰기) 추출하여 동일하게 적용
146
+ → 없으면 일반 공공기관 표준 적용 (document_format_guide 참조)
147
+ 3. **말투**: "개괄식(~했음, ~임)과 격식체(~했습니다, ~입니다) 중 어떤 문체로?"
148
+ 4. **분량**: "예상 페이지 수가 있으신가요? (예: 5~6페이지)"
149
+ 5. **확정 수치**: "금액, 일정, 목표 등 확정된 수치가 있으면 알려주세요" (없으면 임의 생성하지 않음)
150
+ 6. **추가 참조**: "웹 검색이나 다른 소스를 참조할까요?"
151
+
152
+ ## 작업 순서
153
+ 1. hwp_smart_analyze → 문서 구조/타입/완성도 파악
154
+ 2. 참고자료 있으면 → hwp_auto_fill_from_reference로 자동 매핑+채우기
155
+ 3. 없으면 → hwp_smart_fill로 서식 보존하며 채우기
156
+ ${detailMode ? `4. 채우기 전 미리보기 → 사용자 확인 후 진행` : ''}
157
+ 5. hwp_save_document → 저장
158
+ 6. 검증: hwp_privacy_scan(개인정보) + 빈 셀 확인 → 결과 보고
159
+
160
+ 파일: ${file_path}
161
+ ${reference ? `참고자료: ${reference}` : ''}
162
+ ${context ? `지시: ${context.replace('--상세', '').replace('--detail', '').trim()}` : ''}
163
+
164
+ ## 규칙 (공문서 표준 — document_format_guide 참조)
165
+ - 서식: style 미지정 → 기존 셀 서식 자동 상속
166
+ - 날짜: "2025. 3. 22.", 금액: "금10,269,000원", 순번: 1.→가.→1)→가)
167
+ - 결재란/서명란/이미 채워진 셀: 변경 금지
168
+
169
+ ## 양식 동적 대응 원칙
170
+ - 양식이 제공되면 반드시 hwp_extract_style_profile로 서식 추출 → 동일 적용
171
+ - 글꼴/크기/자간/줄간격을 고정 규칙이 아닌 양식에서 추출한 값으로 적용
172
+ - 순번 체계는 양식의 패턴을 따름 (Ⅰ/□/1./ㅇ 등 양식마다 다름)
173
+ - 작성요령(< 작성요령 >, ※ 표시) → 작성 완료 후 hwp_delete_guide_text로 삭제 여부 확인
174
+ - 체크박스(□, ☐) → hwp_toggle_checkbox로 체크 전환
175
+ - 공문서 양식은 수신/참조/결재란 구조를 인식하고 보존`,
176
+ },
177
+ }],
178
+ };
179
+ });
180
+ server.prompt('document_format_guide', '한국 공공기관 공문서 서식 표준 가이드를 제공합니다.', {}, () => ({
181
+ messages: [{
182
+ role: 'user',
183
+ content: {
184
+ type: 'text',
185
+ text: `한국 공공기관 공문서 서식 표준을 알려주세요.
186
+
187
+ ## 핵심 규격
188
+
189
+ ### 1. 문서 구조: 두문·본문·결문 3단 구성
190
+ - 두문: 행정기관명, 수신자
191
+ - 본문: 제목, 내용, 붙임 (붙임 뒤 쌍점 없음)
192
+ - 결문: 발신명의, 기안자/검토자/결재자, 기관 정보
193
+
194
+ ### 2. 글꼴/크기
195
+ | 용도 | 보고서 | 기안문 |
196
+ |------|--------|--------|
197
+ | 본문 | 휴먼명조(HTF) 15pt | 맑은 고딕 11.5pt |
198
+ | 대제목 | HY헤드라인M 22pt | - |
199
+ | 소제목 | 16pt | - |
200
+ | 참조 | 중고딕 13pt | - |
201
+ | 표 안 | 10pt | 10pt |
202
+
203
+ ### 3. 줄간격/자간/장평
204
+ | 항목 | 보고서 | 기안문(맑은고딕) | 기안문(굴림, 구) |
205
+ |------|--------|----------------|----------------|
206
+ | 줄간격 | 160% | 103% | 123% |
207
+ | 장평 | 100 | 100 | 100 |
208
+ | 자간 | 0 (-10~0) | 0 | 0 |
209
+ | 표 안 줄간격 | 100~130% | - | 123% |
210
+
211
+ ### 4. 순번 체계 (시행규칙 제2조 제1항)
212
+ 1. → 가. → 1) → 가) → (1) → (가) → ① → ㉮
213
+ 들여쓰기: 2단계부터 2타(한글 1자)씩
214
+
215
+ ### 5. 여백 (보고서/공문서)
216
+ | 항목 | 보고서(mm) | 공문서(mm) |
217
+ |------|-----------|-----------|
218
+ | 위 | 15 | 30 |
219
+ | 아래 | 10~15 | 15 |
220
+ | 좌 | 20 | 20 |
221
+ | 우 | 20 | 15 |
222
+
223
+ ### 6. 날짜/금액/기타
224
+ - 날짜: "2025. 3. 21." (연월일 글자 생략, 마침표 사이 1타)
225
+ - 금액: 아라비아 숫자 + 괄호 한글 병기
226
+ - "끝" 표시: 본문 마지막 2타 띄운 후
227
+ - 법령 인용: 낫표 「 」
228
+ - 관인: 발신명의 마지막 글자가 인영 가운데`,
229
+ },
230
+ }],
231
+ }));
232
+ server.prompt('review_document', '작성 완료된 문서를 검토하고 수정점을 제안합니다. 공문서 표준 준수, 개인정보, 빈 항목, 내용 일관성을 점검합니다.', {
233
+ file_path: z.string().describe('HWP 파일 경로'),
234
+ }, ({ file_path }) => ({
235
+ messages: [{
236
+ role: 'user',
237
+ content: {
238
+ type: 'text',
239
+ text: `다음 문서를 검토하고 수정이 필요한 부분을 알려주세요.
240
+
241
+ ## 검토 순서
242
+ 1. hwp_smart_analyze로 문서 구조 + 완성도 확인
243
+ 2. hwp_get_as_markdown으로 전체 내용 확인
244
+ 3. hwp_privacy_scan으로 개인정보 포함 여부 확인
245
+
246
+ ## 검토 항목 (체크리스트)
247
+ - [ ] 빈 셀/필드가 남아있는지
248
+ - [ ] 날짜 형식: "2025. 3. 22." (마침표 구분, 연월일 글자 생략)
249
+ - [ ] 금액 형식: "금OOO원" (아라비아 숫자)
250
+ - [ ] 순번 체계: 1. → 가. → 1) → 가) → (1) → (가) → ① → ㉮
251
+ - [ ] 결재란/서명란이 비워져 있는지 (AI가 채우면 안 됨)
252
+ - [ ] 개인정보(주민번호, 전화번호, 이메일) 포함 시 마스킹 필요 여부
253
+ - [ ] 내용의 논리적 일관성 (목표 ↔ 추진전략 ↔ 기대효과 연결)
254
+ - [ ] 문체 일관성 (격식체/일반체 혼용 여부)
255
+
256
+ 파일: ${file_path}
257
+
258
+ ## 결과 형식
259
+ 검토 결과를 다음 형식의 표로 정리하세요:
260
+ | 항목 | 상태 | 내용 |
261
+ |------|------|------|
262
+ | 완성도 | ✅/⚠️ | 예: 100%, 빈 셀 3개 |
263
+ | 날짜 형식 | ✅/❌ | 예: 모두 정상 / "2025년 3월" → "2025. 3." 수정 필요 |
264
+ | ... | | |
265
+
266
+ 수정이 필요한 부분은 구체적인 위치(표 번호, 셀)와 수정 방법을 안내하세요.`,
267
+ },
268
+ }],
269
+ }));
270
+ server.prompt('auto_fill_from_excel', '엑셀/CSV 데이터로 HWP 양식을 자동으로 채웁니다. "엑셀로 양식 채워줘" 요청에 사용.', {
271
+ file_path: z.string().describe('HWP 파일 경로'),
272
+ excel_path: z.string().describe('엑셀 또는 CSV 파일 경로'),
273
+ }, ({ file_path, excel_path }) => ({
274
+ messages: [{
275
+ role: 'user',
276
+ content: {
277
+ type: 'text',
278
+ text: `엑셀 데이터로 한글 양식을 자동 채워주세요.
279
+
280
+ ## 작업 순서
281
+ 1. hwp_smart_analyze로 HWP 문서 구조 파악
282
+ 2. hwp_read_reference로 엑셀 데이터 로드
283
+ 3. hwp_auto_fill_from_reference로 자동 매핑 + 채우기
284
+ 4. 매핑 안 된 항목은 사용자에게 확인
285
+ 5. hwp_save_document로 저장
286
+ 6. hwp_privacy_scan으로 개인정보 확인
287
+
288
+ HWP 파일: ${file_path}
289
+ 엑셀 파일: ${excel_path}
290
+
291
+ 규칙:
292
+ - 서식: 기존 셀 서식 자동 상속
293
+ - 결재란/서명란: 채우지 않음
294
+ - 매핑 불확실한 항목: 사용자에게 확인 후 진행`,
295
+ },
296
+ }],
297
+ }));
298
+ server.prompt('create_report', '빈 문서에서 보고서를 새로 작성합니다.', {
299
+ topic: z.string().describe('보고서 주제'),
300
+ context: z.string().optional().describe('추가 지시'),
301
+ }, ({ topic, context }) => ({
302
+ messages: [{
303
+ role: 'user',
304
+ content: {
305
+ type: 'text',
306
+ text: `새 보고서를 작성해주세요.
307
+
308
+ ## 사전 확인
309
+ 1. "참고자료가 있으신가요?"
310
+ 2. "보고서 분량은? (간결/표준/상세)"
311
+ 3. "특별히 포함할 내용이 있으면 알려주세요"
312
+
313
+ ## 작업 순서
314
+ 1. 현재 열린 문서에 hwp_insert_heading으로 제목 삽입
315
+ 2. hwp_insert_markdown으로 본문 구조 작성
316
+ 3. 필요시 hwp_table_create_from_data로 표 삽입
317
+ 4. hwp_save_document로 저장
318
+
319
+ 주제: ${topic}
320
+ ${context ? `추가 지시: ${context}` : ''}
321
+
322
+ 규칙:
323
+ - 공문서 표준: 순번 1.→가.→1)→가), 날짜 "2025. 3. 22."
324
+ - 서식: 제목 Bold 22pt, 본문 11pt`,
325
+ },
326
+ }],
327
+ }));
328
+ server.prompt('write_document', '양식을 참고하여 새 문서를 처음부터 작성합니다. 양식 서식 추출 → 사전 질문 → 내용 작성 → 저장.', {
329
+ topic: z.string().describe('문서 주제/과업명'),
330
+ template_path: z.string().optional().describe('참고 양식 파일 경로 (서식/구조를 따를 문서)'),
331
+ reference_path: z.string().optional().describe('참고 내용 파일 경로 (내용을 가져올 문서)'),
332
+ }, ({ topic, template_path, reference_path }) => ({
333
+ messages: [{
334
+ role: 'user',
335
+ content: {
336
+ type: 'text',
337
+ text: `다음 주제로 문서를 작성해주세요.
338
+
339
+ ## ⚠️ 사전 확인 (반드시 먼저 물어보세요)
340
+
341
+ 1. **말투**: "개괄식(~했음, ~임)과 격식체(~했습니다, ~입니다) 중 어떤 문체로?"
342
+ 2. **분량**: "예상 페이지 수가 있으신가요?"
343
+ 3. **확정 수치**: "금액, 일정 등 확정된 수치가 있으면 알려주세요"
344
+ 4. **추가 참조**: "웹 검색이나 다른 소스를 참조할까요?"
345
+ 5. **구분 표시**: "AI가 추가한 내용을 파란색으로 표시할까요?"
346
+
347
+ ## 작업 순서
348
+ ${template_path ? `1. 양식 분석: hwp_open_document("${template_path}") → hwp_extract_style_profile로 서식 추출` : '1. 일반 공공기관 표준 서식 적용'}
349
+ ${reference_path ? `2. 내용 참고: hwp_read_reference("${reference_path}")로 내용 로드` : '2. AI가 주제에 맞는 내용 생성'}
350
+ 3. 새 문서에 양식 서식 + 내용 조합하여 작성
351
+ 4. 들여쓰기 적용 (left_margin + indent로 첫줄/나머지줄 설정)
352
+ 5. hwp_save_document로 저장 (한글에서 열린 상태 유지)
353
+ 6. 검증: hwp_privacy_scan + 빈 항목 확인
354
+
355
+ 주제: ${topic}
356
+ ${template_path ? `양식: ${template_path}` : ''}
357
+ ${reference_path ? `참고 내용: ${reference_path}` : ''}
358
+
359
+ ## 서식 규칙
360
+ - 양식이 제공되면: hwp_extract_style_profile 결과에 따라 동적 적용
361
+ - 양식이 없으면: 공공기관 표준 (document_format_guide 참조)
362
+ - 들여쓰기: left_margin(나머지 줄) + indent(첫 줄 추가) 조합
363
+ - 색상 구분: 원본 내용=검정, AI 추가=파란색(0,0,255)
364
+ - 작업 완료 후 한글 프로그램과 문서를 열린 상태로 유지`,
365
+ },
366
+ }],
367
+ }));
368
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { HwpBridge } from '../hwp-bridge.js';
3
+ export declare function registerResources(server: McpServer, bridge: HwpBridge): void;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * MCP Resources: document status, analysis, text, tables
3
+ */
4
+ import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ export function registerResources(server, bridge) {
6
+ // Server status
7
+ server.resource('status', 'hwp://status', {
8
+ description: 'HWP MCP 서버 상태 (Python 실행 여부, 열린 문서 정보)',
9
+ mimeType: 'application/json',
10
+ }, async (uri) => {
11
+ const state = bridge.getState();
12
+ const status = {
13
+ python_running: state.pythonRunning,
14
+ document_open: state.currentDocumentPath !== null,
15
+ current_file: state.currentDocumentPath,
16
+ current_format: state.currentDocumentFormat,
17
+ server_uptime_seconds: Math.round(state.uptimeMs / 1000),
18
+ };
19
+ return {
20
+ contents: [{ uri: uri.href, text: JSON.stringify(status), mimeType: 'application/json' }],
21
+ };
22
+ });
23
+ // Cached analysis
24
+ server.resource('current-analysis', 'hwp://current/analysis', {
25
+ description: '현재 문서의 캐시된 분석 결과 (표, 필드, 텍스트 포함)',
26
+ mimeType: 'application/json',
27
+ }, async (uri) => {
28
+ const analysis = bridge.getCachedAnalysis();
29
+ if (!analysis) {
30
+ return {
31
+ contents: [{
32
+ uri: uri.href,
33
+ text: JSON.stringify({ error: '분석된 문서가 없습니다. hwp_analyze_document를 먼저 실행하세요.' }),
34
+ mimeType: 'application/json',
35
+ }],
36
+ };
37
+ }
38
+ return {
39
+ contents: [{ uri: uri.href, text: JSON.stringify(analysis), mimeType: 'application/json' }],
40
+ };
41
+ });
42
+ // Current document text
43
+ server.resource('current-text', 'hwp://current/text', {
44
+ description: '현재 문서의 본문 텍스트',
45
+ mimeType: 'text/plain',
46
+ }, async (uri) => {
47
+ const analysis = bridge.getCachedAnalysis();
48
+ if (!analysis) {
49
+ return {
50
+ contents: [{
51
+ uri: uri.href,
52
+ text: '분석된 문서가 없습니다. hwp_analyze_document를 먼저 실행하세요.',
53
+ mimeType: 'text/plain',
54
+ }],
55
+ };
56
+ }
57
+ return {
58
+ contents: [{ uri: uri.href, text: analysis.full_text || '', mimeType: 'text/plain' }],
59
+ };
60
+ });
61
+ // Table resource template
62
+ server.resource('table', new ResourceTemplate('hwp://tables/{index}', {
63
+ list: async () => {
64
+ const analysis = bridge.getCachedAnalysis();
65
+ if (!analysis || !analysis.tables) {
66
+ return { resources: [] };
67
+ }
68
+ return {
69
+ resources: analysis.tables.map((_, i) => ({
70
+ uri: `hwp://tables/${i}`,
71
+ name: `표 ${i}`,
72
+ description: `문서의 ${i}번째 표 데이터`,
73
+ mimeType: 'application/json',
74
+ })),
75
+ };
76
+ },
77
+ }), {
78
+ description: '특정 표 데이터 (인덱스로 접근)',
79
+ mimeType: 'application/json',
80
+ }, async (uri, { index }) => {
81
+ const analysis = bridge.getCachedAnalysis();
82
+ if (!analysis || !analysis.tables) {
83
+ return {
84
+ contents: [{
85
+ uri: uri.href,
86
+ text: JSON.stringify({ error: '분석된 문서가 없습니다.' }),
87
+ mimeType: 'application/json',
88
+ }],
89
+ };
90
+ }
91
+ const idx = parseInt(String(index), 10);
92
+ if (isNaN(idx) || idx < 0 || idx >= analysis.tables.length) {
93
+ return {
94
+ contents: [{
95
+ uri: uri.href,
96
+ text: JSON.stringify({ error: `표 인덱스 ${index}이 범위를 벗어났습니다.` }),
97
+ mimeType: 'application/json',
98
+ }],
99
+ };
100
+ }
101
+ return {
102
+ contents: [{
103
+ uri: uri.href,
104
+ text: JSON.stringify(analysis.tables[idx]),
105
+ mimeType: 'application/json',
106
+ }],
107
+ };
108
+ });
109
+ }
@@ -0,0 +1,12 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { HwpBridge } from './hwp-bridge.js';
3
+ export type Toolset = 'minimal' | 'standard' | 'full';
4
+ /**
5
+ * MCP 서버 도구 등록.
6
+ *
7
+ * toolset별 도구 구성 (총 85개+, 2026-03-23 최종):
8
+ * - minimal (15개): 문서관리 5 + 분석 7 + 편집 3. 토큰 절약.
9
+ * - standard (85개+): 전체. 문서(5) + 분석(16) + 편집(51) + 복합(20). (기본값)
10
+ * - full: standard와 동일. 향후 확장 시 분리.
11
+ */
12
+ export declare function setupServer(server: McpServer, bridge: HwpBridge, toolset?: Toolset): void;
package/dist/server.js ADDED
@@ -0,0 +1,29 @@
1
+ import { registerDocumentTools } from './tools/document-tools.js';
2
+ import { registerAnalysisTools } from './tools/analysis-tools.js';
3
+ import { registerEditingTools } from './tools/editing-tools.js';
4
+ import { registerCompositeTools } from './tools/composite-tools.js';
5
+ import { registerResources } from './resources/document-resources.js';
6
+ import { registerPrompts } from './prompts/hwp-prompts.js';
7
+ /**
8
+ * MCP 서버 도구 등록.
9
+ *
10
+ * toolset별 도구 구성 (총 85개+, 2026-03-23 최종):
11
+ * - minimal (15개): 문서관리 5 + 분석 7 + 편집 3. 토큰 절약.
12
+ * - standard (85개+): 전체. 문서(5) + 분석(16) + 편집(51) + 복합(20). (기본값)
13
+ * - full: standard와 동일. 향후 확장 시 분리.
14
+ */
15
+ export function setupServer(server, bridge, toolset = 'standard') {
16
+ // 문서 관리 + 분석: 모든 toolset에 포함
17
+ registerDocumentTools(server, bridge);
18
+ registerAnalysisTools(server, bridge, toolset);
19
+ // 편집 도구: minimal에서는 핵심만
20
+ registerEditingTools(server, bridge, toolset);
21
+ // 복합 도구: minimal에서는 제외 (standard 이상)
22
+ if (toolset !== 'minimal') {
23
+ registerCompositeTools(server, bridge);
24
+ }
25
+ // 리소스 + 프롬프트: 모든 toolset에 포함
26
+ registerResources(server, bridge);
27
+ registerPrompts(server);
28
+ console.error(`[HWP MCP] 도구셋: ${toolset}`);
29
+ }
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { HwpBridge } from '../hwp-bridge.js';
3
+ import type { Toolset } from '../server.js';
4
+ export declare function registerAnalysisTools(server: McpServer, bridge: HwpBridge, toolset?: Toolset): void;