dingtalk-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 ADDED
@@ -0,0 +1,44 @@
1
+ # 钉钉待办MCP Server
2
+
3
+
4
+ ## 🚀 功能特性
5
+
6
+ - **创建待办**:
7
+ - **更新待办**
8
+ - **删除待办**
9
+ - **更新待办执行人状态**
10
+ - **查询待办**
11
+
12
+ ## 如何使用
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "dingtalk-tasks": {
17
+ "command": "npx",
18
+ "args": [
19
+ "-y",
20
+ "dingtalk-tasks-mcp@latest"
21
+ ],
22
+ "env": {
23
+ "DINGTALK_Client_ID": "your dingtalk client id",
24
+ "DINGTALK_Client_Secret": "your dingtalk client secret"
25
+ }
26
+ }
27
+ }
28
+ }
29
+ ```
30
+ ### 如何获取钉钉Client ID和Client Secret
31
+ 1. [成为钉钉开发者](https://open.dingtalk.com/document/orgapp/obtain-developer-permissions)
32
+ 2. [创建应用](https://open.dingtalk.com/document/orgapp/create-an-application)
33
+ 3. 进入应用详情页-凭证与基础信息,获取Client ID和Client Secret
34
+ 4. [添加权限](https://open.dingtalk.com/document/orgapp/add-api-permission),申请以下权限点
35
+ - Todo.Todo.Write
36
+ - Todo.Todo.Read
37
+
38
+
39
+ ## 📞 支持
40
+
41
+ - 钉钉开放平台: https://open.dingtalk.com
42
+ - MCP协议: https://modelcontextprotocol.io
43
+ - 欢迎加入钉钉MCP交流群
44
+ ![欢迎加入钉钉MCP交流群](https://img.alicdn.com/imgextra/i4/O1CN01QEZnE31yZBvlEHXss_!!6000000006592-2-tps-864-938.png)
@@ -0,0 +1,208 @@
1
+ server:
2
+ name: dingtalk-tasks
3
+ description: 钉钉待办
4
+ default_active: true
5
+ securitySchemes:
6
+ - id: DingTalkAuth
7
+ type: apiKey
8
+ in: header
9
+ name: x-acs-dingtalk-access-token
10
+ tools:
11
+ - name: queryTasks
12
+ description: 查询钉钉待办/任务列表
13
+ args:
14
+ - name: unionId
15
+ description: 用户UnionId
16
+ type: string
17
+ required: true
18
+ position: path
19
+ - name: nextToken
20
+ type: string
21
+ description: 分页游标,默认为0。如果一个查询条件一次无法全部返回结果,会返回分页token,下次查询带上该token后会返回后续数据,直到分页token为null表示数据已经全部查询完毕。
22
+ position: body
23
+ - name: isDone
24
+ description: 待办完成状态。true:已完成;false:未完成
25
+ type: boolean
26
+ position: body
27
+ - name: roleTypes
28
+ description: 查询目标用户角色类型。executor:执行人;creator:创建人;participant:参与人。可以同时传多个值。外层list表示或的关系,内层list表示与的关系。例如:[["executor"], ["creator"],["participant"]] 表示查询用户角色为执行人或创建人或参与人的待办列表; [["executor", "creator"]] 表示查询用户角色为执行人并且是创建人的待办列表。
29
+ type: array
30
+ items:
31
+ type: array
32
+ items:
33
+ type: string
34
+ position: body
35
+ requestTemplate:
36
+ url: https://api.dingtalk.com/v1.0/todo/users/{unionId}/org/tasks/query
37
+ method: POST
38
+ headers:
39
+ - key: Content-Type
40
+ value: application/json
41
+ security:
42
+ id: DingTalkAuth
43
+ responseTemplate: {}
44
+ - name: deleteTask
45
+ description: 删除钉钉待办
46
+ args:
47
+ - name: unionId
48
+ description: 用户UnionId
49
+ type: string
50
+ required: true
51
+ position: path
52
+ - name: taskId
53
+ description: 待办ID
54
+ type: string
55
+ required: true
56
+ position: path
57
+ requestTemplate:
58
+ url: https://api.dingtalk.com/v1.0/todo/users/{unionId}/tasks/{taskId}
59
+ method: DELETE
60
+ headers:
61
+ - key: Content-Type
62
+ value: application/json
63
+ security:
64
+ id: DingTalkAuth
65
+ responseTemplate: {}
66
+ - name: createTask
67
+ description: 创建待办
68
+ args:
69
+ - name: unionId
70
+ description: 待办创建者的UnionId
71
+ type: string
72
+ required: true
73
+ position: path
74
+ - name: subject
75
+ description: 待办标题,最大长度1024
76
+ type: string
77
+ required: true
78
+ position: body
79
+ - name: description
80
+ description: 待办备注,最大长度4096
81
+ type: string
82
+ position: body
83
+ - name: dueTime
84
+ description: 待办截止时间,Unix时间戳,单位毫秒。
85
+ type: number
86
+ position: body
87
+ - name: executorIds
88
+ description: 待办执行人的UnionId
89
+ type: array
90
+ position: body
91
+ items:
92
+ type: string
93
+ - name: participantIds
94
+ description: 待办参与人的UnionId
95
+ type: array
96
+ position: body
97
+ items:
98
+ type: string
99
+ - name: detailUrl.appUrl
100
+ description: 移动端待办详情页URL
101
+ type: string
102
+ position: body
103
+ required: true
104
+ - name: detailUrl.pcUrl
105
+ description: PC端待办详情页URL
106
+ type: string
107
+ position: body
108
+ required: true
109
+ requestTemplate:
110
+ url: https://api.dingtalk.com/v1.0/todo/users/{unionId}/tasks
111
+ method: POST
112
+ headers:
113
+ - key: Content-Type
114
+ value: application/json
115
+ security:
116
+ id: DingTalkAuth
117
+ responseTemplate: { }
118
+ - name: updateTask
119
+ description: 更新待办
120
+ args:
121
+ - name: unionId
122
+ description: 用户UnionId
123
+ type: string
124
+ required: true
125
+ position: path
126
+ - name: taskId
127
+ description: 待办ID
128
+ type: string
129
+ required: true
130
+ position: path
131
+ - name: subject
132
+ description: 待办标题,最大长度1024
133
+ type: string
134
+ required: true
135
+ position: body
136
+ - name: description
137
+ description: 待办备注,4096
138
+ type: string
139
+ position: body
140
+ - name: done
141
+ description: 完成状态。true:已完成;false:未完成
142
+ type: boolean
143
+ position: body
144
+ - name: dueTime
145
+ description: 待办截止时间,Unix时间戳,单位毫秒。
146
+ type: number
147
+ position: body
148
+ - name: executorIds
149
+ description: 待办执行人的UnionId
150
+ type: array
151
+ position: body
152
+ items:
153
+ type: string
154
+ - name: participantIds
155
+ description: 待办参与人的UnionId
156
+ type: array
157
+ position: body
158
+ items:
159
+ type: string
160
+
161
+ requestTemplate:
162
+ url: https://api.dingtalk.com/v1.0/todo/users/{unionId}/tasks/{taskId}
163
+ method: PUT
164
+ headers:
165
+ - key: Content-Type
166
+ value: application/json
167
+ security:
168
+ id: DingTalkAuth
169
+ responseTemplate: { }
170
+ - name: updateExecutorsTaskStatus
171
+ description: 更新执行人待办状态
172
+ args:
173
+ - name: unionId
174
+ description: 待办所属用户UnionId
175
+ type: string
176
+ required: true
177
+ position: path
178
+ - name: taskId
179
+ description: 待办ID
180
+ type: string
181
+ required: true
182
+ position: path
183
+ - name: executorStatusList
184
+ description: 执行者状态列表,id需传用户的unionId,最大数量1000。
185
+ type: array
186
+ required: true
187
+ position: body
188
+ items:
189
+ type: object
190
+ properties:
191
+ id:
192
+ type: string
193
+ description: 执行者unionId
194
+ isDone:
195
+ type: boolean
196
+ description: 执行者完成状态
197
+ "required":
198
+ - "id"
199
+ - "isDone"
200
+ requestTemplate:
201
+ url: https://api.dingtalk.com/v1.0/todo/users/{unionId}/tasks/{taskId}/executorStatus
202
+ method: PUT
203
+ headers:
204
+ - key: Content-Type
205
+ value: application/json
206
+ security:
207
+ id: DingTalkAuth
208
+ responseTemplate: { }
@@ -0,0 +1,40 @@
1
+ export declare class DingTalkMCPServer {
2
+ private server;
3
+ private accessToken;
4
+ private readonly appId;
5
+ private readonly appSecret;
6
+ private readonly tokenCacheFile;
7
+ private tokenCacheData;
8
+ private tools;
9
+ constructor();
10
+ private loadConfig;
11
+ /**
12
+ * 加载本地缓存的access_token
13
+ */
14
+ private loadTokenCache;
15
+ /**
16
+ * 检查token缓存是否有效(未过期)
17
+ */
18
+ private isTokenCacheValid;
19
+ /**
20
+ * 保存access_token到本地缓存
21
+ */
22
+ private saveTokenCache;
23
+ /**
24
+ * 清除token缓存
25
+ */
26
+ private clearTokenCache;
27
+ /**
28
+ * 获取有效的access_token(优先使用缓存)
29
+ */
30
+ private getValidAccessToken;
31
+ private refreshAccessToken;
32
+ private setupHandlers;
33
+ private generateSchema;
34
+ private executeTool;
35
+ private buildUrl;
36
+ private buildHeaders;
37
+ private buildBody;
38
+ run(): Promise<void>;
39
+ }
40
+ //# sourceMappingURL=DingTalkMCPServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DingTalkMCPServer.d.ts","sourceRoot":"","sources":["../src/DingTalkMCPServer.ts"],"names":[],"mappings":"AAoBA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,KAAK,CAAiB;;IAuB9B,OAAO,CAAC,UAAU;IA0BlB;;OAEG;IACH,OAAO,CAAC,cAAc;IA0BtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;YACW,mBAAmB;YAiBnB,kBAAkB;IAwChC,OAAO,CAAC,aAAa;IA6BrB,OAAO,CAAC,cAAc;YAeR,WAAW;IA0EzB,OAAO,CAAC,QAAQ;IA0ChB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,SAAS;IAyCJ,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAKlC"}
@@ -0,0 +1,439 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import axios from 'axios';
5
+ import * as yaml from 'js-yaml';
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ export class DingTalkMCPServer {
12
+ constructor() {
13
+ this.accessToken = null;
14
+ this.tokenCacheData = null;
15
+ this.tools = [];
16
+
17
+ this.accessToken = process.env.DINGTALK_ACCESS_TOKEN || null;
18
+ this.appId = process.env.DINGTALK_Client_ID;
19
+ this.appSecret = process.env.DINGTALK_Client_Secret;
20
+ this.debug = process.env.DEBUG;
21
+ // Token缓存配置
22
+ this.tokenCacheFile = path.join(__dirname, '..', '.dingtalk_token_cache.json');
23
+ this.loadConfig();
24
+ this.server = new Server({
25
+ name: 'Dingtalk MCP Server',
26
+ description: "Dingtalk MCP Server, inclued tasks, contacts, calendar, robot etc.",
27
+ version: '1.0.0',
28
+ capabilities: {
29
+ tools: {},
30
+ },
31
+ });
32
+ this.loadTokenCache();
33
+ this.setupHandlers();
34
+ }
35
+ loadConfig() {
36
+ try {
37
+ //激活的profile
38
+ const profiles = process.env.ACTIOVE_PROFILES;
39
+ const profiles_list = [];
40
+ if (profiles){
41
+ profiles_list = profiles.split(',');
42
+ }
43
+
44
+ const configDir = path.join(__dirname, '..');
45
+ fs.readdirSync(configDir).forEach(
46
+ (file) => {
47
+ if (file.endsWith('mcp_server.yaml')) {
48
+ console.info("found mcp config file:", file);
49
+
50
+ const configContent = fs.readFileSync(path.join(configDir, file), 'utf8');
51
+ const config = yaml.load(configContent);
52
+ if (!config) {
53
+ throw new Error('Config is empty');
54
+ }
55
+ if (config.server.default_active || profiles_list.includes(config.name)){
56
+
57
+ (config.tools || []).forEach(tool => {
58
+ if (this.tools.includes(tool.name)) {
59
+ throw new Error('Dulipict tool name: '+ tool.name);
60
+ }
61
+ this.tools.push(tool);
62
+ });
63
+
64
+ }
65
+
66
+ }
67
+
68
+ }
69
+ );
70
+ if (this.tools && this.tools.length > 0) {
71
+ console.info(`Loaded ${this.tools.length} tools from config`);
72
+ console.info(`Tools: ${this.tools.map(t => t.name).join(', ')}`);
73
+ }else{
74
+ throw new Error('No tools found in config, tools is empty');
75
+ }
76
+ }
77
+ catch (error) {
78
+ const err = error;
79
+ console.error('Failed to load config:', err.message);
80
+ this.tools = [];
81
+ throw error;
82
+ }
83
+ }
84
+ /**
85
+ * 加载本地缓存的access_token
86
+ */
87
+ loadTokenCache() {
88
+ try {
89
+ if (fs.existsSync(this.tokenCacheFile)) {
90
+ const cacheContent = fs.readFileSync(this.tokenCacheFile, 'utf8');
91
+ const cacheData = JSON.parse(cacheContent);
92
+ // 检查缓存是否有效
93
+ if (this.isTokenCacheValid(cacheData)) {
94
+ this.tokenCacheData = cacheData;
95
+ this.accessToken = cacheData.access_token;
96
+ console.error('Loaded valid access token from cache');
97
+ console.error(`Token expires at: ${new Date(cacheData.expires_at).toISOString()}`);
98
+ }
99
+ else {
100
+ console.error('Cached token expired, will refresh when needed');
101
+ this.clearTokenCache();
102
+ }
103
+ }
104
+ else {
105
+ console.error('No token cache found');
106
+ }
107
+ }
108
+ catch (error) {
109
+ const err = error;
110
+ console.error('Failed to load token cache:', err.message);
111
+ this.clearTokenCache();
112
+ }
113
+ }
114
+ /**
115
+ * 检查token缓存是否有效(未过期)
116
+ */
117
+ isTokenCacheValid(cacheData) {
118
+ if (!cacheData || !cacheData.access_token || !cacheData.expires_at) {
119
+ return false;
120
+ }
121
+ // 提前5分钟刷新token,避免在请求过程中过期
122
+ const bufferTime = 5 * 60 * 1000; // 5分钟
123
+ const now = Date.now();
124
+ return now < (cacheData.expires_at - bufferTime);
125
+ }
126
+ /**
127
+ * 保存access_token到本地缓存
128
+ */
129
+ saveTokenCache(accessToken, expiresIn = 7200) {
130
+ try {
131
+ const now = Date.now();
132
+ const expiresAt = now + (expiresIn * 1000); // 转换为毫秒
133
+ this.tokenCacheData = {
134
+ access_token: accessToken,
135
+ expires_in: expiresIn,
136
+ expires_at: expiresAt,
137
+ created_at: now,
138
+ app_id: this.appId
139
+ };
140
+ fs.writeFileSync(this.tokenCacheFile, JSON.stringify(this.tokenCacheData, null, 2));
141
+ console.error('Access token saved to cache');
142
+ console.error(`Token expires at: ${new Date(expiresAt).toISOString()}`);
143
+ }
144
+ catch (error) {
145
+ const err = error;
146
+ console.error('Failed to save token cache:', err.message);
147
+ }
148
+ }
149
+ /**
150
+ * 清除token缓存
151
+ */
152
+ clearTokenCache() {
153
+ try {
154
+ if (fs.existsSync(this.tokenCacheFile)) {
155
+ fs.unlinkSync(this.tokenCacheFile);
156
+ console.error('Token cache cleared');
157
+ }
158
+ this.tokenCacheData = null;
159
+ }
160
+ catch (error) {
161
+ const err = error;
162
+ console.error('Failed to clear token cache:', err.message);
163
+ }
164
+ }
165
+ /**
166
+ * 获取有效的access_token(优先使用缓存)
167
+ */
168
+ async getValidAccessToken() {
169
+ // 如果环境变量中有token,直接使用
170
+ if (process.env.DINGTALK_ACCESS_TOKEN) {
171
+ return process.env.DINGTALK_ACCESS_TOKEN;
172
+ }
173
+ // 检查当前缓存的token是否有效
174
+ if (this.tokenCacheData && this.isTokenCacheValid(this.tokenCacheData)) {
175
+ console.error('Using cached access token');
176
+ return this.tokenCacheData.access_token;
177
+ }
178
+ // 缓存无效或不存在,刷新token
179
+ console.error('Token cache invalid or missing, refreshing...');
180
+ return await this.refreshAccessToken();
181
+ }
182
+ async refreshAccessToken() {
183
+ if (!this.appId || !this.appSecret) {
184
+ throw new Error('DINGTALK_APP_ID and DINGTALK_APP_SECRET are required');
185
+ }
186
+ try {
187
+ console.error('Requesting new access token from DingTalk API...');
188
+ const response = await axios.get('https://oapi.dingtalk.com/gettoken', {
189
+ params: {
190
+ appkey: this.appId,
191
+ appsecret: this.appSecret
192
+ },
193
+ timeout: 10000 // 10秒超时
194
+ });
195
+ if (response.data.errcode === 0) {
196
+ this.accessToken = response.data.access_token;
197
+ const expiresIn = response.data.expires_in || 7200;
198
+ // 保存到缓存
199
+ this.saveTokenCache(this.accessToken, expiresIn);
200
+ console.error('Access token refreshed successfully');
201
+ return this.accessToken;
202
+ }
203
+ else {
204
+ throw new Error(`Token refresh failed: ${response.data.errmsg} (errcode: ${response.data.errcode})`);
205
+ }
206
+ }
207
+ catch (error) {
208
+ // 刷新失败时清除缓存
209
+ this.clearTokenCache();
210
+ if (axios.isAxiosError(error) && error.response) {
211
+ throw new Error(`Failed to refresh access token: HTTP ${error.response.status} - ${JSON.stringify(error.response.data)}`);
212
+ }
213
+ else {
214
+ const err = error;
215
+ throw new Error(`Failed to refresh access token: ${err.message}`);
216
+ }
217
+ }
218
+ }
219
+ setupHandlers() {
220
+ // 列出可用工具
221
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
222
+ const tools = this.tools.map(tool => ({
223
+ name: tool.name,
224
+ description: tool.description,
225
+ inputSchema: {
226
+ type: 'object',
227
+ properties: this.generateSchema(tool.args || []),
228
+ required: (tool.args || []).filter(arg => arg.required).map(arg => arg.name)
229
+ }
230
+ }));
231
+ if(this.debug){
232
+ console.error(JSON.stringify(tools, null, 2));
233
+ }
234
+ return { tools };
235
+ });
236
+ // 执行工具调用
237
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
238
+ const { name, arguments: args } = request.params;
239
+ const result = await this.executeTool(name, args || {});
240
+ // 转换为 MCP SDK 期望的格式
241
+ return {
242
+ content: result.content,
243
+ isError: result.isError
244
+ };
245
+ });
246
+ }
247
+ generateSchema(args) {
248
+ const schema = {};
249
+ args.forEach(arg => {
250
+ if (arg.system) {
251
+ // 如果 system 属性有值,则跳过本次循环,不给大模型构造这个参数
252
+ return;
253
+ }
254
+ schema[arg.name] = {
255
+ type: arg.type,
256
+ description: arg.description
257
+ };
258
+ if (arg.type === 'array' && arg.items) {
259
+ schema[arg.name].items = arg.items;
260
+ }
261
+ });
262
+ return schema;
263
+ }
264
+ async executeTool(toolName, args) {
265
+ const tool = this.tools.find(t => t.name === toolName);
266
+ if (!tool) {
267
+ return {
268
+ content: [{
269
+ type: 'text',
270
+ text: `Tool ${toolName} not found. Available tools: ${this.tools.map(t => t.name).join(', ')}`
271
+ }],
272
+ isError: true
273
+ };
274
+ }
275
+ try {
276
+ // 获取有效的访问令牌(使用缓存机制)
277
+ const accessToken = await this.getValidAccessToken();
278
+ if (!accessToken) {
279
+ throw new Error('No access token available. Please set DINGTALK_ACCESS_TOKEN or DINGTALK_APP_ID/DINGTALK_APP_SECRET');
280
+ }
281
+ // 更新当前token
282
+ this.accessToken = accessToken;
283
+ // 构建请求
284
+ const url = this.buildUrl(tool.requestTemplate.url, args);
285
+ const headers = this.buildHeaders(tool);
286
+ const body = this.buildBody(tool, args);
287
+ console.error(`Calling ${tool.requestTemplate.method} ${url}`);
288
+ console.error(`Headers:`, headers);
289
+ if (body)
290
+ console.error(`Body:`, JSON.stringify(body, null, 2));
291
+ // 执行API调用
292
+ const response = await axios({
293
+ method: tool.requestTemplate.method,
294
+ url: url,
295
+ headers: headers,
296
+ data: body,
297
+ timeout: 30000
298
+ });
299
+ return {
300
+ content: [{
301
+ type: 'text',
302
+ text: JSON.stringify(response.data, null, 2)
303
+ }]
304
+ };
305
+ }
306
+ catch (error) {
307
+ let errorMessage = error.message;
308
+ if (axios.isAxiosError(error) && error.response) {
309
+ // 如果是token相关错误,清除缓存
310
+ if (error.response.status === 401 ||
311
+ (error.response.data && error.response.data.errcode === 40014)) {
312
+ console.error('Token authentication failed, clearing cache...');
313
+ this.clearTokenCache();
314
+ this.accessToken = null;
315
+ }
316
+ errorMessage = `API Error ${error.response.status}: ${JSON.stringify(error.response.data, null, 2)}`;
317
+ }
318
+ console.error('Tool execution error:', errorMessage);
319
+ return {
320
+ content: [{
321
+ type: 'text',
322
+ text: `Error executing ${toolName}: ${errorMessage}`
323
+ }],
324
+ isError: true
325
+ };
326
+ }
327
+ }
328
+ buildUrl(template, args) {
329
+ let url = template;
330
+ // 替换路径参数
331
+ Object.keys(args).forEach(key => {
332
+ const regex = new RegExp(`\\{${key}\\}`, 'g');
333
+ if (regex.test(url)) {
334
+ url = url.replace(regex, encodeURIComponent(String(args[key])));
335
+ }
336
+ });
337
+ // 处理查询参数
338
+ const [baseUrl, queryString] = url.split('?');
339
+ if (queryString) {
340
+ const queryParams = new URLSearchParams();
341
+ // 解析模板中的查询参数
342
+ const templateParams = new URLSearchParams(queryString);
343
+ for (const [key, value] of templateParams.entries()) {
344
+ // 检查是否为模板占位符
345
+ if (value.includes('String') || value.includes('Long') || value.includes('Boolean') || value.includes('Integer')) {
346
+ if (args[key] !== undefined) {
347
+ queryParams.set(key, String(args[key]));
348
+ }
349
+ }
350
+ else {
351
+ queryParams.set(key, value);
352
+ }
353
+ }
354
+ const finalQuery = queryParams.toString();
355
+ return finalQuery ? `${baseUrl}?${finalQuery}` : baseUrl;
356
+ }
357
+ // 特殊处理oapi.dingtalk.com接口,将access_token作为URL参数传递
358
+ if (url.includes('oapi.dingtalk.com') && this.accessToken) {
359
+ const separator = url.includes('?') ? '&' : '?';
360
+ return `${url}${separator}access_token=${encodeURIComponent(this.accessToken)}`;
361
+ }
362
+ return url;
363
+ }
364
+ buildHeaders(tool) {
365
+ const headers = {
366
+ 'Content-Type': 'application/json'
367
+ };
368
+ // 只有对新版API (api.dingtalk.com) 才添加token到header
369
+ if (tool.requestTemplate.url && !tool.requestTemplate.url.includes('oapi.dingtalk.com') && this.accessToken) {
370
+ headers['x-acs-dingtalk-access-token'] = this.accessToken;
371
+ }
372
+ if (tool.requestTemplate.headers) {
373
+ tool.requestTemplate.headers.forEach(header => {
374
+ headers[header.key] = header.value;
375
+ });
376
+ }
377
+ return headers;
378
+ }
379
+ buildBody(tool, args) {
380
+ if (tool.requestTemplate.method === 'GET' || tool.requestTemplate.method === 'DELETE') {
381
+ return undefined;
382
+ }
383
+ const body = {};
384
+ (tool.args || []).forEach(arg => {
385
+ if (arg.position === 'body' && args[arg.name] !== undefined) {
386
+ // 系统参数,从环境变量读取
387
+ if (arg.system) {
388
+ body[arg.name] = process.env[arg.system];
389
+ return;
390
+ }
391
+
392
+ //Object类型参数,递归处理
393
+ let objParmas = arg.name.split('.');
394
+ if (objParmas && objParmas.length > 1) {
395
+ if (objParmas.length == 2){
396
+ body[objParmas[0]][objParmas[1]] = args[arg.name];
397
+ }
398
+ if (objParmas.length == 3){
399
+ body[objParmas[0]][objParmas[1]][objParmas[2]] = args[arg.name];
400
+ }
401
+ return;
402
+ }
403
+
404
+ // userIds参数直接传递为数组类型,保证请求体为正确的JSON对象
405
+ if (arg.name === 'userIds' && Array.isArray(args[arg.name])) {
406
+ body[arg.name] = args[arg.name];
407
+ }
408
+ // 搜索用户API参数名称转换,从snake_case转为camelCase
409
+ else if (tool.name === 'searchUser') {
410
+ // Convert snake_case to camelCase for the search user API
411
+ const camelCaseName = arg.name.replace(/_([a-z])/g, (g) => g[1].toUpperCase());
412
+ body[camelCaseName] = args[arg.name];
413
+ }
414
+ else {
415
+ body[arg.name] = args[arg.name];
416
+ }
417
+ }
418
+ });
419
+ // 为searchUser添加默认的分页参数
420
+ if (tool.name === 'searchUser') {
421
+ // 设置默认的offset为0
422
+ if (body.offset === undefined) {
423
+ body.offset = 0;
424
+ }
425
+ // 设置默认的size为20
426
+ if (body.size === undefined) {
427
+ body.size = 20;
428
+ }
429
+ console.error(`SearchUser API with params: offset=${body.offset}, size=${body.size}`);
430
+ }
431
+ return Object.keys(body).length > 0 ? body : undefined;
432
+ }
433
+ async run() {
434
+ const transport = new StdioServerTransport();
435
+ await this.server.connect(transport);
436
+ console.info('DingTalk MCP server running on stdio');
437
+ }
438
+ }
439
+ //# sourceMappingURL=DingTalkMCPServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DingTalkMCPServer.js","sourceRoot":"","sources":["../src/DingTalkMCPServer.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { DingTalkMCPServer } from './DingTalkMCPServer.js';
3
+ async function main() {
4
+ try {
5
+ // process.env.debug = true;
6
+ const server = new DingTalkMCPServer();
7
+ await server.run();
8
+ }
9
+ catch (error) {
10
+ console.error('Failed to start DingTalk MCP server:', error);
11
+ process.exit(1);
12
+ }
13
+ }
14
+ main().catch(error => {
15
+ console.error('Unexpected error:', error);
16
+ process.exit(1);
17
+ });
18
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACvC,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DingTalk Calendar MCP Server
3
+ *
4
+ * A TypeScript-based MCP server for DingTalk Calendar integration
5
+ */
6
+ export { DingTalkMCPServer } from './DingTalkMCPServer.js';
7
+ export * from './types.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DingTalk Calendar MCP Server
3
+ *
4
+ * A TypeScript-based MCP server for DingTalk Calendar integration
5
+ */
6
+ export { DingTalkMCPServer } from './DingTalkMCPServer.js';
7
+ export * from './types.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,cAAc,YAAY,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * DingTalk Calendar MCP Server Type Definitions
3
+ */
4
+ export interface MCPTool {
5
+ name: string;
6
+ description: string;
7
+ args?: MCPArg[];
8
+ requestTemplate: RequestTemplate;
9
+ }
10
+ export interface MCPArg {
11
+ name: string;
12
+ type: string;
13
+ description: string;
14
+ required?: boolean;
15
+ position?: 'body' | 'query' | 'path' | 'header';
16
+ items?: {
17
+ type: string;
18
+ };
19
+ }
20
+ export interface RequestTemplate {
21
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
22
+ url: string;
23
+ headers?: HeaderTemplate[];
24
+ }
25
+ export interface HeaderTemplate {
26
+ key: string;
27
+ value: string;
28
+ }
29
+ export interface TokenCacheData {
30
+ access_token: string;
31
+ expires_in: number;
32
+ expires_at: number;
33
+ created_at: number;
34
+ app_id?: string | undefined;
35
+ }
36
+ export interface DingTalkTokenResponse {
37
+ errcode: number;
38
+ errmsg?: string;
39
+ access_token: string;
40
+ expires_in: number;
41
+ }
42
+ export interface ToolExecutionResult {
43
+ content: Array<{
44
+ type: 'text';
45
+ text: string;
46
+ }>;
47
+ isError?: boolean;
48
+ }
49
+ export interface MCPServerConfig {
50
+ name: string;
51
+ version: string;
52
+ }
53
+ export interface MCPServerCapabilities {
54
+ capabilities: {
55
+ tools: Record<string, any>;
56
+ };
57
+ }
58
+ export interface MCPToolSchema {
59
+ name: string;
60
+ description: string;
61
+ inputSchema: {
62
+ type: 'object';
63
+ properties: Record<string, any>;
64
+ required: string[];
65
+ };
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,eAAe,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChD,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * DingTalk Calendar MCP Server Type Definitions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "dingtalk-mcp",
3
+ "version": "1.0.0",
4
+ "description": "DingTalk MCP Server - A TypeScript-based MCP server for DingTalk integration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "dingtalk-mcp": "./dist/cli.js"
10
+ },
11
+ "files": [
12
+ "dist/**/*",
13
+ "dingtalk_tasks_mcp_server.yaml"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "start": "npm run build && node dist/cli.js",
19
+ "prepublishOnly": "npm run build",
20
+ "test": "npm run build && node dist/test.js",
21
+ "test-token-cache": "npm run build && node dist/test-token-cache.js",
22
+ "demo-token-cache": "npm run build && node dist/demo-token-cache.js",
23
+ "get-token": "npm run build && node dist/get-token.js",
24
+ "clean": "rm -rf dist"
25
+ },
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^0.4.0",
28
+ "axios": "^1.6.0",
29
+ "dotenv": "^16.3.0",
30
+ "js-yaml": "^4.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/js-yaml": "^4.0.9",
34
+ "@types/node": "^20.19.0",
35
+ "typescript": "^5.8.3"
36
+ },
37
+ "keywords": [
38
+ "mcp",
39
+ "dingtalk",
40
+ "con",
41
+ "cursor",
42
+ "ai",
43
+ "typescript",
44
+ "model-context-protocol",
45
+ "tasks"
46
+ ],
47
+ "author": "Generated by openapi-to-mcp",
48
+ "license": "MIT",
49
+ "engines": {
50
+ "node": ">=16.0.0"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/yourusername/dingtalk-mcp.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/yourusername/dingtalk-mcp/issues"
58
+ },
59
+ "homepage": "https://github.com/yourusername/dingtalk-mcp#readme"
60
+ }