contract-template-mcp-server 1.0.1 → 1.1.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.
Files changed (3) hide show
  1. package/README.md +24 -4
  2. package/package.json +1 -1
  3. package/src/index.js +20 -12
package/README.md CHANGED
@@ -11,6 +11,7 @@ CRM 合同模版库管理 MCP Server,为智能体(如 CodeBuddy/WorkBuddy)
11
11
  | `list_contract_templates` | 查询合同模板列表(支持分类/关键词筛选) | `GET /mcp/contract/template/list` |
12
12
  | `get_contract_template` | 获取模板详情及文件下载URL | `GET /mcp/contract/template/detail` |
13
13
  | `create_contract_template` | 在分类下创建新模板(含 v1.0 初版) | `POST /mcp/contract/template/create` |
14
+ | `upload_file_to_template_category` | 上传文件并一步创建模板(推荐) | `POST /mcp/contract/template/upload-and-create` |
14
15
 
15
16
  ## 安装与配置
16
17
 
@@ -88,6 +89,18 @@ AI: ① 先调用文件上传接口 /resource/nas-center/upload 上传文件,
88
89
  → 模板创建成功(v1.0 草稿状态)
89
90
  ```
90
91
 
92
+ ### 上传文件一步创建模板(推荐)
93
+
94
+ ```
95
+ 用户: 帮我把这个文件上传到销售合同分类下
96
+ AI: 调用 upload_file_to_template_category(filePath="/path/to/file.docx", categoryId=销售合同分类ID)
97
+ → 内部自动完成:文件读取 + 上传 NAS/OSS + 模板创建 + 版本初始化
98
+ → 模板创建成功(v1.0 草稿状态)
99
+ ```
100
+
101
+ > **性能说明**:MCP Server 与 WorkBuddy 同机运行,`upload_file_to_template_category` 直接通过 `filePath`
102
+ > 读取本地文件,无需客户端做 base64 编码,大文件上传速度大幅提升。
103
+
91
104
  ## 数据来源标记
92
105
 
93
106
  所有通过 MCP Server 创建的分类和模板,数据库 `data_source` 字段会自动标记为 `MCP_SERVER`,
@@ -95,11 +108,18 @@ AI: ① 先调用文件上传接口 /resource/nas-center/upload 上传文件,
95
108
 
96
109
  ## 文件上传说明
97
110
 
98
- 创建模板需要先上传文件获取 `fileId`。文件可通过以下方式上传:
99
- - **NAS 上传**:`POST /resource/nas-center/upload`(multipart/form-data)
100
- - **OSS 上传**:`POST /resource/oss/upload`(multipart/form-data)
111
+ ### 方式一:`upload_file_to_template_category`(推荐)
112
+
113
+ 直接传文件本地路径,MCP Server 自动完成文件读取、上传和模板创建:
114
+ - 参数 `filePath`:本地文件的绝对路径
115
+ - 参数 `fileName`:可选,不传则从路径自动提取
116
+
117
+ ### 方式二:手动分步上传
101
118
 
102
- 上传成功后返回的 `fileId`(或 `attachmentId`)即为创建模板时需要的参数。
119
+ 1. 先上传文件获取 `fileId`:
120
+ - **NAS 上传**:`POST /resource/nas-center/upload`(multipart/form-data)
121
+ - **OSS 上传**:`POST /resource/oss/upload`(multipart/form-data)
122
+ 2. 使用 `create_contract_template` 传入 `fileId` 创建模板
103
123
 
104
124
  ## 技术架构
105
125
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contract-template-mcp-server",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "MCP Server - CRM合同模版库管理,支持合同模版分类管理、合同模版管理、合同模版版本管理",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -28,6 +28,7 @@
28
28
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
29
29
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
30
30
  import { z } from "zod";
31
+ import fs from "fs";
31
32
  import {
32
33
  listCategories,
33
34
  createCategory,
@@ -41,7 +42,7 @@ import {
41
42
  // 创建 MCP Server 实例
42
43
  const server = new McpServer({
43
44
  name: "contract-template-mcp-server",
44
- version: "1.0.1",
45
+ version: "1.1.0",
45
46
  });
46
47
 
47
48
  // ============================================================
@@ -427,17 +428,18 @@ server.tool(
427
428
  "使用示例:用户说\u201C帮我把这个文件上传到销售合同分类下\u201D,智能体调用此工具即可一步完成。",
428
429
  ].join("\n"),
429
430
  {
430
- fileContent: z
431
+ filePath: z
431
432
  .string()
432
433
  .describe(
433
- "文件的 Base64 编码内容(必填)。用户选择或拖拽的文件经 Base64 编码后的字符串。" +
434
- '例如从 MCP 客户端获取到的附件内容。如果是大文件,确保使用完整的 Base64 字符串。'
434
+ "文件的本地绝对路径(必填)。由于 MCP Server WorkBuddy 运行在同一台机器上," +
435
+ "直接传文件路径即可,服务端会自动读取文件内容,无需客户端做 base64 编码。" +
436
+ "例如:\"/Users/user/Desktop/销售合同模板.docx\""
435
437
  ),
436
438
  fileName: z
437
439
  .string()
438
- .min(1)
440
+ .optional()
439
441
  .describe(
440
- "原始文件名(必填),如 \"关于长春市国资国企在线监管平台上线方案_20260506_v0.1.doc\""
442
+ "文件名(可选)。不传则从 filePath 中自动提取文件名"
441
443
  ),
442
444
  categoryId: z
443
445
  .string()
@@ -462,7 +464,7 @@ server.tool(
462
464
  .describe("创建该模板的AI模型名称(可选),用于追溯数据来源"),
463
465
  },
464
466
  async ({
465
- fileContent,
467
+ filePath,
466
468
  fileName,
467
469
  categoryId,
468
470
  categoryName,
@@ -471,12 +473,13 @@ server.tool(
471
473
  modelName,
472
474
  }) => {
473
475
  try {
474
- // Base64 解码为 Buffer
475
- const fileData = Buffer.from(fileContent, "base64");
476
+ // 直接读取本地文件(MCP Server WorkBuddy 同机运行,无需 base64 编码)
477
+ const actualFileName = fileName || filePath.split("/").pop() || "unknown";
478
+ const fileData = fs.readFileSync(filePath);
476
479
 
477
480
  const result = await uploadAndCreateTemplate({
478
481
  fileData,
479
- fileName,
482
+ fileName: actualFileName,
480
483
  categoryId,
481
484
  templateName,
482
485
  description,
@@ -491,7 +494,7 @@ server.tool(
491
494
  text: JSON.stringify(
492
495
  {
493
496
  success: true,
494
- message: `文件「${fileName}」已成功上传到${categoryName || categoryId}分类下,模板创建完成(v1.0 草稿状态)`,
497
+ message: `文件「${actualFileName}」已成功上传到${categoryName || categoryId}分类下,模板创建完成(v1.0 草稿状态)`,
495
498
  data: newTemplate
496
499
  ? {
497
500
  id: newTemplate.id ? String(newTemplate.id) : undefined,
@@ -511,6 +514,11 @@ server.tool(
511
514
  ],
512
515
  };
513
516
  } catch (error) {
517
+ let errorMessage = error.message;
518
+ // 提供更友好的文件不存在错误提示
519
+ if (error.code === "ENOENT") {
520
+ errorMessage = `文件不存在或无法访问: ${filePath}`;
521
+ }
514
522
  return {
515
523
  content: [
516
524
  {
@@ -518,7 +526,7 @@ server.tool(
518
526
  text: JSON.stringify(
519
527
  {
520
528
  success: false,
521
- message: `上传文件并创建模板失败: ${error.message}`,
529
+ message: `上传文件并创建模板失败: ${errorMessage}`,
522
530
  },
523
531
  null,
524
532
  2