@8btc/ppt-generator-mcp 0.0.1

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 (39) hide show
  1. package/README.md +129 -0
  2. package/dist/export-pptx.d.ts +6 -0
  3. package/dist/export-pptx.js +876 -0
  4. package/dist/generate-ppt-slides.d.ts +10 -0
  5. package/dist/generate-ppt-slides.js +581 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +161 -0
  8. package/dist/ppt-generator.d.ts +39 -0
  9. package/dist/ppt-generator.js +110 -0
  10. package/dist/tpls/imgs.json +482 -0
  11. package/dist/tpls/tpl-1.json +7649 -0
  12. package/dist/tpls/tpl-2.json +7455 -0
  13. package/dist/tpls/tpl-3.json +8184 -0
  14. package/dist/tpls/tpl-4.json +8352 -0
  15. package/dist/types/outline.d.ts +36 -0
  16. package/dist/types/outline.js +2 -0
  17. package/dist/types/slide.d.ts +696 -0
  18. package/dist/types/slide.js +2 -0
  19. package/dist/utils/element.d.ts +94 -0
  20. package/dist/utils/element.js +239 -0
  21. package/dist/utils/htmlParser/format.d.ts +3 -0
  22. package/dist/utils/htmlParser/format.js +47 -0
  23. package/dist/utils/htmlParser/index.d.ts +4 -0
  24. package/dist/utils/htmlParser/index.js +15 -0
  25. package/dist/utils/htmlParser/lexer.d.ts +2 -0
  26. package/dist/utils/htmlParser/lexer.js +245 -0
  27. package/dist/utils/htmlParser/parser.d.ts +15 -0
  28. package/dist/utils/htmlParser/parser.js +117 -0
  29. package/dist/utils/htmlParser/stringify.d.ts +3 -0
  30. package/dist/utils/htmlParser/stringify.js +32 -0
  31. package/dist/utils/htmlParser/tags.d.ts +8 -0
  32. package/dist/utils/htmlParser/tags.js +50 -0
  33. package/dist/utils/htmlParser/types.d.ts +55 -0
  34. package/dist/utils/htmlParser/types.js +2 -0
  35. package/dist/utils/svg2Base64.d.ts +1 -0
  36. package/dist/utils/svg2Base64.js +58 -0
  37. package/dist/utils/svgPathParser.d.ts +120 -0
  38. package/dist/utils/svgPathParser.js +145 -0
  39. package/package.json +59 -0
