hwpConvertMdMCP
将HWP/HWPX文件转换为Markdown hwpConverMd API的模型上下文协议(MCP)服务器。
Claude Desktop、Cursor、Claude Code、Flowise等MCP客户端可以使用HWP文档转换功能。
______________________________________________________________________
体系结构
MCP 클라이언트 (Claude Desktop / Cursor / Flowise CustomFunction)
│
│ stdio 또는 Streamable HTTP (JSON-RPC + SSE)
▼
hwpConverMdMCP (Node.js MCP Server)
│
│ HTTP (multipart/form-data)
▼
hwpConverMd (Python FastAPI Server)
│
├── HwpFastConverter (XML 직접 파싱, 고속)
├── HwpConverter (hwp5html 폴백)
│
├── POST /api/v1/convert → JSON (markdown + download_url)
├── POST /api/v1/convert/base64 → JSON (Base64 입력, Flowise용)
├── POST /api/v1/upload-md → JSON (임의 MD 저장 → download_url 발급)
└── GET /api/v1/download/{file} → 파일 다운로드______________________________________________________________________
前提条件
- Node.js >= 18.0.0
- hwpConverMd 必须运行Python服务器
运行hwpConverMd服务器
# Docker로 실행 (권장)
cd ../hwpConverMd
docker compose up --build
# 또는 직접 실행
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 8000如果服务器正常运行 http://localhost:8000/ 在 {"status": "ok"} 可以查看响应。
______________________________________________________________________
安装
npm install
npm run build______________________________________________________________________
MCP工具
“工具”“说明”“参数”“响应” |------|------|----------|------| | convert_hwp_to_md |转换为本地文件路径| filePath:文件路径| markdown文本| | convert_hwp_content_to_md |转换为Base64内容| content:Base64, filename:文件名| markdown+ [DOWNLOAD_URL] |
convert_hwp_content_to_md响应格式
该工具是MCP content 数组返回两个文本块:
{
"content": [
{ "type": "text", "text": "# 변환된 마크다운 내용..." },
{ "type": "text", "text": "[DOWNLOAD_URL]/api/v1/download/파일명.md" }
]
}- 第一块:转换后的标注全文
- 第二块:
[DOWNLOAD_URL]前缀+HWP API的下载路径(可能没有)
______________________________________________________________________
使用方法
1.在Claude桌面上使用(stdio)
claude_desktop_config.json添加到:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"hwp-converter": {
"command": "node",
"args": ["/absolute/path/to/hwpConverMdMCP/dist/transport/stdio.js"],
"env": {
"HWP_API_URL": "http://localhost:8000"
}
}
}
}2.在Cursor中使用(stdio)
在项目根目录中 .cursor/mcp.json 创建:
{
"mcpServers": {
"hwp-converter": {
"command": "node",
"args": ["/absolute/path/to/hwpConverMdMCP/dist/transport/stdio.js"],
"env": {
"HWP_API_URL": "http://localhost:8000"
}
}
}
}3.在Claude Code中使用(stdio)
claude mcp add hwp-converter \
-e HWP_API_URL=http://localhost:8000 \
-- node /absolute/path/to/hwpConverMdMCP/dist/transport/stdio.js4.Streamable HTTP模式(用于Flowise/Web客户端)
# 빌드 후 실행
npm run start:http
# 또는 개발 모드
npm run dev:httpMCP端点: http://localhost:3000/mcp
Docker Compose
根目录的 docker-compose.yml使用共同启动整个堆栈(API+MCP+Flowise):
# 루트 디렉토리에서
cd ..
docker compose up -d --build服务端口URL |--------|------|-----| |api | 8000 |http://localhost:8000/docs | |mcp|3001|http://localhost:3001/mcp | |流量|3000|http://localhost:3000 |
MCP容器的 HWP_API_URL=http://api:8000 (Docker内部网络)______________________________________________________________________
环境变量
| 变量 | 说明 | 默认值 |
|---|---|---|
HWP_API_URL | hwpConverMd API서버 URL | http://localhost:8000 |
MCP_HTTP_PORT | Streamable HTTP端口 | 3000 |
______________________________________________________________________
开发
npm install
npm run dev:stdio # stdio 모드 개발
npm run dev:http # HTTP 모드 개발
npm run build # TypeScript 빌드
npm run start:stdio # stdio 모드 실행
npm run start:http # HTTP 모드 실행______________________________________________________________________
Kubenetes部署
清单结构
k8s_manifest/
├── common/
│ ├── namespace.yaml # 네임스페이스
│ ├── default-deny.yaml # 기본 NetworkPolicy deny-all
│ └── resource-quota.yaml # 리소스 제한
└── mcp/
├── serviceaccount.yaml # 전용 ServiceAccount
├── rbac.yaml # 최소 권한 RBAC
├── configmap.yaml # 설정
├── mcp-deployment.yaml # Deployment + Service
├── networkpolicy.yaml # MCP → API 통신 허용
└── ingress.yaml # 외부 접근部署
# 공통 리소스
kubectl apply -f k8s_manifest/common/
# MCP 서버
kubectl apply -f k8s_manifest/mcp/K8s操作注意事项
MCP服务器作为一台运行(推荐)
MCP服务器 内存会话使用。在多个Pod上运行 initialize 收到请求的Pod和 tools/call 收到请求的Pod不同 "Server not initialized" 发生错误。
# MCP는 1대 고정 (stateful)
kubectl scale deploy hwp-mcp --replicas=1
# HPA가 걸려있으면 제거
kubectl delete hpa hwp-mcpMCP服务器只进行协议中继(几乎不使用CPU),一台就足够了。实际转换负载由HWP API负责,并通过HPA进行缩放。
如果需要多个Pod,请在Ingress中添加会话属性:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "MCP_ROUTE"
nginx.ingress.kubernetes.io/session-cookie-max-age: "600"Ingress设置(必需)
Base64编码的HWP文件将发送到JSON body,因此需要增加body size限制和超时:
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "360"
nginx.ingress.kubernetes.io/proxy-send-timeout: "360"Flowise调用时使用内部URL
Flowise CustomFunction调用MCP时 K8s内部服务URL请使用:
// K8s 내부 (권장) - Ingress 안 거침, body size 제한 없음
const MCP_URL = 'http://hwp-mcp-svc:3000/mcp';
// 외부 Ingress (비권장) - hairpin NAT, SSL, body size 제한
const MCP_URL = 'https://hwp-mcp.your-domain.com/mcp';安全设置
| 项目 | 应用程序 |
|---|---|
| 服务帐户 | 仅限服务SA, automountServiceAccountToken: false |
| 基于角色的访问控制 | 仅允许ConfigMap读取(最低权限) |
| 安全上下文 | runAsNonRoot, drop ALL capabilities, seccompProfile: RuntimeDefault |
| 网络策略 | default-deny-all +仅明示允许(mcp->api,ingress->mcp) |
确认
# Pod 상태
kubectl get pods -l app=hwp-mcp
# MCP 초기화 테스트
kubectl port-forward svc/hwp-mcp-svc 3000:3000
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'______________________________________________________________________
调用MCP工具
方法A:MCP客户端应用程序(Claude Desktop/Cursor)
设置后,如果用自然语言请求,LLM将自动调用工具:
“把这个HWP文件转换成标记下载:/path/to/document.hwp”
方法B:MCP Client SDK编程
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(
new StreamableHTTPClientTransport(new URL("http://localhost:3000/mcp"))
);
// 파일 경로로 변환 (로컬 환경)
const result = await client.callTool({
name: "convert_hwp_to_md",
arguments: { filePath: "/path/to/document.hwp" },
});
// Base64로 변환 (원격/K8s/Flowise 환경)
const result2 = await client.callTool({
name: "convert_hwp_content_to_md",
arguments: { content: base64String, filename: "document.hwp" },
});方法C:curl直接调用JSON-RPC
# 1. 세션 초기화
SESSION_ID=$(curl -si -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' \
| grep -i mcp-session-id | awk -F': ' '{print $2}' | tr -d '\r')
echo "Session: $SESSION_ID"
# 2. Initialized 알림
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
# 3. 도구 호출
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"convert_hwp_to_md","arguments":{"filePath":"/path/to/doc.hwp"}}}'两个工具的使用情况
“工具”“何时使用”“环境” |------|----------|------| | convert_hwp_to_md |MCP服务器等文件系统|本地,Docker volume mount | | convert_hwp_content_to_md |文件系统分离的环境K8s、Flowise、远程服务器|
______________________________________________________________________
LLM集成
这个MCP服务器本身就是LLM的连接层。
| 方式 | 说明 | 需要代码 |
|---|---|---|
| Claude Desktop/Cursor | 仅通过config.json设置自动启动 | 无 |
| 克劳德代码 | claude mcp add 通过命令注册 | 无 |
| Flowise | 从CustomFunction调用MCP JSON-RPC | CustomFunction代码 |
| 编程(Anthropic API) | MCP Client+Claude API组合 examples/llm-with-mcp.ts |
Anthropic Claude API+MCP集成示例
ANTHROPIC_API_KEY=sk-ant-... npx tsx examples/llm-with-mcp.ts /path/to/doc.hwp "이 문서를 요약해줘"详细代码包括: examples/llm-with-mcp.ts请参阅。
