dingtalk-mcp 1.1.3 → 1.1.5

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  # 钉钉MCP Server
2
2
 
3
3
 
4
+
4
5
  ## 🚀 功能特性
5
6
  - 钉钉通讯录
6
7
  - 钉钉部门管理
@@ -12,6 +13,8 @@
12
13
  - 钉钉工作通知
13
14
  - 钉钉应用管理
14
15
  - 钉钉服务窗
16
+ - 钉钉项目管理
17
+ - 钉钉日志
15
18
 
16
19
  ## 如何使用
17
20
  ```json
@@ -37,18 +40,20 @@
37
40
  2. DINGTALK_Client_Secret
38
41
  3. ACTIVE_PROFILES,激活哪些钉钉MCP服务,逗号风格,如果是ALL则激活全部。可选集合
39
42
 
40
- | ProfileId | Description | Permission |
41
- |--------------------------|--------------------|-------------------------------------------------|
42
- | dingtalk-contacts | 钉钉通讯录,默认激活 |
43
- | dingtalk-department | 钉钉部门管理 |
44
- | dingtalk-robot-send-message | 钉钉机器人发消息/DING,默认激活 | 需要企业内机器人发送消息权限 |
45
- | dingtalk-honor | 钉钉企业文化荣誉 |
46
- | dingtalk-tasks | 钉钉待办 | Todo.Todo.Write<br>Todo.Todo.Read |
47
- | dingtalk-calendar | 钉钉日程 |
48
- | dingtalk-checkin | 钉钉签到 |
49
- | dingtalk-notice | 钉钉工作通知 |
50
- | dingtalk-app-manage | 钉钉应用管理 | qyapi_microapp_manage<br>qyapi_get_microapp_list |
51
- | dingtalk-service-window | 钉钉服务窗 | |
43
+ | ProfileId | Description | Permission |
44
+ |-----------------------------|--------------------|--------------------------------------------------|
45
+ | dingtalk-contacts | 钉钉通讯录,默认激活 | qyapi_addresslist_search qyapi_get_member
46
+ | dingtalk-department | 钉钉部门管理 |qyapi_get_department_list qyapi_get_department_member
47
+ | dingtalk-robot-send-message | 钉钉机器人发消息/DING,默认激活 | 需要企业内机器人发送消息权限 <br/>Premium.Ding.Write |
48
+ | dingtalk-honor | 钉钉企业文化荣誉 |OrgCulture.Honor.Read OrgCulture.Honor.Read
49
+ | dingtalk-tasks | 钉钉待办 | Todo.Todo.Write<br>Todo.Todo.Read |
50
+ | dingtalk-calendar | 钉钉日程 |Calendar.Event.Write Calendar.Event.Read Calendar.EventSchedule.Read
51
+ | dingtalk-checkin | 钉钉签到 |qyapi_checkin_read
52
+ | dingtalk-notice | 钉钉工作通知 |
53
+ | dingtalk-app-manage | 钉钉应用管理 | qyapi_microapp_manage<br>qyapi_get_microapp_list |
54
+ | dingtalk-service-window | 钉钉服务窗 | OfficialAccount.Message.Send OfficialAccount.Contact.Read OfficialAccount.Account.Read |
55
+ | dingtalk-teambition | 钉钉项目管理 | Project.Project.Write.All Project.Project.Read.All Project.Task.Write.All Project.Task.Read.All |
56
+ | dingtalk-report | 钉钉日志 | qyapi_report_statistics qyapi_report_manage qyapi_report_query |
52
57
 
53
58
  4. ROBOT_CODE,用于发消息/DING的机器人Code
54
59
  5. ROBOT_ACCESS_TOKEN,群自定义机器人ACCESS_TOKEN,用于自定义机器人发消息
@@ -0,0 +1,423 @@
1
+ server:
2
+ name: dingtalk-report
3
+ description: 钉钉日志
4
+ tools:
5
+ - name: createReport
6
+ description: |
7
+ 创建并发送工作日志到指定接收人。
8
+
9
+ 【重要提示】contents参数格式复杂,必须严格按照以下格式构造:
10
+
11
+ 1. 每个content对象必须包含5个字段:content_type, sort, type, content, key
12
+ 2. content_type固定为"markdown"
13
+ 3. sort和type的值需要从getTemplateDetail接口获取
14
+ 4. key为字段名称,content为实际填写的内容
15
+
16
+ 【使用流程】
17
+ 1. 先调用getTemplateDetail获取模板字段信息
18
+ 2. 根据返回的fields构造contents数组
19
+ 3. 调用本接口创建日志
20
+
21
+ 【完整示例】
22
+ 对于"空白日志"模板:
23
+ {
24
+ "template_id": "1740b290d90f07517b0d3b14da2b4b7b",
25
+ "contents": [
26
+ {
27
+ "content_type": "markdown",
28
+ "sort": 0,
29
+ "type": 1,
30
+ "content": "今天完成了项目开发工作",
31
+ "key": "内容"
32
+ }
33
+ ],
34
+ "userid": "0420131813787933",
35
+ "to_chat": true,
36
+ "dd_from": "MCP_ASSISTANT",
37
+ "to_userids": ["0420131813787933"]
38
+ }
39
+
40
+ 【常见参数组合】
41
+ - 发送给自己:to_userids=["自己的userid"], to_chat=true
42
+ - 发送给他人:to_userids=["他人userid1", "他人userid2"], to_chat=true
43
+ - 发送到群:to_cids=["群id1"], to_chat=false
44
+ requestTemplate:
45
+ method: POST
46
+ url: https://oapi.dingtalk.com/topapi/report/create
47
+ args:
48
+ - name: template_id
49
+ type: string
50
+ required: true
51
+ position: body
52
+ description: |
53
+ 模板ID,从getTemplateDetail接口的result.id字段获取。
54
+ 示例值:"1740b290d90f07517b0d3b14da2b4b7b"
55
+ - name: contents
56
+ type: array
57
+ required: true
58
+ position: body
59
+ description: |
60
+ 日志内容数组,必须严格按照以下JSON Schema构造:
61
+
62
+ 每个数组元素是一个对象,包含以下必需字段:
63
+ - content_type: 固定值"markdown"
64
+ - sort: 数字,字段排序(从模板详情获取)
65
+ - type: 数字,字段类型(从模板详情获取,通常为1)
66
+ - content: 字符串,实际填写的内容,支持Markdown格式,最长1000字符
67
+ - key: 字符串,字段名称(从模板详情的field_name获取)
68
+
69
+ 构造方法:
70
+ 1. 调用getTemplateDetail获取模板fields
71
+ 2. 对于每个field,创建一个content对象:
72
+ {
73
+ "content_type": "markdown",
74
+ "sort": field.sort,
75
+ "type": field.type,
76
+ "content": "你要填写的内容",
77
+ "key": field.field_name
78
+ }
79
+ items:
80
+ type: object
81
+ required:
82
+ - content_type
83
+ - sort
84
+ - type
85
+ - content
86
+ - key
87
+ properties:
88
+ content_type:
89
+ type: string
90
+ enum: ["markdown"]
91
+ description: 内容类型,固定值"markdown"
92
+ sort:
93
+ type: number
94
+ description: 字段排序序号,必须从getTemplateDetail的result.fields[].sort获取
95
+ type:
96
+ type: number
97
+ description: 字段类型,必须从getTemplateDetail的result.fields[].type获取(1=文本类型)
98
+ content:
99
+ type: string
100
+ maxLength: 1000
101
+ description: 实际填写的内容,支持Markdown语法,最长1000字符
102
+ key:
103
+ type: string
104
+ description: 字段名称,必须从getTemplateDetail的result.fields[].field_name获取
105
+ - name: userid
106
+ type: string
107
+ required: true
108
+ position: body
109
+ description: |
110
+ 创建日志的员工userId。
111
+ 示例值:"0420131813787933"
112
+ - name: to_userids
113
+ type: array
114
+ required: false
115
+ position: body
116
+ description: |
117
+ 日志发送到的员工userId列表(可选)。
118
+ 如果不指定,日志只保存不发送。
119
+ 示例值:["0420131813787933", "其他userid"]
120
+ items:
121
+ type: string
122
+ description: 员工的userId
123
+ - name: to_chat
124
+ type: boolean
125
+ required: true
126
+ position: body
127
+ description: |
128
+ 发送日志到员工时是否发送单聊消息。
129
+ - true: 发送日志消息给指定用户
130
+ - false: 不单独发送消息
131
+ 通常设置为true以确保接收人能收到通知。
132
+ - name: to_cids
133
+ type: array
134
+ required: false
135
+ position: body
136
+ description: |
137
+ 日志要发送到的群ID列表(可选)。
138
+ 注意:群必须是在日志模板中预先配置好的接收群。
139
+ 示例值:["群id1", "群id2"]
140
+ items:
141
+ type: string
142
+ description: 群聊的ID
143
+ - name: dd_from
144
+ type: string
145
+ required: true
146
+ position: body
147
+ description: |
148
+ 日志来源标识,自定义的唯一来源标识。
149
+ 建议使用有意义的标识,如"MCP_ASSISTANT"、"AUTO_REPORT"等。
150
+ 示例值:"MCP_ASSISTANT"
151
+
152
+ - name: saveReportDraft
153
+ description: |
154
+ 保存日志内容供后续编辑和发送(草稿功能)。
155
+
156
+ 此接口用于保存日志内容但不立即发送,可以后续在钉钉中编辑和发送。
157
+ contents参数格式与createLog相同,必须包含完整的字段结构。
158
+
159
+ 【使用场景】
160
+ - 需要保存日志但暂不发送
161
+ - 创建模板供后续使用
162
+ - 批量准备多个日志内容
163
+
164
+ 【参数格式】与createLog的contents参数完全相同
165
+ requestTemplate:
166
+ method: POST
167
+ url: https://oapi.dingtalk.com/topapi/report/savecontent
168
+ args:
169
+ - name: template_id
170
+ type: string
171
+ required: true
172
+ position: body
173
+ description: |
174
+ 模板ID,从getTemplateDetail接口的result.id字段获取。
175
+ 示例值:"1740b290d90f07517b0d3b14da2b4b7b"
176
+ - name: contents
177
+ type: array
178
+ required: true
179
+ position: body
180
+ description: |
181
+ 日志内容数组,格式与createLog接口的contents参数完全相同。
182
+
183
+ 每个数组元素必须包含:
184
+ - content_type: "markdown"
185
+ - sort: 从模板详情获取的字段排序
186
+ - type: 从模板详情获取的字段类型
187
+ - content: 实际内容
188
+ - key: 字段名称
189
+ items:
190
+ type: object
191
+ required:
192
+ - content_type
193
+ - sort
194
+ - type
195
+ - content
196
+ - key
197
+ properties:
198
+ content_type:
199
+ type: string
200
+ enum: ["markdown"]
201
+ description: 内容类型,固定值"markdown"
202
+ sort:
203
+ type: number
204
+ description: 字段排序序号
205
+ type:
206
+ type: number
207
+ description: 字段类型(1=文本类型)
208
+ content:
209
+ type: string
210
+ maxLength: 1000
211
+ description: 实际填写的内容
212
+ key:
213
+ type: string
214
+ description: 字段名称
215
+ - name: userid
216
+ type: string
217
+ required: true
218
+ position: body
219
+ description: |
220
+ 创建日志的员工userId。
221
+ 示例值:"0420131813787933"
222
+ - name: dd_from
223
+ type: string
224
+ required: true
225
+ position: body
226
+ description: |
227
+ 日志来源标识,自定义的唯一标识。
228
+ 示例值:"MCP_ASSISTANT"
229
+
230
+ - name: getLogList
231
+ description: |
232
+ 查询用户发出的日志列表。
233
+
234
+ 可以根据时间范围、模板名称、用户等条件查询日志列表。
235
+ 支持分页查询,适用于批量处理和数据分析。
236
+
237
+ 【使用场景】
238
+ - 查看个人的日志历史
239
+ - 统计团队日志数据
240
+ - 查找特定时间段的日志
241
+
242
+ 【时间参数说明】
243
+ - start_time和end_time最多相隔180天
244
+ - 时间格式为Unix时间戳(毫秒)
245
+ - 可使用JavaScript的Date.now()或new Date().getTime()获取
246
+
247
+ 【查询示例】
248
+ 查询最近7天的所有日志:
249
+ {
250
+ "start_time": 1703145600000, // 7天前的时间戳
251
+ "end_time": 1703750400000, // 当前时间戳
252
+ "cursor": 0,
253
+ "size": 10
254
+ }
255
+ requestTemplate:
256
+ method: POST
257
+ url: https://oapi.dingtalk.com/topapi/report/list
258
+ args:
259
+ - name: start_time
260
+ type: number
261
+ required: true
262
+ position: body
263
+ description: |
264
+ 查询的日志创建开始时间,Unix时间戳(毫秒)。
265
+ 注意:与end_time间隔不能超过180天。
266
+ 示例值:1703145600000(2023-12-21的时间戳)
267
+ - name: end_time
268
+ type: number
269
+ required: true
270
+ position: body
271
+ description: |
272
+ 查询的日志创建结束时间,Unix时间戳(毫秒)。
273
+ 必须大于start_time,且间隔不超过180天。
274
+ 示例值:1703750400000(2023-12-28的时间戳)
275
+ - name: template_name
276
+ type: string
277
+ required: false
278
+ position: body
279
+ description: |
280
+ 要查询的模板名称(可选)。
281
+ 不传则查询所有模板的日志。
282
+ 示例值:"日报"、"周报"、"空白日志"
283
+ - name: userid
284
+ type: string
285
+ required: false
286
+ position: body
287
+ description: |
288
+ 员工的userId(可选)。
289
+ 不传则查询所有员工的日志(需要权限)。
290
+ 示例值:"0420131813787933"
291
+ - name: cursor
292
+ type: number
293
+ required: true
294
+ position: body
295
+ description: |
296
+ 查询游标,用于分页。
297
+ 初始查询传入0,后续从上一次响应的next_cursor获取。
298
+ 示例值:0
299
+ - name: size
300
+ type: number
301
+ required: true
302
+ position: body
303
+ description: |
304
+ 每页数据量,范围1-20。
305
+ 建议使用10以获得较好的性能。
306
+ 示例值:10
307
+ - name: modified_start_time
308
+ type: number
309
+ required: false
310
+ position: body
311
+ description: |
312
+ 查询的日志修改开始时间,Unix时间戳(毫秒)(可选)。
313
+ 用于查询在特定时间段内被修改过的日志。
314
+ - name: modified_end_time
315
+ type: number
316
+ required: false
317
+ position: body
318
+ description: |
319
+ 查询的日志修改结束时间,Unix时间戳(毫秒)(可选)。
320
+ 与modified_start_time配合使用。
321
+
322
+ - name: getTemplateList
323
+ description: |
324
+ 获取用户可见的日志模板列表。
325
+
326
+ 返回当前用户有权限查看和使用的所有日志模板。
327
+ 模板包含基本信息如名称、ID等,不包含详细字段信息。
328
+
329
+ 【使用场景】
330
+ - 查看可用的日志模板
331
+ - 获取模板基本信息
332
+ - 为用户选择提供模板列表
333
+
334
+ 【返回信息】
335
+ - template_list: 模板列表
336
+ - 每个模板包含:name(名称)、report_code(ID)等
337
+
338
+ 【后续操作】
339
+ 获取到模板列表后,可使用getTemplateDetail获取具体模板的字段信息。
340
+ requestTemplate:
341
+ method: POST
342
+ url: https://oapi.dingtalk.com/topapi/report/template/listbyuserid
343
+ args:
344
+ - name: userid
345
+ type: string
346
+ required: false
347
+ position: body
348
+ description: |
349
+ 员工的userId(可选)。
350
+ 不传表示获取所有日志模板。
351
+ 传入userid则获取该用户有权限的模板。
352
+ 示例值:"0420131813787933"
353
+ - name: offset
354
+ type: number
355
+ required: false
356
+ position: body
357
+ description: |
358
+ 分页偏移量,从0开始(可选)。
359
+ 用于分页查询,默认为0。
360
+ 示例值:0
361
+ - name: size
362
+ type: number
363
+ required: false
364
+ position: body
365
+ description: |
366
+ 分页大小,范围1-100(可选)。
367
+ 默认值为100,建议使用默认值获取所有模板。
368
+ 示例值:100
369
+
370
+ - name: getTemplateDetail
371
+ description: |
372
+ 查看日志模板的详细字段和配置信息。
373
+
374
+ 返回模板的完整字段定义,这是构造createLog的contents参数的关键信息。
375
+ 每个字段包含field_name、sort、type等属性,用于构造正确的日志内容。
376
+
377
+ 【重要性】
378
+ 此接口是使用createLog的前置条件!必须先获取模板详情才能正确构造contents参数。
379
+
380
+ 【返回字段说明】
381
+ - fields数组:模板的所有字段定义
382
+ - 每个field包含:
383
+ - field_name: 字段名称(用于contents的key)
384
+ - sort: 排序序号(用于contents的sort)
385
+ - type: 字段类型(用于contents的type,1=文本)
386
+
387
+ 【使用示例】
388
+ 1. 调用此接口获取模板详情
389
+ 2. 根据返回的fields构造contents数组
390
+ 3. 调用createLog创建日志
391
+
392
+ 对于"空白日志"模板的响应示例:
393
+ {
394
+ "fields": [
395
+ {
396
+ "field_name": "内容",
397
+ "sort": 0,
398
+ "type": 1
399
+ }
400
+ ],
401
+ "id": "1740b290d90f07517b0d3b14da2b4b7b",
402
+ "name": "空白日志"
403
+ }
404
+ requestTemplate:
405
+ method: POST
406
+ url: https://oapi.dingtalk.com/topapi/report/template/getbyname
407
+ args:
408
+ - name: template_name
409
+ type: string
410
+ required: true
411
+ position: body
412
+ description: |
413
+ 模板名称,必须是已存在的模板名称。
414
+ 可以从getTemplateList接口的返回结果中获取准确的模板名称。
415
+ 示例值:"空白日志"、"日报"、"周报"
416
+ - name: userid
417
+ type: string
418
+ required: true
419
+ position: body
420
+ description: |
421
+ 操作该接口的员工userId。
422
+ 必须是有权限查看该模板的用户ID。
423
+ 示例值:"0420131813787933"
@@ -0,0 +1,360 @@
1
+ server:
2
+ name: dingtalk-teambition
3
+ description: 钉钉Teambition-项目管理
4
+ tools:
5
+
6
+ - name: createProject
7
+ description: 创建项目
8
+ requestTemplate:
9
+ method: POST
10
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects
11
+ args:
12
+ - name: userId
13
+ description: 操作者userId。
14
+ type: string
15
+ required: true
16
+ position: path
17
+ - name: name
18
+ description: 项目名称。
19
+ type: string
20
+ required: true
21
+ position: body
22
+
23
+
24
+ - name: queryProjectsByProjectName
25
+ description: 根据项目名称模糊查询项目信息
26
+ requestTemplate:
27
+ method: POST
28
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects/query
29
+ args:
30
+ - name: userId
31
+ description: 操作者userId。
32
+ type: string
33
+ required: true
34
+ position: path
35
+ - name: name
36
+ description: 项目名称,模糊查询指定项目名称的项目信息
37
+ type: string
38
+ required: true
39
+ position: body
40
+ - name: maxResults
41
+ description: 分页大小,默认10,最大300
42
+ type: number
43
+ required: false
44
+ position: body
45
+ - name: nextToken
46
+ description: 分页标。供分页使用,下一页token,从当前查询结果中获取。
47
+ type: string
48
+ required: false
49
+ position: body
50
+
51
+ - name: queryProjectStatusesByProjectId
52
+ description: 根据项目ID查询项目状态信息
53
+ requestTemplate:
54
+ method: GET
55
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects/{projectId}/statuses
56
+ args:
57
+ - name: userId
58
+ description: 操作者userId。
59
+ type: string
60
+ required: true
61
+ position: path
62
+ - name: projectId
63
+ description: 项目ID。
64
+ type: string
65
+ required: true
66
+ position: path
67
+
68
+ - name: queryProjectMembersByProjectId
69
+ description: 根据项目ID查询项目成员信息
70
+ requestTemplate:
71
+ method: GET
72
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects/{projectId}/members?maxResults={String}
73
+ args:
74
+ - name: userId
75
+ description: 操作者userId。
76
+ type: string
77
+ required: true
78
+ position: path
79
+ - name: projectId
80
+ description: 项目ID。
81
+ type: string
82
+ required: true
83
+ position: path
84
+ - name: maxResults
85
+ description: 分页大小,默认10,最大300
86
+ type: number
87
+ required: false
88
+ position: query
89
+
90
+ - name: addProjectMembers
91
+ description: 添加项目成员
92
+ requestTemplate:
93
+ method: POST
94
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects/{projectId}/members
95
+ args:
96
+ - name: userId
97
+ description: 操作者userId。
98
+ type: string
99
+ required: true
100
+ position: path
101
+ - name: projectId
102
+ description: 项目ID。
103
+ type: string
104
+ required: true
105
+ position: path
106
+ - name: userIds
107
+ description: 被添加的用户userId列表,建议一次不超过10个。
108
+ type: array
109
+ required: true
110
+ position: body
111
+ items:
112
+ type: string
113
+
114
+ - name: removeProjectMembers
115
+ description: 添加项目成员
116
+ requestTemplate:
117
+ method: POST
118
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projects/{projectId}/members/remove
119
+ args:
120
+ - name: userId
121
+ description: 操作者userId。
122
+ type: string
123
+ required: true
124
+ position: path
125
+ - name: projectId
126
+ description: 项目ID。
127
+ type: string
128
+ required: true
129
+ position: path
130
+ - name: userIds
131
+ description: 被删除的用户userId列表,建议一次不超过10个。
132
+ type: array
133
+ required: true
134
+ position: body
135
+ items:
136
+ type: string
137
+
138
+
139
+ # 项目任务
140
+ - name: listProjectTasks
141
+ description: 查询项目中的任务列表
142
+ requestTemplate:
143
+ method: GET
144
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/projectIds/{projectId}/tasks?nextToken=String&maxResults=Integer
145
+ args:
146
+ - name: userId
147
+ description: 操作者userId。
148
+ type: string
149
+ required: true
150
+ position: path
151
+ - name: projectId
152
+ description: 项目ID。
153
+ type: string
154
+ required: true
155
+ position: path
156
+ - name: nextToken
157
+ description: 分页游标。如果是首次调用,该参数不传。如果是非首次调用,该参数传上次接口返回的nextToken。
158
+ type: string
159
+ required: true
160
+ position: query
161
+ - name: maxResults
162
+ description: 每页返回最大数量。默认10,最大500。
163
+ type: number
164
+ required: false
165
+ position: query
166
+
167
+ - name: listUserProjectTasks
168
+ description: 查询用户项目任务信息列表
169
+ requestTemplate:
170
+ method: POST
171
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/search?roleTypes=String&tql=String&nextToken=String&maxResults=String
172
+ args:
173
+ - name: userId
174
+ description: 操作者userId。
175
+ type: string
176
+ required: true
177
+ position: path
178
+ - name: roleTypes
179
+ description: 用户的任务角色。creator、executor、involveMember 中的一个或多个,多个以英文逗号拼接。例如:creator,executor
180
+ type: string
181
+ required: true
182
+ position: query
183
+ - name: nextToken
184
+ description: 分页游标。如果是首次调用,该参数不传。如果是非首次调用,该参数传上次接口返回的nextToken。
185
+ type: string
186
+ required: true
187
+ position: query
188
+ - name: maxResults
189
+ description: 每页返回最大数量。默认10,最大500。
190
+ type: number
191
+ required: false
192
+ position: query
193
+
194
+ - name: queryProjectTaskDetail
195
+ description: 查询项目任务详情
196
+ requestTemplate:
197
+ method: GET
198
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks?taskId=String
199
+ args:
200
+ - name: userId
201
+ description: 操作者userId。
202
+ type: string
203
+ required: true
204
+ position: path
205
+ - name: taskId
206
+ description: 项目任务ID
207
+ type: string
208
+ required: true
209
+ position: query
210
+
211
+ - name: createProjectTask
212
+ description: 创建项目任务
213
+ requestTemplate:
214
+ method: POST
215
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks
216
+ args:
217
+ - name: userId
218
+ description: 操作者userId。
219
+ type: string
220
+ required: true
221
+ position: path
222
+ - name: projectId
223
+ description: 项目id。
224
+ type: string
225
+ required: true
226
+ position: body
227
+ - name: content
228
+ description: 任务标题
229
+ type: string
230
+ required: true
231
+ position: body
232
+ - name: note
233
+ description: 任务备注
234
+ type: string
235
+ required: false
236
+ position: body
237
+ - name: startDate
238
+ description: 任务截止时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。
239
+ type: string
240
+ required: false
241
+ position: body
242
+ - name: dueDate
243
+ description: 任务开始时间,格式:YYYY-MM-DDTHH:mm:ssZ(ISO 8601/RFC 3339)。
244
+ type: string
245
+ required: false
246
+ position: body
247
+ - name: executorId
248
+ description: 任务执行者userId。
249
+ type: string
250
+ required: false
251
+ position: body
252
+
253
+ - name: deleteProjectTask
254
+ description: 删除项目任务
255
+ requestTemplate:
256
+ method: DELETE
257
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/{taskId}
258
+ args:
259
+ - name: userId
260
+ description: 操作者userId。
261
+ type: string
262
+ required: true
263
+ position: path
264
+ - name: taskId
265
+ description: 任务ID
266
+ type: string
267
+ required: true
268
+ position: path
269
+
270
+
271
+ - name: updateProjectTaskNote
272
+ description: 更新项目任务备注
273
+ requestTemplate:
274
+ method: PUT
275
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/{taskId}/notes
276
+ args:
277
+ - name: userId
278
+ description: 操作者userId。
279
+ type: string
280
+ required: true
281
+ position: path
282
+ - name: taskId
283
+ description: 任务ID。
284
+ type: string
285
+ required: true
286
+ position: path
287
+ - name: note
288
+ description: 任务备注
289
+ type: string
290
+ required: true
291
+ position: body
292
+
293
+ - name: updateProjectTaskContent
294
+ description: 更新项目任务标题
295
+ requestTemplate:
296
+ method: PUT
297
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/{taskId}/contents
298
+ args:
299
+ - name: userId
300
+ description: 操作者userId。
301
+ type: string
302
+ required: true
303
+ position: path
304
+ - name: taskId
305
+ description: 任务ID。
306
+ type: string
307
+ required: true
308
+ position: path
309
+ - name: content
310
+ description: 任务标题
311
+ type: string
312
+ required: true
313
+ position: body
314
+
315
+ - name: updateProjectTaskExecutors
316
+ description: 更新项目任务执行者
317
+ requestTemplate:
318
+ method: PUT
319
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/{taskId}/executors
320
+ args:
321
+ - name: userId
322
+ description: 操作者userId。
323
+ type: string
324
+ required: true
325
+ position: path
326
+ - name: taskId
327
+ description: 任务ID。
328
+ type: string
329
+ required: true
330
+ position: path
331
+ - name: executorId
332
+ description: 任务执行者userId
333
+ type: string
334
+ required: true
335
+ position: body
336
+
337
+
338
+ - name: updateProjectTaskInvolveMembers
339
+ description: 更新项目任务参与者
340
+ requestTemplate:
341
+ method: PUT
342
+ url: https://api.dingtalk.com/v1.0/project/users/{userId}/tasks/{taskId}/involveMembers
343
+ args:
344
+ - name: userId
345
+ description: 操作者userId。
346
+ type: string
347
+ required: true
348
+ position: path
349
+ - name: taskId
350
+ description: 任务ID。
351
+ type: string
352
+ required: true
353
+ position: path
354
+ - name: involveMembers
355
+ description: 任务参与者userId列表
356
+ type: array
357
+ required: true
358
+ position: body
359
+ items:
360
+ type: string
@@ -2,6 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { ServiceWindowMessageBuilder } from './utils/messageBuilder.js'
5
+ import { LogMessageBuilder } from './utils/logBuilder.js'
5
6
  import axios from 'axios';
6
7
  import * as yaml from 'js-yaml';
7
8
  import fs from 'fs';
@@ -23,7 +24,11 @@ export class DingTalkMCPServer {
23
24
  this.debug = process.env.DEBUG;
24
25
  // Token缓存配置
25
26
  this.tokenCacheFile = path.join(__dirname, '..', '.dingtalk_token_cache.json');
26
- this.loadConfig();
27
+ this.loadConfig(path.join(__dirname, '..'));
28
+ // 测试状态
29
+ if (process.env.STAGING){
30
+ this.loadConfig(path.join(__dirname, '../staging'));
31
+ }
27
32
  this.server = new Server({
28
33
  name: 'Dingtalk MCP Server',
29
34
  description: "Dingtalk MCP Server, inclued tasks, contacts, calendar, robot etc.",
@@ -35,7 +40,7 @@ export class DingTalkMCPServer {
35
40
  this.loadTokenCache();
36
41
  this.setupHandlers();
37
42
  }
38
- loadConfig() {
43
+ loadConfig(dirname) {
39
44
  try {
40
45
  //激活的profile
41
46
  const profiles = process.env.ACTIVE_PROFILES;
@@ -44,7 +49,7 @@ export class DingTalkMCPServer {
44
49
  profiles_list = profiles.split(',');
45
50
  }
46
51
 
47
- const configDir = path.join(__dirname, '..');
52
+ const configDir = path.join(dirname);
48
53
  fs.readdirSync(configDir).forEach(
49
54
  (file) => {
50
55
  if (file.endsWith('mcp_server.yaml')) {
@@ -72,9 +77,7 @@ export class DingTalkMCPServer {
72
77
  );
73
78
  if (this.tools && this.tools.length > 0) {
74
79
  console.error(`Loaded ${this.tools.length} tools from config`);
75
- console.error(`Tools:\r\n${this.tools.map(t => t.name + ', ' + t.description).join('\r\n')}`);
76
- }else{
77
- throw new Error('No tools found in config, tools is empty');
80
+ console.error(`Tools:\r\n${this.tools.map(t => t.name + ', '+ t.requestTemplate.method+' ' + t.requestTemplate.url + ', ' + t.description).join('\r\n')}`);
78
81
  }
79
82
  }
80
83
  catch (error) {
@@ -118,7 +121,7 @@ export class DingTalkMCPServer {
118
121
  * 检查token缓存是否有效(未过期)
119
122
  */
120
123
  isTokenCacheValid(cacheData) {
121
- if (!cacheData || !cacheData.access_token || !cacheData.expires_at) {
124
+ if (!cacheData || !cacheData.access_token || !cacheData.expires_at || cacheData.app_id !== this.appId) {
122
125
  return false;
123
126
  }
124
127
  // 提前5分钟刷新token,避免在请求过程中过期
@@ -440,6 +443,8 @@ export class DingTalkMCPServer {
440
443
  return ServiceWindowMessageBuilder.buildSendServiceWindowMarkdownBody(args);
441
444
  }else if (tool.name === 'batchSendServiceWindowMessage'){
442
445
  return ServiceWindowMessageBuilder.buildBatchSendServiceWindowMarkdownBody(args);
446
+ }else if (tool.name === 'createLog' || tool.name === 'saveLogDraft'){
447
+ return LogMessageBuilder.buildBody(args);
443
448
  }
444
449
 
445
450
 
@@ -0,0 +1,16 @@
1
+ /**
2
+ * ServiceWindow Message Builder - 核心特色功能
3
+ * 简化复杂的服务窗消息格式构建
4
+ */
5
+ export class LogMessageBuilder {
6
+ /**
7
+ * 构建服务窗消息体
8
+ * @param message 用户友好的消息参数
9
+ * @returns 钉钉API标准格式的消息体
10
+ */
11
+ static buildBody(message) {
12
+ return {
13
+ create_report_param: message
14
+ }
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dingtalk-mcp",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "DingTalk MCP Server - A TypeScript-based MCP server for DingTalk integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,17 +47,17 @@
47
47
  "model-context-protocol",
48
48
  "tasks"
49
49
  ],
50
- "author": "Generated by openapi-to-mcp",
50
+ "author": "dingtalk",
51
51
  "license": "MIT",
52
52
  "engines": {
53
53
  "node": ">=16.0.0"
54
54
  },
55
55
  "repository": {
56
56
  "type": "git",
57
- "url": "git+https://github.com/yourusername/dingtalk-mcp.git"
57
+ "url": "https://github.com/open-dingtalk/dingtalk-mcp"
58
58
  },
59
59
  "bugs": {
60
- "url": "https://github.com/yourusername/dingtalk-mcp/issues"
60
+ "url": "https://github.com/open-dingtalk/dingtalk-mcp/issues"
61
61
  },
62
- "homepage": "https://github.com/yourusername/dingtalk-mcp#readme"
62
+ "homepage": "https://open.dingtalk.com/document/ai-dev/dingtalk-server-api-mcp-overview"
63
63
  }