@liyanbin666/wechat-messenger 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,125 @@
1
+ # 企业微信 MCP 决策服务
2
+
3
+ 基于 MCP (Model Context Protocol) 的企业微信机器人服务,用于 Trae AI 远程决策确认。
4
+
5
+ ## 功能特性
6
+
7
+ - **决策请求** (`wechat_request_decision`): 高危操作前发送确认请求到企业微信
8
+ - **信息通知** (`wechat_notify_info`): 发送普通通知消息
9
+ - **成功通知** (`wechat_notify_success`): 发送操作成功通知
10
+ - **错误通知** (`wechat_notify_error`): 发送操作失败通知
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ # 安装依赖
16
+ npm install
17
+
18
+ # 编译 TypeScript
19
+ npm run build
20
+ ```
21
+
22
+ ## 配置
23
+
24
+ 1. 复制环境变量示例文件:
25
+ ```bash
26
+ cp .env.example .env
27
+ ```
28
+
29
+ 2. 编辑 `.env` 文件,配置你的企业微信机器人 Webhook URL
30
+
31
+ ## 使用
32
+
33
+ ### 启动服务
34
+
35
+ ```bash
36
+ npm start
37
+ ```
38
+
39
+ ### 测试
40
+
41
+ ```bash
42
+ npm test
43
+ ```
44
+
45
+ ### MCP Inspector 调试
46
+
47
+ ```bash
48
+ npm run inspector
49
+ ```
50
+
51
+ ## Trae 配置
52
+
53
+ 在 Trae 的 MCP 配置中添加:
54
+
55
+ ```json
56
+ {
57
+ "mcpServers": {
58
+ "wechat-decision": {
59
+ "command": "node",
60
+ "args": ["D:\\work\\SZ\\YFY\\AI_Store\\mcp-wechat-server\\dist\\index.js"],
61
+ "env": {
62
+ "WECHAT_WEBHOOK_URL": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=bb78ab00-09c8-4fff-b1fe-744327d524f8"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ ## 工具说明
70
+
71
+ ### wechat_request_decision
72
+
73
+ 向企业微信发送决策请求,等待用户确认。
74
+
75
+ **参数:**
76
+ - `operation` (string, 必需): 操作描述
77
+ - `risk_level` (string, 可选): 风险等级 (high/medium/low),默认 medium
78
+ - `details` (string, 可选): 详细信息
79
+ - `timeout_seconds` (number, 可选): 超时时间(秒),默认 300
80
+
81
+ **返回值:**
82
+ - `approved`: 用户确认
83
+ - `rejected`: 用户拒绝或超时
84
+
85
+ ### wechat_notify_info
86
+
87
+ 发送普通信息通知。
88
+
89
+ **参数:**
90
+ - `message` (string, 必需): 消息内容
91
+ - `title` (string, 可选): 消息标题,默认 "AI 通知"
92
+
93
+ ### wechat_notify_success
94
+
95
+ 发送操作成功通知。
96
+
97
+ **参数:**
98
+ - `operation` (string, 必需): 操作名称
99
+ - `details` (string, 可选): 详细信息
100
+
101
+ ### wechat_notify_error
102
+
103
+ 发送操作失败通知。
104
+
105
+ **参数:**
106
+ - `operation` (string, 必需): 操作名称
107
+ - `error_message` (string, 必需): 错误信息
108
+
109
+ ## 工作流程
110
+
111
+ 1. AI 检测到高危操作,调用 `wechat_request_decision`
112
+ 2. 企业微信群收到 Markdown 格式的决策请求
113
+ 3. 用户在群里回复 `确认 req_xxx` 或 `拒绝 req_xxx`
114
+ 4. AI 根据返回结果继续执行或终止
115
+
116
+ ## 技术栈
117
+
118
+ - TypeScript
119
+ - MCP SDK (@modelcontextprotocol/sdk)
120
+ - Axios (HTTP 请求)
121
+ - Zod (参数校验)
122
+
123
+ ## 许可证
124
+
125
+ MIT
@@ -0,0 +1,36 @@
1
+ /**
2
+ * 决策请求存储管理
3
+ */
4
+ import { DecisionRequest, RiskLevel } from './types.js';
5
+ export declare class DecisionStore {
6
+ private store;
7
+ /**
8
+ * 创建新的决策请求
9
+ */
10
+ create(operation: string, riskLevel: RiskLevel, details: string | undefined, timeout: number): string;
11
+ /**
12
+ * 获取决策请求
13
+ */
14
+ get(requestId: string): DecisionRequest | undefined;
15
+ /**
16
+ * 更新决策状态
17
+ */
18
+ updateStatus(requestId: string, status: 'approved' | 'rejected'): boolean;
19
+ /**
20
+ * 检查决策是否超时
21
+ */
22
+ isExpired(requestId: string): boolean;
23
+ /**
24
+ * 清理过期的决策请求
25
+ */
26
+ cleanup(): void;
27
+ /**
28
+ * 构建决策请求消息
29
+ */
30
+ buildDecisionMessage(requestId: string, operation: string, riskLevel: RiskLevel, details?: string): string;
31
+ /**
32
+ * 构建结果通知消息
33
+ */
34
+ buildResultMessage(requestId: string, operation: string, approved: boolean): string;
35
+ }
36
+ //# sourceMappingURL=decision-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-store.d.ts","sourceRoot":"","sources":["../src/decision-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAExE,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAA2C;IAExD;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAgBrG;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAInD;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO;IAUzE;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAMrC;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IA8B1G;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM;CAYpF"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * 决策请求存储管理
3
+ */
4
+ import { RiskLevelEmoji } from './types.js';
5
+ export class DecisionStore {
6
+ store = new Map();
7
+ /**
8
+ * 创建新的决策请求
9
+ */
10
+ create(operation, riskLevel, details, timeout) {
11
+ const requestId = `req_${Date.now()}`;
12
+ const decision = {
13
+ requestId,
14
+ operation,
15
+ riskLevel,
16
+ details,
17
+ status: 'pending',
18
+ createdAt: Date.now(),
19
+ timeout: timeout * 1000 // 转换为毫秒
20
+ };
21
+ this.store.set(requestId, decision);
22
+ return requestId;
23
+ }
24
+ /**
25
+ * 获取决策请求
26
+ */
27
+ get(requestId) {
28
+ return this.store.get(requestId);
29
+ }
30
+ /**
31
+ * 更新决策状态
32
+ */
33
+ updateStatus(requestId, status) {
34
+ const decision = this.store.get(requestId);
35
+ if (decision && decision.status === 'pending') {
36
+ decision.status = status;
37
+ this.store.set(requestId, decision);
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ /**
43
+ * 检查决策是否超时
44
+ */
45
+ isExpired(requestId) {
46
+ const decision = this.store.get(requestId);
47
+ if (!decision)
48
+ return true;
49
+ return Date.now() - decision.createdAt > decision.timeout;
50
+ }
51
+ /**
52
+ * 清理过期的决策请求
53
+ */
54
+ cleanup() {
55
+ const now = Date.now();
56
+ for (const [requestId, decision] of this.store.entries()) {
57
+ if (now - decision.createdAt > decision.timeout + 60000) { // 超时后保留1分钟
58
+ this.store.delete(requestId);
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * 构建决策请求消息
64
+ */
65
+ buildDecisionMessage(requestId, operation, riskLevel, details) {
66
+ const currentTime = new Date().toLocaleString('zh-CN');
67
+ const riskEmoji = RiskLevelEmoji[riskLevel];
68
+ const lines = [
69
+ `## ${riskEmoji} AI 决策请求`,
70
+ '',
71
+ `**请求 ID**: \`${requestId}\``,
72
+ `**时间**: ${currentTime}`,
73
+ `**操作**: ${operation}`,
74
+ `**风险等级**: ${riskLevel.toUpperCase()}`,
75
+ ];
76
+ if (details) {
77
+ lines.push(`**详情**: ${details}`);
78
+ }
79
+ lines.push('', '---', '**请回复以下指令**:', `- 确认: \`确认 ${requestId}\``, `- 拒绝: \`拒绝 ${requestId}\``, '', '⏰ 超时时间: 5 分钟');
80
+ return lines.join('\n');
81
+ }
82
+ /**
83
+ * 构建结果通知消息
84
+ */
85
+ buildResultMessage(requestId, operation, approved) {
86
+ const currentTime = new Date().toLocaleString('zh-CN');
87
+ const emoji = approved ? '✅' : '❌';
88
+ const result = approved ? '已确认' : '已拒绝';
89
+ return `## ${emoji} 决策${result}
90
+
91
+ **时间**: ${currentTime}
92
+ **请求 ID**: \`${requestId}\`
93
+ **操作**: ${operation}
94
+ **结果**: ${result}`;
95
+ }
96
+ }
97
+ //# sourceMappingURL=decision-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-store.js","sourceRoot":"","sources":["../src/decision-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 企业微信 MCP 决策服务
4
+ * 基于官方 MCP SDK 实现
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 企业微信 MCP 决策服务
4
+ * 基于官方 MCP SDK 实现
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
9
+ import { z } from 'zod';
10
+ import { WechatClient } from './wechat-client.js';
11
+ import { DecisionStore } from './decision-store.js';
12
+ // 从环境变量获取配置
13
+ const WEBHOOK_URL = process.env.WECHAT_WEBHOOK_URL ||
14
+ 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=bb78ab00-09c8-4fff-b1fe-744327d524f8';
15
+ // 初始化客户端和存储
16
+ const wechatClient = new WechatClient(WEBHOOK_URL);
17
+ const decisionStore = new DecisionStore();
18
+ // 定期清理过期决策
19
+ setInterval(() => decisionStore.cleanup(), 60000);
20
+ // 定义工具参数 Schema
21
+ const RequestDecisionSchema = z.object({
22
+ operation: z.string().describe('操作描述,如"删除数据库表 users"'),
23
+ risk_level: z.enum(['high', 'medium', 'low']).default('medium').describe('风险等级:high(高危)/medium(中危)/low(低危)'),
24
+ details: z.string().optional().describe('操作的详细信息(可选)'),
25
+ timeout_seconds: z.number().min(30).max(600).default(300).describe('等待超时时间(秒),默认300秒')
26
+ });
27
+ const NotifyInfoSchema = z.object({
28
+ message: z.string().describe('通知消息内容'),
29
+ title: z.string().default('AI 通知').describe('消息标题')
30
+ });
31
+ const NotifySuccessSchema = z.object({
32
+ operation: z.string().describe('操作名称'),
33
+ details: z.string().optional().describe('详细信息')
34
+ });
35
+ const NotifyErrorSchema = z.object({
36
+ operation: z.string().describe('操作名称'),
37
+ error_message: z.string().describe('错误信息')
38
+ });
39
+ // 定义工具
40
+ const TOOLS = [
41
+ {
42
+ name: 'wechat_request_decision',
43
+ description: '向企业微信发送决策请求,等待用户远程确认。用于高危操作前的确认流程。',
44
+ inputSchema: {
45
+ type: 'object',
46
+ properties: {
47
+ operation: { type: 'string', description: '操作描述,如"删除数据库表 users"' },
48
+ risk_level: { type: 'string', enum: ['high', 'medium', 'low'], description: '风险等级' },
49
+ details: { type: 'string', description: '详细信息(可选)' },
50
+ timeout_seconds: { type: 'number', description: '超时时间(秒)' }
51
+ },
52
+ required: ['operation']
53
+ },
54
+ annotations: {
55
+ readOnlyHint: false,
56
+ destructiveHint: false,
57
+ idempotentHint: true,
58
+ openWorldHint: false
59
+ }
60
+ },
61
+ {
62
+ name: 'wechat_notify_info',
63
+ description: '发送普通信息通知到企业微信群(无需确认)',
64
+ inputSchema: {
65
+ type: 'object',
66
+ properties: {
67
+ message: { type: 'string', description: '通知消息内容' },
68
+ title: { type: 'string', description: '消息标题' }
69
+ },
70
+ required: ['message']
71
+ },
72
+ annotations: {
73
+ readOnlyHint: true,
74
+ destructiveHint: false,
75
+ idempotentHint: true,
76
+ openWorldHint: false
77
+ }
78
+ },
79
+ {
80
+ name: 'wechat_notify_success',
81
+ description: '发送操作成功通知到企业微信群',
82
+ inputSchema: {
83
+ type: 'object',
84
+ properties: {
85
+ operation: { type: 'string', description: '操作名称' },
86
+ details: { type: 'string', description: '详细信息' }
87
+ },
88
+ required: ['operation']
89
+ },
90
+ annotations: {
91
+ readOnlyHint: true,
92
+ destructiveHint: false,
93
+ idempotentHint: true,
94
+ openWorldHint: false
95
+ }
96
+ },
97
+ {
98
+ name: 'wechat_notify_error',
99
+ description: '发送操作失败/错误通知到企业微信群',
100
+ inputSchema: {
101
+ type: 'object',
102
+ properties: {
103
+ operation: { type: 'string', description: '操作名称' },
104
+ error_message: { type: 'string', description: '错误信息' }
105
+ },
106
+ required: ['operation', 'error_message']
107
+ },
108
+ annotations: {
109
+ readOnlyHint: true,
110
+ destructiveHint: false,
111
+ idempotentHint: true,
112
+ openWorldHint: false
113
+ }
114
+ }
115
+ ];
116
+ // 创建 MCP 服务器
117
+ const server = new Server({
118
+ name: 'wechat-decision-server',
119
+ version: '1.0.0'
120
+ }, {
121
+ capabilities: {
122
+ tools: {}
123
+ }
124
+ });
125
+ // 处理工具列表请求
126
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
127
+ return { tools: TOOLS };
128
+ });
129
+ // 处理工具调用请求
130
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
131
+ const { name, arguments: args } = request.params;
132
+ try {
133
+ switch (name) {
134
+ case 'wechat_request_decision': {
135
+ const params = RequestDecisionSchema.parse(args);
136
+ const requestId = decisionStore.create(params.operation, params.risk_level, params.details, params.timeout_seconds);
137
+ const message = decisionStore.buildDecisionMessage(requestId, params.operation, params.risk_level, params.details);
138
+ const sent = await wechatClient.sendMarkdown(message);
139
+ if (!sent) {
140
+ return {
141
+ content: [{ type: 'text', text: 'rejected' }],
142
+ isError: true
143
+ };
144
+ }
145
+ // 等待决策结果(轮询方式)
146
+ const startTime = Date.now();
147
+ const timeoutMs = params.timeout_seconds * 1000;
148
+ const checkInterval = 2000; // 2秒检查一次
149
+ while (Date.now() - startTime < timeoutMs) {
150
+ const decision = decisionStore.get(requestId);
151
+ if (decision) {
152
+ if (decision.status === 'approved') {
153
+ return {
154
+ content: [{ type: 'text', text: 'approved' }]
155
+ };
156
+ }
157
+ else if (decision.status === 'rejected') {
158
+ return {
159
+ content: [{ type: 'text', text: 'rejected' }]
160
+ };
161
+ }
162
+ }
163
+ await sleep(checkInterval);
164
+ }
165
+ // 超时
166
+ decisionStore.updateStatus(requestId, 'rejected');
167
+ const timeoutMessage = decisionStore.buildResultMessage(requestId, params.operation, false);
168
+ await wechatClient.sendMarkdown(timeoutMessage);
169
+ return {
170
+ content: [{ type: 'text', text: 'rejected' }],
171
+ isError: true
172
+ };
173
+ }
174
+ case 'wechat_notify_info': {
175
+ const params = NotifyInfoSchema.parse(args);
176
+ const currentTime = new Date().toLocaleString('zh-CN');
177
+ const content = `## ℹ️ ${params.title}\n\n**时间**: ${currentTime}\n\n${params.message}`;
178
+ const sent = await wechatClient.sendMarkdown(content);
179
+ return {
180
+ content: [{ type: 'text', text: sent ? '通知发送成功' : '通知发送失败' }]
181
+ };
182
+ }
183
+ case 'wechat_notify_success': {
184
+ const params = NotifySuccessSchema.parse(args);
185
+ const currentTime = new Date().toLocaleString('zh-CN');
186
+ let content = `## ✅ 操作成功\n\n**时间**: ${currentTime}\n**操作**: ${params.operation}`;
187
+ if (params.details) {
188
+ content += `\n**详情**: ${params.details}`;
189
+ }
190
+ const sent = await wechatClient.sendMarkdown(content);
191
+ return {
192
+ content: [{ type: 'text', text: sent ? '成功通知已发送' : '通知发送失败' }]
193
+ };
194
+ }
195
+ case 'wechat_notify_error': {
196
+ const params = NotifyErrorSchema.parse(args);
197
+ const currentTime = new Date().toLocaleString('zh-CN');
198
+ const content = `## ❌ 操作失败\n\n**时间**: ${currentTime}\n**操作**: ${params.operation}\n**错误**: ${params.error_message}`;
199
+ const sent = await wechatClient.sendMarkdown(content);
200
+ return {
201
+ content: [{ type: 'text', text: sent ? '错误通知已发送' : '通知发送失败' }]
202
+ };
203
+ }
204
+ default:
205
+ throw new Error(`未知工具: ${name}`);
206
+ }
207
+ }
208
+ catch (error) {
209
+ const errorMessage = error instanceof Error ? error.message : String(error);
210
+ return {
211
+ content: [{ type: 'text', text: `错误: ${errorMessage}` }],
212
+ isError: true
213
+ };
214
+ }
215
+ });
216
+ // 辅助函数
217
+ function sleep(ms) {
218
+ return new Promise(resolve => setTimeout(resolve, ms));
219
+ }
220
+ // 启动服务器
221
+ async function main() {
222
+ const transport = new StdioServerTransport();
223
+ await server.connect(transport);
224
+ console.error('企业微信 MCP 服务已启动 (stdio 模式)');
225
+ }
226
+ main().catch(console.error);
227
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/test.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 企业微信 MCP 服务测试
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/dist/test.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 企业微信 MCP 服务测试
3
+ */
4
+ import { WechatClient } from './wechat-client.js';
5
+ import { DecisionStore } from './decision-store.js';
6
+ const WEBHOOK_URL = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=bb78ab00-09c8-4fff-b1fe-744327d524f8';
7
+ async function runTests() {
8
+ console.log('='.repeat(50));
9
+ console.log('企业微信 MCP 服务测试');
10
+ console.log('='.repeat(50));
11
+ const client = new WechatClient(WEBHOOK_URL);
12
+ const store = new DecisionStore();
13
+ // 测试 1: 发送普通通知
14
+ console.log('\n[Test 1] 发送普通通知...');
15
+ const test1 = await client.sendMarkdown(`## ✅ MCP 服务测试\n\n**时间**: ${new Date().toLocaleString('zh-CN')}\n\n这是一条测试消息,验证服务连通性。`);
16
+ console.log(`结果: ${test1 ? '✅ 成功' : '❌ 失败'}`);
17
+ // 测试 2: 创建决策请求
18
+ console.log('\n[Test 2] 创建决策请求...');
19
+ const requestId = store.create('删除测试数据', 'high', '测试决策流程', 300);
20
+ console.log(`请求 ID: ${requestId}`);
21
+ const message = store.buildDecisionMessage(requestId, '删除测试数据', 'high', '测试决策流程');
22
+ const test2 = await client.sendMarkdown(message);
23
+ console.log(`结果: ${test2 ? '✅ 成功' : '❌ 失败'}`);
24
+ // 测试 3: 模拟决策确认
25
+ console.log('\n[Test 3] 模拟决策确认...');
26
+ console.log('请在企业微信群中回复后,按以下格式输入:');
27
+ console.log(' 确认: 输入 "approve"');
28
+ console.log(' 拒绝: 输入 "reject"');
29
+ // 模拟等待(实际使用时通过回调或轮询实现)
30
+ setTimeout(() => {
31
+ store.updateStatus(requestId, 'approved');
32
+ console.log('决策已自动确认(模拟)');
33
+ const result = store.get(requestId);
34
+ console.log(`决策状态: ${result?.status}`);
35
+ }, 5000);
36
+ console.log('\n测试完成!');
37
+ }
38
+ runTests().catch(console.error);
39
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,GAAG,2FAA2F,CAAC;AAEhH,KAAK,UAAU,QAAQ;IACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;IAElC,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,4BAA4B,IAAI,IAAI,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC/H,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9C,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9C,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAEjC,uBAAuB;IACvB,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAE3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC;AAED,QAAQ,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 企业微信 MCP 服务类型定义
3
+ */
4
+ export interface WechatMessage {
5
+ msgtype: 'markdown' | 'text';
6
+ markdown?: {
7
+ content: string;
8
+ };
9
+ text?: {
10
+ content: string;
11
+ };
12
+ }
13
+ export interface DecisionRequest {
14
+ requestId: string;
15
+ operation: string;
16
+ riskLevel: 'high' | 'medium' | 'low';
17
+ details?: string;
18
+ status: 'pending' | 'approved' | 'rejected' | 'timeout';
19
+ createdAt: number;
20
+ timeout: number;
21
+ }
22
+ export interface WechatResponse {
23
+ errcode: number;
24
+ errmsg: string;
25
+ }
26
+ export type RiskLevel = 'high' | 'medium' | 'low';
27
+ export declare const RiskLevelEmoji: Record<RiskLevel, string>;
28
+ //# 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,aAAa;IAC5B,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAElD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAIpD,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 企业微信 MCP 服务类型定义
3
+ */
4
+ export const RiskLevelEmoji = {
5
+ high: '🔴',
6
+ medium: '🟡',
7
+ low: '🟢'
8
+ };
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyBH,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,GAAG,EAAE,IAAI;CACV,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 企业微信机器人客户端
3
+ */
4
+ export declare class WechatClient {
5
+ private webhookUrl;
6
+ constructor(webhookUrl: string);
7
+ /**
8
+ * 发送消息到企业微信群
9
+ */
10
+ sendMessage(content: string, msgType?: 'markdown' | 'text'): Promise<boolean>;
11
+ /**
12
+ * 发送 Markdown 消息
13
+ */
14
+ sendMarkdown(content: string): Promise<boolean>;
15
+ /**
16
+ * 发送文本消息
17
+ */
18
+ sendText(content: string): Promise<boolean>;
19
+ }
20
+ //# sourceMappingURL=wechat-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-client.d.ts","sourceRoot":"","sources":["../src/wechat-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAI9B;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAU,GAAG,MAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IA6B/F;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrD;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGlD"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 企业微信机器人客户端
3
+ */
4
+ import axios from 'axios';
5
+ export class WechatClient {
6
+ webhookUrl;
7
+ constructor(webhookUrl) {
8
+ this.webhookUrl = webhookUrl;
9
+ }
10
+ /**
11
+ * 发送消息到企业微信群
12
+ */
13
+ async sendMessage(content, msgType = 'markdown') {
14
+ try {
15
+ const payload = msgType === 'markdown'
16
+ ? { msgtype: 'markdown', markdown: { content } }
17
+ : { msgtype: 'text', text: { content } };
18
+ const response = await axios.post(this.webhookUrl, payload, {
19
+ headers: { 'Content-Type': 'application/json' },
20
+ timeout: 10000
21
+ });
22
+ if (response.data.errcode === 0) {
23
+ console.error('[消息发送成功]');
24
+ return true;
25
+ }
26
+ else {
27
+ console.error(`[发送失败] errcode: ${response.data.errcode}, errmsg: ${response.data.errmsg}`);
28
+ return false;
29
+ }
30
+ }
31
+ catch (error) {
32
+ const axiosError = error;
33
+ console.error(`[请求异常] ${axiosError.message}`);
34
+ return false;
35
+ }
36
+ }
37
+ /**
38
+ * 发送 Markdown 消息
39
+ */
40
+ async sendMarkdown(content) {
41
+ return this.sendMessage(content, 'markdown');
42
+ }
43
+ /**
44
+ * 发送文本消息
45
+ */
46
+ async sendText(content) {
47
+ return this.sendMessage(content, 'text');
48
+ }
49
+ }
50
+ //# sourceMappingURL=wechat-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat-client.js","sourceRoot":"","sources":["../src/wechat-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAC;AAG1C,MAAM,OAAO,YAAY;IACf,UAAU,CAAS;IAE3B,YAAY,UAAkB;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,UAA+B,UAAU;QAC1E,IAAI,CAAC;YACH,MAAM,OAAO,GAAkB,OAAO,KAAK,UAAU;gBACnD,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE;gBAChD,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;YAE3C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,IAAI,CAAC,UAAU,EACf,OAAO,EACP;gBACE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,OAAO,EAAE,KAAK;aACf,CACF,CAAC;YAEF,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,CAAC,IAAI,CAAC,OAAO,aAAa,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC3F,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,KAAmB,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;CACF"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@liyanbin666/wechat-messenger",
3
+ "version": "1.0.0",
4
+ "description": "企业微信 MCP 消息服务 - 用于 Trae AI 发送通知和决策请求",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "wechat-messenger": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "dev": "tsc --watch",
18
+ "test": "node dist/test.js",
19
+ "inspector": "npx @modelcontextprotocol/inspector node dist/index.js",
20
+ "prepare": "npm run build"
21
+ },
22
+ "keywords": ["mcp", "wechat", "messenger", "notifier", "trae", "decision"],
23
+ "author": "liyanbin666 <liyanbin0991@gmail.com>",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/你的用户名/wechat-mcp-server.git"
28
+ },
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.0.4",
31
+ "axios": "^1.6.0",
32
+ "zod": "^3.22.4"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.10.0",
36
+ "typescript": "^5.3.0"
37
+ }
38
+ }