@birthday8/doc-mcp 1.0.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.
- package/README.md +137 -0
- package/index.js +159 -0
- package/install.js +96 -0
- package/package.json +32 -0
- package/python/__pycache__/docx_converter.cpython-313.pyc +0 -0
- package/python/docx_converter.py +807 -0
- package/python/requirements.txt +4 -0
- package/python/server.py +320 -0
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# @doc-creator/mcp-server
|
|
2
|
+
|
|
3
|
+
Doc Creator MCP Server - Generate Word documents from HTML with rich formatting support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ Text formatting (bold, italic, underline, strikethrough)
|
|
8
|
+
- ✅ Colors and background highlighting
|
|
9
|
+
- ✅ Headings (H1-H6)
|
|
10
|
+
- ✅ Paragraph indentation (em units)
|
|
11
|
+
- ✅ Lists (ordered/unordered/nested)
|
|
12
|
+
- ✅ Tables with styles
|
|
13
|
+
- ✅ Info/Warning/Success boxes
|
|
14
|
+
- ✅ Code blocks
|
|
15
|
+
- ✅ Blockquotes
|
|
16
|
+
- ✅ Multi-column layout
|
|
17
|
+
- ✅ Page breaks
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
No installation required! Just configure your MCP client.
|
|
22
|
+
|
|
23
|
+
## MCP Configuration
|
|
24
|
+
|
|
25
|
+
Add to your MCP client configuration:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"mcpServers": {
|
|
30
|
+
"doc-creator": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "@doc-creator/mcp-server"]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Requirements
|
|
39
|
+
|
|
40
|
+
- Node.js 14+
|
|
41
|
+
- Python 3.8+ (will be checked automatically)
|
|
42
|
+
|
|
43
|
+
## Available Tools
|
|
44
|
+
|
|
45
|
+
### 1. convert_document
|
|
46
|
+
Convert an existing HTML file to Word document.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"html_path": "/path/to/document.html",
|
|
51
|
+
"output_path": "/path/to/output.docx"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. generate_document
|
|
56
|
+
Generate a Word document from HTML content.
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"title": "My Document",
|
|
61
|
+
"content": "<h2>Section 1</h2><p>Content here...</p>",
|
|
62
|
+
"output_dir": "/optional/output/directory"
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. get_html_template
|
|
67
|
+
Get the HTML template with CSS styles.
|
|
68
|
+
|
|
69
|
+
## HTML Conventions
|
|
70
|
+
|
|
71
|
+
### Basic Structure
|
|
72
|
+
```html
|
|
73
|
+
<!DOCTYPE html>
|
|
74
|
+
<html lang="zh-CN">
|
|
75
|
+
<head>
|
|
76
|
+
<meta charset="UTF-8">
|
|
77
|
+
<title>Document Title</title>
|
|
78
|
+
<style>
|
|
79
|
+
/* CSS styles */
|
|
80
|
+
</style>
|
|
81
|
+
</head>
|
|
82
|
+
<body>
|
|
83
|
+
<h1>Title</h1>
|
|
84
|
+
<p>Content with <strong>bold</strong> and <em>italic</em>.</p>
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Text Formatting
|
|
90
|
+
```html
|
|
91
|
+
<strong>Bold</strong>
|
|
92
|
+
<em>Italic</em>
|
|
93
|
+
<u>Underline</u>
|
|
94
|
+
<s>Strikethrough</s>
|
|
95
|
+
<span class="red">Red text</span>
|
|
96
|
+
<span class="highlight">Highlighted</span>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Paragraph Indentation
|
|
100
|
+
```html
|
|
101
|
+
<p data-indent="2">This paragraph has 2em first-line indent</p>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Info Boxes
|
|
105
|
+
```html
|
|
106
|
+
<div class="info">Information message</div>
|
|
107
|
+
<div class="warning">Warning message</div>
|
|
108
|
+
<div class="success">Success message</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Tables
|
|
112
|
+
```html
|
|
113
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
114
|
+
<thead>
|
|
115
|
+
<tr>
|
|
116
|
+
<th style="border: 1px solid #ddd; padding: 12px;">Header</th>
|
|
117
|
+
</tr>
|
|
118
|
+
</thead>
|
|
119
|
+
<tbody>
|
|
120
|
+
<tr>
|
|
121
|
+
<td style="border: 1px solid #ddd; padding: 12px;">Cell</td>
|
|
122
|
+
</tr>
|
|
123
|
+
</tbody>
|
|
124
|
+
</table>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Multi-Column Layout
|
|
128
|
+
```html
|
|
129
|
+
<div class="columns" data-cols="2">
|
|
130
|
+
<p>Column 1 content...</p>
|
|
131
|
+
<p>Column 2 content...</p>
|
|
132
|
+
</div>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Doc Creator MCP Server - Entry Point
|
|
5
|
+
* 通过npx运行Python MCP Server
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
|
|
12
|
+
// Python脚本路径
|
|
13
|
+
const pythonDir = path.join(__dirname, 'python');
|
|
14
|
+
const serverScript = path.join(pythonDir, 'server.py');
|
|
15
|
+
const requirementsFile = path.join(pythonDir, 'requirements.txt');
|
|
16
|
+
|
|
17
|
+
// 检查Python是否安装
|
|
18
|
+
function checkPython() {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const pythonCommands = ['python3', 'python', 'py'];
|
|
21
|
+
let found = false;
|
|
22
|
+
|
|
23
|
+
function tryNext(index) {
|
|
24
|
+
if (index >= pythonCommands.length) {
|
|
25
|
+
reject(new Error('Python not found. Please install Python 3.8 or higher.'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const cmd = pythonCommands[index];
|
|
30
|
+
const check = spawn(cmd, ['--version'], { shell: true });
|
|
31
|
+
|
|
32
|
+
check.on('error', () => {
|
|
33
|
+
tryNext(index + 1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
check.stdout.on('data', (data) => {
|
|
37
|
+
const version = data.toString().trim();
|
|
38
|
+
console.error(`[Doc Creator] Found Python: ${version}`);
|
|
39
|
+
found = true;
|
|
40
|
+
resolve(cmd);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
check.on('close', (code) => {
|
|
44
|
+
if (!found) {
|
|
45
|
+
tryNext(index + 1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
tryNext(0);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 检查依赖是否已安装
|
|
55
|
+
function checkDependencies(pythonCmd) {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const check = spawn(pythonCmd, ['-c', 'import mcp, docx, bs4'], {
|
|
58
|
+
cwd: pythonDir,
|
|
59
|
+
shell: true
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
check.on('close', (code) => {
|
|
63
|
+
resolve(code === 0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
check.on('error', () => {
|
|
67
|
+
resolve(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 安装Python依赖
|
|
73
|
+
function installDependencies(pythonCmd) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
console.error('[Doc Creator] Installing Python dependencies...');
|
|
76
|
+
|
|
77
|
+
const install = spawn(pythonCmd, ['-m', 'pip', 'install', '-r', requirementsFile], {
|
|
78
|
+
cwd: pythonDir,
|
|
79
|
+
shell: true,
|
|
80
|
+
stdio: 'pipe'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
let output = '';
|
|
84
|
+
install.stdout.on('data', (data) => {
|
|
85
|
+
output += data.toString();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
install.stderr.on('data', (data) => {
|
|
89
|
+
output += data.toString();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
install.on('close', (code) => {
|
|
93
|
+
if (code === 0) {
|
|
94
|
+
console.error('[Doc Creator] Dependencies installed successfully.');
|
|
95
|
+
resolve();
|
|
96
|
+
} else {
|
|
97
|
+
reject(new Error(`Failed to install dependencies: ${output}`));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
install.on('error', (err) => {
|
|
102
|
+
reject(new Error(`Failed to run pip: ${err.message}`));
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 启动MCP Server
|
|
108
|
+
async function startServer() {
|
|
109
|
+
try {
|
|
110
|
+
// 检查Python
|
|
111
|
+
const pythonCmd = await checkPython();
|
|
112
|
+
|
|
113
|
+
// 检查依赖
|
|
114
|
+
const depsInstalled = await checkDependencies(pythonCmd);
|
|
115
|
+
|
|
116
|
+
// 如果依赖未安装,尝试安装
|
|
117
|
+
if (!depsInstalled) {
|
|
118
|
+
try {
|
|
119
|
+
await installDependencies(pythonCmd);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error(`[Doc Creator] Warning: ${err.message}`);
|
|
122
|
+
console.error('[Doc Creator] Trying to continue anyway...');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 启动Python MCP Server
|
|
127
|
+
console.error('[Doc Creator] Starting MCP Server...');
|
|
128
|
+
|
|
129
|
+
const server = spawn(pythonCmd, [serverScript], {
|
|
130
|
+
cwd: pythonDir,
|
|
131
|
+
stdio: ['inherit', 'inherit', 'inherit']
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
server.on('error', (err) => {
|
|
135
|
+
console.error(`[Doc Creator] Failed to start server: ${err.message}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
server.on('close', (code) => {
|
|
140
|
+
process.exit(code);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// 处理进程信号
|
|
144
|
+
process.on('SIGINT', () => {
|
|
145
|
+
server.kill('SIGINT');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
process.on('SIGTERM', () => {
|
|
149
|
+
server.kill('SIGTERM');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.error(`[Doc Creator] Error: ${err.message}`);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 启动服务器
|
|
159
|
+
startServer();
|
package/install.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Doc Creator MCP Server - Post-install Script
|
|
5
|
+
* 在安装npm包时自动安装Python依赖
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const pythonDir = path.join(__dirname, 'python');
|
|
12
|
+
const requirementsFile = path.join(pythonDir, 'requirements.txt');
|
|
13
|
+
|
|
14
|
+
// 检查Python是否安装
|
|
15
|
+
function checkPython() {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const pythonCommands = ['python3', 'python', 'py'];
|
|
18
|
+
let found = false;
|
|
19
|
+
|
|
20
|
+
function tryNext(index) {
|
|
21
|
+
if (index >= pythonCommands.length) {
|
|
22
|
+
console.log('[Doc Creator] Python not found. Will check again at runtime.');
|
|
23
|
+
resolve(null);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const cmd = pythonCommands[index];
|
|
28
|
+
const check = spawn(cmd, ['--version'], { shell: true });
|
|
29
|
+
|
|
30
|
+
check.on('error', () => {
|
|
31
|
+
tryNext(index + 1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
check.stdout.on('data', () => {
|
|
35
|
+
if (!found) {
|
|
36
|
+
found = true;
|
|
37
|
+
resolve(cmd);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
check.on('close', () => {
|
|
42
|
+
if (!found) {
|
|
43
|
+
tryNext(index + 1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
tryNext(0);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 安装Python依赖
|
|
53
|
+
function installDependencies(pythonCmd) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
console.log('[Doc Creator] Installing Python dependencies...');
|
|
56
|
+
|
|
57
|
+
const install = spawn(pythonCmd, ['-m', 'pip', 'install', '-r', requirementsFile], {
|
|
58
|
+
cwd: pythonDir,
|
|
59
|
+
shell: true,
|
|
60
|
+
stdio: 'inherit'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
install.on('close', (code) => {
|
|
64
|
+
if (code === 0) {
|
|
65
|
+
console.log('[Doc Creator] Python dependencies installed successfully.');
|
|
66
|
+
resolve();
|
|
67
|
+
} else {
|
|
68
|
+
console.log('[Doc Creator] Failed to install dependencies. Will retry at runtime.');
|
|
69
|
+
resolve(); // 不中断安装流程
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
install.on('error', () => {
|
|
74
|
+
console.log('[Doc Creator] Failed to run pip. Will retry at runtime.');
|
|
75
|
+
resolve(); // 不中断安装流程
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 主函数
|
|
81
|
+
async function main() {
|
|
82
|
+
console.log('[Doc Creator] Running post-install script...');
|
|
83
|
+
|
|
84
|
+
const pythonCmd = await checkPython();
|
|
85
|
+
|
|
86
|
+
if (pythonCmd) {
|
|
87
|
+
await installDependencies(pythonCmd);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log('[Doc Creator] Post-install complete.');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
main().catch(() => {
|
|
94
|
+
// 安装失败不中断npm install
|
|
95
|
+
process.exit(0);
|
|
96
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@birthday8/doc-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Doc Creator MCP Server - Generate Word documents from HTML",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"doc-creator-mcp": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node install.js",
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"mcp-server",
|
|
16
|
+
"docx",
|
|
17
|
+
"word",
|
|
18
|
+
"document",
|
|
19
|
+
"html",
|
|
20
|
+
"converter"
|
|
21
|
+
],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=14.0.0"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"index.js",
|
|
29
|
+
"install.js",
|
|
30
|
+
"python/"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
Binary file
|