hwp-devcode-kr 프로젝트의 MCP 서버와 npm 패키지를 구축하는 스킬. MCP server 구현, npm publish 설정, AI tools 정의 시 사용. "MCP", "npm 배포", "AI 도구", "mcp-server" 키워드가 나오면 이 스킬을 사용할 것.
hwp-devcode-kr의 MCP 서버와 npm 패키지 구조를 구현한다.
파서 레이어(src/parser/, src/model/)가 구현되어 있어야 한다.
parse_hwp - HWP/HWPX 파일 → 문서 구조 JSON
extract_text - HWP/HWPX → 텍스트 추출
render_page_svg - 특정 페이지 → SVG 문자열 (렌더러 완성 후)
get_document_info - 문서 메타데이터 (쪽수, 작성자, 생성일 등)
hwp-devcode-kr/
├── src/
│ ├── index.ts ← 공개 API (npm 패키지)
│ ├── mcp-server.ts ← MCP 서버 진입점
│ └── tools/
│ ├── parse-hwp.ts
│ ├── extract-text.ts
│ ├── render-page-svg.ts
│ └── get-document-info.ts
├── package.json
├── tsconfig.json
└── tsup.config.ts
{
"name": "hwp-devcode-kr",
"version": "0.1.0",
"description": "Pure TypeScript HWP/HWPX parser and MCP server",
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./mcp-server": {
"import": "./dist/mcp-server.js",
"types": "./dist/mcp-server.d.ts"
}
},
"bin": {
"hwp-mcp": "./dist/mcp-server.js"
},
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"type-check": "tsc --noEmit"
},
"dependencies": {
"cfb": "^1.2.2",
"fflate": "^0.8.2",
"@modelcontextprotocol/sdk": "^1.0.0"
},
"devDependencies": {
"typescript": "^5.3.0",
"tsup": "^8.0.0",
"@types/node": "^20.0.0"
}
}
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"outDir": "dist",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"esModuleInterop": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
// src/mcp-server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new McpServer({
name: 'hwp-parser',
version: '0.1.0',
});
server.tool(
'parse_hwp',
'한글(HWP/HWPX) 파일을 파싱하여 문서 구조를 JSON으로 반환',
{
file_path: z.string().describe('HWP 또는 HWPX 파일 경로'),
},
async ({ file_path }) => {
const data = await fs.readFile(file_path);
const doc = HwpDocument.fromBuffer(new Uint8Array(data));
return {
content: [{
type: 'text',
text: JSON.stringify(doc.toJSON(), null, 2),
}],
};
}
);
server.tool(
'extract_text',
'HWP/HWPX 파일에서 텍스트를 추출',
{
file_path: z.string().describe('HWP 또는 HWPX 파일 경로'),
include_tables: z.boolean().optional().default(true),
},
async ({ file_path, include_tables }) => {
const data = await fs.readFile(file_path);
const doc = HwpDocument.fromBuffer(new Uint8Array(data));
const text = doc.extractText({ includeTables: include_tables });
return { content: [{ type: 'text', text }] };
}
);
// 서버 시작
const transport = new StdioServerTransport();
await server.connect(transport);
import { defineConfig } from 'tsup';
export default defineConfig({
entry: {
index: 'src/index.ts',
'mcp-server': 'src/mcp-server.ts',
},
format: ['esm'],
dts: true,
clean: true,
target: 'node18',
});
// ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
{
"mcpServers": {
"hwp-parser": {
"command": "node",
"args": ["/path/to/hwp-devcode-kr/dist/mcp-server.js"]
}
}
}
package.json + tsconfig.json + tsup.config.ts 생성npm install 실행src/index.ts — 공개 API 정의 (HwpDocument class)src/tools/extract-text.ts — 파서 완성 후 즉시 구현 가능src/tools/get-document-info.ts — 파서 완성 후 즉시 구현 가능src/mcp-server.ts — tools 구현 후src/tools/render-page-svg.ts — 렌더러 완성 후tsup 빌드 + 동작 확인# 빌드
npm run build
# MCP 서버 직접 실행 테스트
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/mcp-server.js
# 도구 호출 테스트
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"extract_text","arguments":{"file_path":"../rhwp/samples/sample.hwp"}}}' | node dist/mcp-server.js