@birthday8/doc-mcp 1.0.1 → 1.0.3
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 +2 -2
- package/index.js +61 -65
- package/install.js +45 -35
- package/package.json +2 -4
- package/python/docx_converter.py +1152 -428
- package/python/html_fixer.py +125 -0
- package/python/html_rules.py +570 -0
- package/python/html_validator.py +174 -0
- package/python/html_validator_strict.py +428 -0
- package/python/sample/example.html +407 -0
- package/python/sample/html_schema.py +283 -0
- package/python/server.py +233 -123
- package/python/test_error_detection.py +84 -0
- package/python/test_strict_validation.py +118 -0
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -5,48 +5,50 @@
|
|
|
5
5
|
* 通过npx运行Python MCP Server
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { spawn } = require(
|
|
9
|
-
const path = require(
|
|
10
|
-
const fs = require(
|
|
8
|
+
const { spawn } = require("child_process");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const fs = require("fs");
|
|
11
11
|
|
|
12
12
|
// Python脚本路径
|
|
13
|
-
const pythonDir = path.join(__dirname,
|
|
14
|
-
const serverScript = path.join(pythonDir,
|
|
15
|
-
const requirementsFile = path.join(pythonDir,
|
|
13
|
+
const pythonDir = path.join(__dirname, "python");
|
|
14
|
+
const serverScript = path.join(pythonDir, "server.py");
|
|
15
|
+
const requirementsFile = path.join(pythonDir, "requirements.txt");
|
|
16
16
|
|
|
17
17
|
// 检查Python是否安装
|
|
18
18
|
function checkPython() {
|
|
19
19
|
return new Promise((resolve, reject) => {
|
|
20
|
-
const pythonCommands = [
|
|
20
|
+
const pythonCommands = ["python3", "python", "py"];
|
|
21
21
|
let found = false;
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
function tryNext(index) {
|
|
24
24
|
if (index >= pythonCommands.length) {
|
|
25
|
-
reject(
|
|
25
|
+
reject(
|
|
26
|
+
new Error("Python not found. Please install Python 3.8 or higher."),
|
|
27
|
+
);
|
|
26
28
|
return;
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
|
|
29
31
|
const cmd = pythonCommands[index];
|
|
30
|
-
const check = spawn(cmd, [
|
|
31
|
-
|
|
32
|
-
check.on(
|
|
32
|
+
const check = spawn(cmd, ["--version"], { shell: true });
|
|
33
|
+
|
|
34
|
+
check.on("error", () => {
|
|
33
35
|
tryNext(index + 1);
|
|
34
36
|
});
|
|
35
|
-
|
|
36
|
-
check.stdout.on(
|
|
37
|
+
|
|
38
|
+
check.stdout.on("data", (data) => {
|
|
37
39
|
const version = data.toString().trim();
|
|
38
40
|
console.error(`[Doc Creator] Found Python: ${version}`);
|
|
39
41
|
found = true;
|
|
40
42
|
resolve(cmd);
|
|
41
43
|
});
|
|
42
|
-
|
|
43
|
-
check.on(
|
|
44
|
+
|
|
45
|
+
check.on("close", (code) => {
|
|
44
46
|
if (!found) {
|
|
45
47
|
tryNext(index + 1);
|
|
46
48
|
}
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
|
-
|
|
51
|
+
|
|
50
52
|
tryNext(0);
|
|
51
53
|
});
|
|
52
54
|
}
|
|
@@ -54,16 +56,16 @@ function checkPython() {
|
|
|
54
56
|
// 检查依赖是否已安装
|
|
55
57
|
function checkDependencies(pythonCmd) {
|
|
56
58
|
return new Promise((resolve, reject) => {
|
|
57
|
-
const check = spawn(pythonCmd, [
|
|
59
|
+
const check = spawn(pythonCmd, ["-c", "import mcp, docx, bs4"], {
|
|
58
60
|
cwd: pythonDir,
|
|
59
|
-
shell: true
|
|
61
|
+
shell: true,
|
|
60
62
|
});
|
|
61
|
-
|
|
62
|
-
check.on(
|
|
63
|
+
|
|
64
|
+
check.on("close", (code) => {
|
|
63
65
|
resolve(code === 0);
|
|
64
66
|
});
|
|
65
|
-
|
|
66
|
-
check.on(
|
|
67
|
+
|
|
68
|
+
check.on("error", () => {
|
|
67
69
|
resolve(false);
|
|
68
70
|
});
|
|
69
71
|
});
|
|
@@ -72,34 +74,29 @@ function checkDependencies(pythonCmd) {
|
|
|
72
74
|
// 安装Python依赖
|
|
73
75
|
function installDependencies(pythonCmd) {
|
|
74
76
|
return new Promise((resolve, reject) => {
|
|
75
|
-
console.error(
|
|
76
|
-
|
|
77
|
-
const install = spawn(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
install.stderr.on('data', (data) => {
|
|
89
|
-
output += data.toString();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
install.on('close', (code) => {
|
|
77
|
+
console.error("[Doc Creator] Installing Python dependencies...");
|
|
78
|
+
|
|
79
|
+
const install = spawn(
|
|
80
|
+
pythonCmd,
|
|
81
|
+
["-m", "pip", "install", "-r", requirementsFile],
|
|
82
|
+
{
|
|
83
|
+
cwd: pythonDir,
|
|
84
|
+
shell: true,
|
|
85
|
+
stdio: "pipe",
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
install.on("close", (code) => {
|
|
93
90
|
if (code === 0) {
|
|
94
|
-
console.error(
|
|
91
|
+
console.error("[Doc Creator] Dependencies installed successfully.");
|
|
95
92
|
resolve();
|
|
96
93
|
} else {
|
|
97
|
-
reject(new Error(
|
|
94
|
+
reject(new Error("Failed to install dependencies"));
|
|
98
95
|
}
|
|
99
96
|
});
|
|
100
|
-
|
|
101
|
-
install.on(
|
|
102
|
-
reject(new Error(
|
|
97
|
+
|
|
98
|
+
install.on("error", (err) => {
|
|
99
|
+
reject(new Error("Failed to run pip"));
|
|
103
100
|
});
|
|
104
101
|
});
|
|
105
102
|
}
|
|
@@ -109,46 +106,45 @@ async function startServer() {
|
|
|
109
106
|
try {
|
|
110
107
|
// 检查Python
|
|
111
108
|
const pythonCmd = await checkPython();
|
|
112
|
-
|
|
109
|
+
|
|
113
110
|
// 检查依赖
|
|
114
111
|
const depsInstalled = await checkDependencies(pythonCmd);
|
|
115
|
-
|
|
112
|
+
|
|
116
113
|
// 如果依赖未安装,尝试安装
|
|
117
114
|
if (!depsInstalled) {
|
|
118
115
|
try {
|
|
119
116
|
await installDependencies(pythonCmd);
|
|
120
117
|
} catch (err) {
|
|
121
118
|
console.error(`[Doc Creator] Warning: ${err.message}`);
|
|
122
|
-
console.error(
|
|
119
|
+
console.error("[Doc Creator] Trying to continue anyway...");
|
|
123
120
|
}
|
|
124
121
|
}
|
|
125
|
-
|
|
122
|
+
|
|
126
123
|
// 启动Python MCP Server
|
|
127
|
-
console.error(
|
|
128
|
-
|
|
124
|
+
console.error("[Doc Creator] Starting MCP Server...");
|
|
125
|
+
|
|
129
126
|
const server = spawn(pythonCmd, [serverScript], {
|
|
130
127
|
cwd: pythonDir,
|
|
131
|
-
stdio: [
|
|
128
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
132
129
|
});
|
|
133
|
-
|
|
134
|
-
server.on(
|
|
130
|
+
|
|
131
|
+
server.on("error", (err) => {
|
|
135
132
|
console.error(`[Doc Creator] Failed to start server: ${err.message}`);
|
|
136
133
|
process.exit(1);
|
|
137
134
|
});
|
|
138
|
-
|
|
139
|
-
server.on(
|
|
135
|
+
|
|
136
|
+
server.on("close", (code) => {
|
|
140
137
|
process.exit(code);
|
|
141
138
|
});
|
|
142
|
-
|
|
139
|
+
|
|
143
140
|
// 处理进程信号
|
|
144
|
-
process.on(
|
|
145
|
-
server.kill(
|
|
141
|
+
process.on("SIGINT", () => {
|
|
142
|
+
server.kill("SIGINT");
|
|
146
143
|
});
|
|
147
|
-
|
|
148
|
-
process.on(
|
|
149
|
-
server.kill(
|
|
144
|
+
|
|
145
|
+
process.on("SIGTERM", () => {
|
|
146
|
+
server.kill("SIGTERM");
|
|
150
147
|
});
|
|
151
|
-
|
|
152
148
|
} catch (err) {
|
|
153
149
|
console.error(`[Doc Creator] Error: ${err.message}`);
|
|
154
150
|
process.exit(1);
|
package/install.js
CHANGED
|
@@ -5,46 +5,48 @@
|
|
|
5
5
|
* 在安装npm包时自动安装Python依赖
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { spawn } = require(
|
|
9
|
-
const path = require(
|
|
8
|
+
const { spawn } = require("child_process");
|
|
9
|
+
const path = require("path");
|
|
10
10
|
|
|
11
|
-
const pythonDir = path.join(__dirname,
|
|
12
|
-
const requirementsFile = path.join(pythonDir,
|
|
11
|
+
const pythonDir = path.join(__dirname, "python");
|
|
12
|
+
const requirementsFile = path.join(pythonDir, "requirements.txt");
|
|
13
13
|
|
|
14
14
|
// 检查Python是否安装
|
|
15
15
|
function checkPython() {
|
|
16
16
|
return new Promise((resolve, reject) => {
|
|
17
|
-
const pythonCommands = [
|
|
17
|
+
const pythonCommands = ["python3", "python", "py"];
|
|
18
18
|
let found = false;
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
function tryNext(index) {
|
|
21
21
|
if (index >= pythonCommands.length) {
|
|
22
|
-
console.log(
|
|
22
|
+
console.log(
|
|
23
|
+
"[Doc Creator] Python not found. Will check again at runtime.",
|
|
24
|
+
);
|
|
23
25
|
resolve(null);
|
|
24
26
|
return;
|
|
25
27
|
}
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
const cmd = pythonCommands[index];
|
|
28
|
-
const check = spawn(cmd, [
|
|
29
|
-
|
|
30
|
-
check.on(
|
|
30
|
+
const check = spawn(cmd, ["--version"], { shell: true });
|
|
31
|
+
|
|
32
|
+
check.on("error", () => {
|
|
31
33
|
tryNext(index + 1);
|
|
32
34
|
});
|
|
33
|
-
|
|
34
|
-
check.stdout.on(
|
|
35
|
+
|
|
36
|
+
check.stdout.on("data", () => {
|
|
35
37
|
if (!found) {
|
|
36
38
|
found = true;
|
|
37
39
|
resolve(cmd);
|
|
38
40
|
}
|
|
39
41
|
});
|
|
40
|
-
|
|
41
|
-
check.on(
|
|
42
|
+
|
|
43
|
+
check.on("close", () => {
|
|
42
44
|
if (!found) {
|
|
43
45
|
tryNext(index + 1);
|
|
44
46
|
}
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
tryNext(0);
|
|
49
51
|
});
|
|
50
52
|
}
|
|
@@ -52,26 +54,34 @@ function checkPython() {
|
|
|
52
54
|
// 安装Python依赖
|
|
53
55
|
function installDependencies(pythonCmd) {
|
|
54
56
|
return new Promise((resolve, reject) => {
|
|
55
|
-
console.log(
|
|
56
|
-
|
|
57
|
-
const install = spawn(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
console.log("[Doc Creator] Installing Python dependencies...");
|
|
58
|
+
|
|
59
|
+
const install = spawn(
|
|
60
|
+
pythonCmd,
|
|
61
|
+
["-m", "pip", "install", "-r", requirementsFile],
|
|
62
|
+
{
|
|
63
|
+
cwd: pythonDir,
|
|
64
|
+
shell: true,
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
install.on("close", (code) => {
|
|
64
70
|
if (code === 0) {
|
|
65
|
-
console.log(
|
|
71
|
+
console.log(
|
|
72
|
+
"[Doc Creator] Python dependencies installed successfully.",
|
|
73
|
+
);
|
|
66
74
|
resolve();
|
|
67
75
|
} else {
|
|
68
|
-
console.log(
|
|
76
|
+
console.log(
|
|
77
|
+
"[Doc Creator] Failed to install dependencies. Will retry at runtime.",
|
|
78
|
+
);
|
|
69
79
|
resolve(); // 不中断安装流程
|
|
70
80
|
}
|
|
71
81
|
});
|
|
72
|
-
|
|
73
|
-
install.on(
|
|
74
|
-
console.log(
|
|
82
|
+
|
|
83
|
+
install.on("error", () => {
|
|
84
|
+
console.log("[Doc Creator] Failed to run pip. Will retry at runtime.");
|
|
75
85
|
resolve(); // 不中断安装流程
|
|
76
86
|
});
|
|
77
87
|
});
|
|
@@ -79,15 +89,15 @@ function installDependencies(pythonCmd) {
|
|
|
79
89
|
|
|
80
90
|
// 主函数
|
|
81
91
|
async function main() {
|
|
82
|
-
console.log(
|
|
83
|
-
|
|
92
|
+
console.log("[Doc Creator] Running post-install script...");
|
|
93
|
+
|
|
84
94
|
const pythonCmd = await checkPython();
|
|
85
|
-
|
|
95
|
+
|
|
86
96
|
if (pythonCmd) {
|
|
87
97
|
await installDependencies(pythonCmd);
|
|
88
98
|
}
|
|
89
|
-
|
|
90
|
-
console.log(
|
|
99
|
+
|
|
100
|
+
console.log("[Doc Creator] Post-install complete.");
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
main().catch(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@birthday8/doc-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Doc Creator MCP Server - Generate Word documents from HTML",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,8 +27,6 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"index.js",
|
|
29
29
|
"install.js",
|
|
30
|
-
"python
|
|
31
|
-
"python/docx_converter.py",
|
|
32
|
-
"python/requirements.txt"
|
|
30
|
+
"python/**/*"
|
|
33
31
|
]
|
|
34
32
|
}
|