package/dist/index.js ADDED
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
7
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
8
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
9
+ const ppt_generator_js_1 = require("./ppt-generator.js");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const zod_1 = require("zod");
12
+ const fs_extra_1 = __importDefault(require("fs-extra"));
13
+ const package_json_1 = __importDefault(require("../package.json"));
14
+ class PPTGeneratorMCPServer {
15
+ constructor() {
16
+ this.server = new mcp_js_1.McpServer({
17
+ name: "ppt-generator",
18
+ version: "0.1.0",
19
+ }, {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ });
24
+ this.pptGenerator = new ppt_generator_js_1.PPTGenerator();
25
+ this.setupToolHandlers();
26
+ }
27
+ setupToolHandlers() {
28
+ this.server.registerTool("get_ppt_template_list", {
29
+ title: "ppt模板列表",
30
+ description: "获取可使用的ppt模板",
31
+ }, async () => {
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text",
36
+ text: JSON.stringify([
37
+ {
38
+ name: "清新风格模板-图标比较多",
39
+ path: node_path_1.default.join(__dirname, "tpls", "tpl-3.json"),
40
+ },
41
+ {
42
+ name: "研究报告风格模板-紫色系",
43
+ path: node_path_1.default.join(__dirname, "tpls", "tpl-4.json"),
44
+ },
45
+ {
46
+ name: "简约风格模板-莫兰迪色系",
47
+ path: node_path_1.default.join(__dirname, "tpls", "tpl-2.json"),
48
+ },
49
+ {
50
+ name: "简单模板-蓝色调",
51
+ path: node_path_1.default.join(__dirname, "tpls", "tpl-1.json"),
52
+ },
53
+ ]),
54
+ },
55
+ ],
56
+ };
57
+ });
58
+ this.server.registerTool("generate_ppt", {
59
+ title: "ppt生成工具",
60
+ description: "根据大纲自动匹配模板生成PPT文件",
61
+ inputSchema: {
62
+ templateFilePath: zod_1.z.string().optional(),
63
+ outputPath: zod_1.z.string().optional(),
64
+ outline: zod_1.z.array(zod_1.z.discriminatedUnion("type", [
65
+ zod_1.z.object({
66
+ type: zod_1.z.literal("cover"),
67
+ data: zod_1.z.object({
68
+ title: zod_1.z.string(),
69
+ text: zod_1.z.string(),
70
+ }),
71
+ }),
72
+ zod_1.z.object({
73
+ type: zod_1.z.literal("contents"),
74
+ data: zod_1.z.object({
75
+ items: zod_1.z.array(zod_1.z.string()),
76
+ }),
77
+ offset: zod_1.z.number().optional(),
78
+ }),
79
+ zod_1.z.object({
80
+ type: zod_1.z.literal("transition"),
81
+ data: zod_1.z.object({
82
+ title: zod_1.z.string(),
83
+ text: zod_1.z.string(),
84
+ }),
85
+ }),
86
+ zod_1.z.object({
87
+ type: zod_1.z.literal("content"),
88
+ data: zod_1.z.object({
89
+ title: zod_1.z.string(),
90
+ items: zod_1.z.array(zod_1.z.object({
91
+ title: zod_1.z.string(),
92
+ text: zod_1.z.string(),
93
+ })),
94
+ }),
95
+ }),
96
+ zod_1.z.object({
97
+ type: zod_1.z.literal("end"),
98
+ }),
99
+ ])),
100
+ },
101
+ }, async ({ outline, templateFilePath, outputPath }) => {
102
+ if (!templateFilePath) {
103
+ templateFilePath = node_path_1.default.join(__dirname, "tpls", "tpl-2.json");
104
+ }
105
+ if (!outputPath) {
106
+ outputPath = node_path_1.default.join(__dirname, "..", "output");
107
+ }
108
+ try {
109
+ fs_extra_1.default.ensureDirSync(outputPath);
110
+ // 保存result.json
111
+ await fs_extra_1.default.writeJson(node_path_1.default.join(outputPath, "outline.json"), outline, {
112
+ spaces: 2,
113
+ });
114
+ const result = await this.pptGenerator.generateResultJson({
115
+ outline: outline,
116
+ templateFilePath: templateFilePath,
117
+ outputPath: node_path_1.default.join(outputPath, "result.json"),
118
+ });
119
+ if (!result) {
120
+ console.error("generate_result_json 生成 result.json 失败");
121
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, "生成result.json失败");
122
+ }
123
+ const resp = await this.pptGenerator.generatePPTFromResult({
124
+ result,
125
+ outputPath: node_path_1.default.join(outputPath, "result.pptx"),
126
+ });
127
+ return {
128
+ content: [
129
+ {
130
+ type: "text",
131
+ text: JSON.stringify(resp, null, 2),
132
+ },
133
+ {
134
+ type: "resource_link",
135
+ uri: `file:///${node_path_1.default.join(outputPath, "result.pptx")}`,
136
+ name: "result.pptx",
137
+ description: "生成的PPT",
138
+ mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
139
+ annotations: {
140
+ audience: ["assistant"],
141
+ priority: 0.9,
142
+ },
143
+ },
144
+ ],
145
+ };
146
+ }
147
+ catch (err) {
148
+ console.error(err);
149
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, "生成PPT失败");
150
+ }
151
+ });
152
+ }
153
+ async run() {
154
+ const transport = new stdio_js_1.StdioServerTransport();
155
+ await this.server.connect(transport);
156
+ console.error("PPT Generator MCP server running on stdio");
157
+ console.error(`VERSION ${package_json_1.default.version}`);
158
+ }
159
+ }
160
+ const server = new PPTGeneratorMCPServer();
161
+ server.run().catch(console.error);
@@ -0,0 +1,39 @@
1
+ import { Outline } from "./types/outline";
2
+ import { Slide } from "./types/slide";
3
+ interface IResult {
4
+ title: string;
5
+ width: number;
6
+ height: number;
7
+ theme: any;
8
+ slides: Slide[];
9
+ }
10
+ export declare class PPTGenerator {
11
+ /**
12
+ * 列出可用的模板
13
+ */
14
+ listTemplates(templateDir?: string): Promise<{
15
+ templates: string[];
16
+ defaultDir: string;
17
+ }>;
18
+ /**
19
+ * 两步生成PPT - 第一步:生成result.json
20
+ */
21
+ generateResultJson(params: {
22
+ outline: Outline[];
23
+ templateFilePath: string;
24
+ outputPath: string;
25
+ title?: string;
26
+ }): Promise<IResult | undefined>;
27
+ /**
28
+ * 两步生成PPT - 第二步:从result.json生成PPT
29
+ */
30
+ generatePPTFromResult(params: {
31
+ result: IResult;
32
+ outputPath: string;
33
+ }): Promise<{
34
+ success: boolean;
35
+ outputPath?: string;
36
+ message: string;
37
+ }>;
38
+ }
39
+ export {};
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PPTGenerator = void 0;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const posix_1 = __importDefault(require("node:path/posix"));
9
+ const export_pptx_1 = require("./export-pptx");
10
+ const generate_ppt_slides_1 = require("./generate-ppt-slides");
11
+ class PPTGenerator {
12
+ /**
13
+ * 列出可用的模板
14
+ */
15
+ async listTemplates(templateDir) {
16
+ const defaultDir = templateDir || posix_1.default.join(__dirname, "../../data");
17
+ const templates = [];
18
+ try {
19
+ if (await fs_extra_1.default.pathExists(defaultDir)) {
20
+ const files = await fs_extra_1.default.readdir(defaultDir);
21
+ const templateFiles = files.filter((file) => file.startsWith("tpl-") && file.endsWith(".json"));
22
+ templates.push(...templateFiles);
23
+ }
24
+ }
25
+ catch (error) {
26
+ console.warn(`无法读取模板目录 ${defaultDir}:`, error);
27
+ }
28
+ return {
29
+ templates,
30
+ defaultDir,
31
+ };
32
+ }
33
+ /**
34
+ * 两步生成PPT - 第一步:生成result.json
35
+ */
36
+ async generateResultJson(params) {
37
+ try {
38
+ const { outline, templateFilePath, outputPath } = params;
39
+ // 读取模板文件
40
+ const templateData = await fs_extra_1.default.readJson(templateFilePath);
41
+ // 使用AIPPT函数生成slides
42
+ const generatedSlides = (0, generate_ppt_slides_1.generatePPTSlides)(templateData.slides, outline);
43
+ // 构建完整的result对象,包含模板的其他属性
44
+ const resultData = {
45
+ title: templateData.title,
46
+ width: templateData.width,
47
+ height: templateData.height,
48
+ theme: templateData.theme,
49
+ slides: generatedSlides,
50
+ };
51
+ // 生成输出路径
52
+ const resultPath = outputPath;
53
+ // 保存result.json
54
+ await fs_extra_1.default.writeJson(resultPath, resultData, { spaces: 2 });
55
+ return resultData;
56
+ }
57
+ catch (error) {
58
+ console.error("generateResultJson catch: ", error);
59
+ throw error;
60
+ }
61
+ }
62
+ /**
63
+ * 两步生成PPT - 第二步:从result.json生成PPT
64
+ */
65
+ async generatePPTFromResult(params) {
66
+ try {
67
+ const { result: resultData, outputPath } = params;
68
+ // 构造导出选项
69
+ const options = {
70
+ title: resultData.title || "Generated Presentation",
71
+ author: "PPT Generator",
72
+ subject: "Auto-generated presentation",
73
+ keywords: "presentation, auto-generated",
74
+ };
75
+ // 构造完整的导出选项
76
+ const exportOptions = {
77
+ slides: resultData.slides,
78
+ theme: resultData.theme || {
79
+ backgroundColor: "#ffffff",
80
+ fontColor: "#333333",
81
+ fontName: "Arial",
82
+ themeColors: ["#1f4e79", "#0f2537"],
83
+ outline: { width: 1, color: "#000000" },
84
+ shadow: { h: 0, v: 0, blur: 0, color: "#000000" },
85
+ },
86
+ viewportRatio: (resultData.width || 1920) / (resultData.height || 1080),
87
+ title: resultData.title || "Generated Presentation",
88
+ viewportSize: resultData.width || 1920,
89
+ };
90
+ // 使用exportPPTX生成PPT
91
+ const pptx = (0, export_pptx_1.exportPPTX)(resultData.slides, false, exportOptions);
92
+ // 确定输出路径
93
+ const finalOutputPath = outputPath;
94
+ // 确保输出目录存在
95
+ await fs_extra_1.default.ensureDir(posix_1.default.dirname(finalOutputPath));
96
+ // 保存PPT文件
97
+ await pptx.writeFile({ fileName: finalOutputPath });
98
+ return {
99
+ success: true,
100
+ outputPath: finalOutputPath,
101
+ message: `PPT文件生成成功: ${finalOutputPath}`,
102
+ };
103
+ }
104
+ catch (error) {
105
+ console.error(`从result.json生成PPT失败: ${error.message}`);
106
+ throw error;
107
+ }
108
+ }
109
+ }
110
+ exports.PPTGenerator = PPTGenerator;