@cmhk-wwso-sec/team-admin-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,228 @@
1
+ # Security Team Admin MCP Server
2
+
3
+ 通过 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 协议,让 AI 智能体直接访问安全团队管理系统的数据。智能体可以创建交流记录、查询课程、发布新闻等,无需人工手动操作后台。
4
+
5
+ ## 架构概览
6
+
7
+ ```
8
+ ┌─────────────┐ MCP (stdio) ┌──────────────────┐ GraphQL ┌─────────────┐
9
+ │ Kiro IDE │ ◄──────────────────► │ MCP Server │ ◄─────────────► │ AppSync │
10
+ │ (AI Agent) │ │ (Node.js/TS) │ │ (DynamoDB) │
11
+ └─────────────┘ └──────────────────┘ └─────────────┘
12
+ ```
13
+
14
+ - **Kiro IDE** 中的 AI 智能体通过 MCP 协议与本 Server 通信
15
+ - **MCP Server** 将 tool 调用转换为 GraphQL 请求发送到 AppSync
16
+ - **AppSync** 使用 API Key 认证,操作 DynamoDB 中的数据
17
+
18
+ ## 快速开始
19
+
20
+ ### 1. 安装依赖
21
+
22
+ ```bash
23
+ cd mcp-server
24
+ npm install
25
+ ```
26
+
27
+ ### 2. 配置环境变量(可选)
28
+
29
+ 默认已内置开发环境的 endpoint 和 API Key。如需修改:
30
+
31
+ ```bash
32
+ cp .env.example .env
33
+ # 编辑 .env 填入你的 AppSync endpoint 和 API Key
34
+ ```
35
+
36
+ ### 3. 在 Kiro 中启用
37
+
38
+ 项目已配置好 `.kiro/settings/mcp.json`,重启 Kiro 或在命令面板中搜索 "MCP" 重新连接即可。
39
+
40
+ 配置文件位置:`.kiro/settings/mcp.json`
41
+
42
+ ```json
43
+ {
44
+ "mcpServers": {
45
+ "sec-team-admin": {
46
+ "command": "npx",
47
+ "args": ["tsx", "mcp-server/src/index.ts"],
48
+ "env": {
49
+ "GRAPHQL_ENDPOINT": "https://your-appsync-endpoint/graphql",
50
+ "API_KEY": "your-api-key"
51
+ },
52
+ "disabled": false,
53
+ "autoApprove": [
54
+ "list_security_exchanges",
55
+ "get_security_exchange",
56
+ "list_courses",
57
+ "list_news",
58
+ "list_events",
59
+ "list_solutions",
60
+ "list_weekly_summaries"
61
+ ]
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ ### 4. 本地测试运行
68
+
69
+ ```bash
70
+ cd mcp-server
71
+ npx tsx src/index.ts
72
+ ```
73
+
74
+ Server 启动后会通过 stdio 等待 MCP 客户端连接。
75
+
76
+ ## 可用工具 (Tools)
77
+
78
+ ### 交流记录 (SecurityExchange)
79
+
80
+ | Tool | 说明 | 自动批准 |
81
+ |------|------|----------|
82
+ | `create_security_exchange` | 创建新的交流记录 | ❌ 需确认 |
83
+ | `list_security_exchanges` | 查询交流记录列表(分页) | ✅ |
84
+ | `get_security_exchange` | 获取单条记录详情 | ✅ |
85
+ | `update_security_exchange` | 更新已有记录 | ❌ 需确认 |
86
+ | `delete_security_exchange` | 删除记录 | ❌ 需确认 |
87
+
88
+ ### 课程 (Course)
89
+
90
+ | Tool | 说明 | 自动批准 |
91
+ |------|------|----------|
92
+ | `list_courses` | 查询课程列表 | ✅ |
93
+ | `create_course` | 创建新课程 | ❌ 需确认 |
94
+
95
+ ### 解决方案 (Solution)
96
+
97
+ | Tool | 说明 | 自动批准 |
98
+ |------|------|----------|
99
+ | `list_solutions` | 查询解决方案列表 | ✅ |
100
+
101
+ ### 周报 (WeeklySummary)
102
+
103
+ | Tool | 说明 | 自动批准 |
104
+ |------|------|----------|
105
+ | `list_weekly_summaries` | 查询周报列表 | ✅ |
106
+ | `create_weekly_summary` | 创建周报 | ❌ 需确认 |
107
+
108
+ ## 使用示例
109
+
110
+ 在 Kiro 对话中,你可以这样使用:
111
+
112
+ ### 创建交流记录
113
+
114
+ > "帮我创建一条交流记录:今天下午2点和某某公司的安全团队进行了客户拜访,讨论了 GuardDuty 和 Security Hub 的使用,参与者是张三和李四"
115
+
116
+ 智能体会自动调用 `create_security_exchange` 工具,填入:
117
+ - exchangeTime: "2025-05-09 14:00"
118
+ - exchangeType: "客户拜访"
119
+ - customerName: "某某公司"
120
+ - preAwsServices: ["GuardDuty", "Security Hub"]
121
+ - communicators: ["张三", "李四"]
122
+
123
+ ### 查询记录
124
+
125
+ > "最近有哪些交流记录?"
126
+
127
+ 智能体调用 `list_security_exchanges` 返回最近的记录列表。
128
+
129
+ ## 安全说明
130
+
131
+ ### 认证方式
132
+
133
+ 当前使用 AppSync API Key 认证,适合开发和内部使用场景。API Key 有 30 天有效期,过期后需要重新部署 Amplify 后端获取新 Key。
134
+
135
+ ### 权限控制
136
+
137
+ - **读操作**(list/get)已加入 `autoApprove`,智能体可直接执行
138
+ - **写操作**(create/update/delete)需要用户在 Kiro 中确认后才会执行
139
+ - 这确保了数据安全:智能体不会在未经确认的情况下修改数据
140
+
141
+ ### 生产环境建议
142
+
143
+ 如果要在生产环境使用,建议:
144
+
145
+ 1. **切换认证方式**:使用 IAM 或 Cognito User Pool 认证替代 API Key
146
+ 2. **环境变量管理**:不要将 API Key 硬编码,使用环境变量或 secrets manager
147
+ 3. **审计日志**:启用 AppSync 的 CloudWatch 日志记录所有 API 调用
148
+ 4. **限流**:在 AppSync 层面配置请求限流
149
+
150
+ ## 开发指南
151
+
152
+ ### 项目结构
153
+
154
+ ```
155
+ mcp-server/
156
+ ├── src/
157
+ │ ├── index.ts # MCP Server 主入口,定义所有 tools
158
+ │ ├── graphql-client.ts # GraphQL 客户端封装
159
+ │ └── queries.ts # GraphQL 查询和变更语句
160
+ ├── package.json
161
+ ├── tsconfig.json
162
+ ├── .env.example
163
+ └── README.md
164
+ ```
165
+
166
+ ### 添加新 Tool
167
+
168
+ 1. 在 `queries.ts` 中添加 GraphQL 查询/变更语句
169
+ 2. 在 `index.ts` 中使用 `server.tool()` 注册新工具
170
+ 3. 定义 Zod schema 作为参数验证
171
+ 4. 实现 handler 函数
172
+
173
+ 示例:
174
+
175
+ ```typescript
176
+ server.tool(
177
+ 'my_new_tool', // tool 名称
178
+ '工具描述', // 描述(智能体用来判断何时调用)
179
+ { // 参数 schema (Zod)
180
+ param1: z.string().describe('参数说明'),
181
+ param2: z.number().optional().describe('可选参数'),
182
+ },
183
+ async (params) => { // handler
184
+ // 调用 GraphQL API
185
+ const result = await client.query(MY_QUERY, { ...params });
186
+ return {
187
+ content: [{ type: 'text', text: '返回结果' }],
188
+ };
189
+ }
190
+ );
191
+ ```
192
+
193
+ ### 构建生产版本
194
+
195
+ ```bash
196
+ npm run build
197
+ # 产出在 dist/ 目录
198
+ node dist/index.js
199
+ ```
200
+
201
+ ## 故障排查
202
+
203
+ ### Server 无法启动
204
+
205
+ 1. 确认 Node.js >= 18(需要原生 fetch 支持)
206
+ 2. 确认依赖已安装:`npm install`
207
+ 3. 检查 TypeScript 编译:`npx tsc --noEmit`
208
+
209
+ ### API 调用失败
210
+
211
+ 1. 检查 API Key 是否过期(30天有效期)
212
+ 2. 确认 GraphQL endpoint 可达
213
+ 3. 查看错误信息中的 GraphQL errors
214
+
215
+ ### Kiro 中看不到 MCP Server
216
+
217
+ 1. 确认 `.kiro/settings/mcp.json` 配置正确
218
+ 2. 在 Kiro 命令面板搜索 "MCP" 查看 server 状态
219
+ 3. 尝试重启 Kiro 或手动重连 MCP server
220
+
221
+ ## 技术栈
222
+
223
+ - **Runtime**: Node.js 18+
224
+ - **Language**: TypeScript 5.4+
225
+ - **MCP SDK**: @modelcontextprotocol/sdk 1.12+
226
+ - **Validation**: Zod 3.23+
227
+ - **Backend**: AWS AppSync (GraphQL) + DynamoDB
228
+ - **Auth**: API Key (开发环境)
@@ -0,0 +1,20 @@
1
+ /**
2
+ * GraphQL Client for Amplify AppSync API
3
+ * 通过 API Key 认证访问 AppSync GraphQL 端点
4
+ */
5
+ export interface GraphQLResponse<T = unknown> {
6
+ data?: T;
7
+ errors?: Array<{
8
+ message: string;
9
+ locations?: unknown;
10
+ path?: unknown;
11
+ }>;
12
+ }
13
+ export declare class GraphQLClient {
14
+ private endpoint;
15
+ private apiKey;
16
+ constructor(endpoint: string, apiKey: string);
17
+ query<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<GraphQLResponse<T>>;
18
+ mutate<T = unknown>(mutation: string, variables?: Record<string, unknown>): Promise<GraphQLResponse<T>>;
19
+ }
20
+ //# sourceMappingURL=graphql-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql-client.d.ts","sourceRoot":"","sources":["../src/graphql-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKtC,KAAK,CAAC,CAAC,GAAG,OAAO,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAmBxB,MAAM,CAAC,CAAC,GAAG,OAAO,EACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CAG/B"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * GraphQL Client for Amplify AppSync API
3
+ * 通过 API Key 认证访问 AppSync GraphQL 端点
4
+ */
5
+ export class GraphQLClient {
6
+ endpoint;
7
+ apiKey;
8
+ constructor(endpoint, apiKey) {
9
+ this.endpoint = endpoint;
10
+ this.apiKey = apiKey;
11
+ }
12
+ async query(query, variables) {
13
+ const response = await fetch(this.endpoint, {
14
+ method: 'POST',
15
+ headers: {
16
+ 'Content-Type': 'application/json',
17
+ 'x-api-key': this.apiKey,
18
+ },
19
+ body: JSON.stringify({ query, variables }),
20
+ });
21
+ if (!response.ok) {
22
+ throw new Error(`GraphQL request failed: ${response.status} ${response.statusText}`);
23
+ }
24
+ return response.json();
25
+ }
26
+ async mutate(mutation, variables) {
27
+ return this.query(mutation, variables);
28
+ }
29
+ }
30
+ //# sourceMappingURL=graphql-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql-client.js","sourceRoot":"","sources":["../src/graphql-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,OAAO,aAAa;IAChB,QAAQ,CAAS;IACjB,MAAM,CAAS;IAEvB,YAAY,QAAgB,EAAE,MAAc;QAC1C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK,CACT,KAAa,EACb,SAAmC;QAEnC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC1C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,MAAM;aACzB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACpE,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAiC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,QAAgB,EAChB,SAAmC;QAEnC,OAAO,IAAI,CAAC,KAAK,CAAI,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Security Team Admin MCP Server
4
+ *
5
+ * 通过 MCP 协议暴露安全团队管理系统的数据操作能力,
6
+ * 允许 AI 智能体直接创建、查询、更新交流记录等数据。
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
package/dist/index.js ADDED
@@ -0,0 +1,445 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Security Team Admin MCP Server
4
+ *
5
+ * 通过 MCP 协议暴露安全团队管理系统的数据操作能力,
6
+ * 允许 AI 智能体直接创建、查询、更新交流记录等数据。
7
+ */
8
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import { z } from 'zod';
11
+ import { GraphQLClient } from './graphql-client.js';
12
+ import * as queries from './queries.js';
13
+ // ============================================================
14
+ // Configuration
15
+ // ============================================================
16
+ const GRAPHQL_ENDPOINT = process.env.GRAPHQL_ENDPOINT ||
17
+ 'https://2vora7hhhveyngl6lz4txmotqy.appsync-api.us-east-1.amazonaws.com/graphql';
18
+ const API_KEY = process.env.API_KEY || 'da2-hm7vqblprzfjhikfznvtuaueia';
19
+ const client = new GraphQLClient(GRAPHQL_ENDPOINT, API_KEY);
20
+ // ============================================================
21
+ // MCP Server Setup
22
+ // ============================================================
23
+ const server = new McpServer({
24
+ name: 'sec-team-admin',
25
+ version: '1.0.0',
26
+ });
27
+ // ============================================================
28
+ // Tools: SecurityExchange (交流记录)
29
+ // ============================================================
30
+ server.tool('create_security_exchange', '创建一条新的安全交流记录。支持多种交流类型:客户拜访、Workshop、市场活动、应急响应、内部培训、AI安全等。', {
31
+ exchangeTime: z.string().describe('交流时间,格式如 "2025-05-09 14:00"'),
32
+ exchangeDate: z.string().optional().describe('交流日期,格式 YYYY-MM-DD'),
33
+ exchangeType: z.string().describe('交流类型:客户拜访/Workshop/市场活动/应急响应/内部培训/AI安全/Blog发布'),
34
+ owner: z.string().describe('记录创建者姓名'),
35
+ sfdcCompanyName: z.string().optional().describe('SFDC公司名称'),
36
+ companySize: z.string().optional().describe('公司规模:XXL/XL/L/M/S/未知'),
37
+ customerName: z.string().optional().describe('客户名称'),
38
+ customerIndustry: z.string().optional().describe('客户行业'),
39
+ bu: z.string().optional().describe('业务单元'),
40
+ businessType: z.array(z.string()).optional().describe('业务类型数组'),
41
+ communicators: z.array(z.string()).optional().describe('交流者列表'),
42
+ notes: z.string().optional().describe('备注信息'),
43
+ preAwsServices: z.array(z.string()).optional().describe('交流前涉及的AWS服务'),
44
+ postAwsServices: z.array(z.string()).optional().describe('交流后推荐的AWS服务'),
45
+ securityBestPractices: z.array(z.string()).optional().describe('涉及的安全最佳实践'),
46
+ complianceCategory: z.array(z.string()).optional().describe('合规类别'),
47
+ workshopLink: z.string().optional().describe('Workshop链接'),
48
+ blogLink: z.string().optional().describe('Blog链接'),
49
+ attendeeCount: z.number().optional().describe('到场人数(市场活动)'),
50
+ emergencyCategory: z.string().optional().describe('应急响应分类'),
51
+ problemDescription: z.string().optional().describe('问题描述(应急响应)'),
52
+ solutionPlan: z.string().optional().describe('修复方案(应急响应)'),
53
+ trainingServices: z.array(z.string()).optional().describe('涉及的安全服务(内部培训)'),
54
+ onlineParticipants: z.number().optional().describe('在线人数(内部培训)'),
55
+ trainingDescription: z.string().optional().describe('培训描述'),
56
+ aiSecurityStage: z.string().optional().describe('AI安全阶段'),
57
+ aiSecuritySolution: z.string().optional().describe('AI安全解决方案'),
58
+ oppLink: z.string().optional().describe('机会链接'),
59
+ oppAmount: z.number().optional().describe('机会金额'),
60
+ oppStatus: z.string().optional().describe('OPP状态'),
61
+ accountTeam: z.string().optional().describe('客户团队'),
62
+ isNotableCase: z.boolean().optional().describe('是否是Notable Case'),
63
+ }, async (params) => {
64
+ try {
65
+ const input = { ...params };
66
+ const result = await client.mutate(queries.CREATE_SECURITY_EXCHANGE, { input });
67
+ if (result.errors) {
68
+ return {
69
+ content: [
70
+ {
71
+ type: 'text',
72
+ text: `创建失败: ${result.errors.map((e) => e.message).join(', ')}`,
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ const record = result.data?.createSecurityExchange;
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: `✅ 交流记录创建成功!\n\nID: ${record?.id}\n类型: ${record?.exchangeType}\n时间: ${record?.exchangeTime}\n客户: ${record?.customerName || '未指定'}\n创建者: ${record?.owner}`,
83
+ },
84
+ ],
85
+ };
86
+ }
87
+ catch (error) {
88
+ return {
89
+ content: [
90
+ {
91
+ type: 'text',
92
+ text: `创建交流记录时出错: ${error instanceof Error ? error.message : String(error)}`,
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ });
98
+ server.tool('list_security_exchanges', '查询安全交流记录列表,支持分页。返回最近的交流记录摘要信息。', {
99
+ limit: z.number().optional().default(20).describe('返回记录数量,默认20'),
100
+ nextToken: z.string().optional().describe('分页 token,用于获取下一页'),
101
+ }, async ({ limit, nextToken }) => {
102
+ try {
103
+ const result = await client.query(queries.LIST_SECURITY_EXCHANGES, {
104
+ limit,
105
+ nextToken,
106
+ });
107
+ if (result.errors) {
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: `查询失败: ${result.errors.map((e) => e.message).join(', ')}`,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ const data = result.data?.listSecurityExchanges;
118
+ const items = data?.items || [];
119
+ let text = `📋 交流记录列表 (共 ${items.length} 条)\n\n`;
120
+ for (const item of items) {
121
+ text += `---\n`;
122
+ text += `ID: ${item.id}\n`;
123
+ text += `时间: ${item.exchangeTime} | 类型: ${item.exchangeType}\n`;
124
+ text += `客户: ${item.customerName || item.sfdcCompanyName || '未指定'}\n`;
125
+ text += `交流者: ${item.communicators?.join(', ') || '未指定'}\n`;
126
+ text += `创建者: ${item.owner}\n`;
127
+ if (item.notes)
128
+ text += `备注: ${String(item.notes).substring(0, 100)}...\n`;
129
+ text += '\n';
130
+ }
131
+ if (data?.nextToken) {
132
+ text += `\n📄 还有更多记录,使用 nextToken: "${data.nextToken}" 获取下一页`;
133
+ }
134
+ return { content: [{ type: 'text', text }] };
135
+ }
136
+ catch (error) {
137
+ return {
138
+ content: [
139
+ {
140
+ type: 'text',
141
+ text: `查询交流记录时出错: ${error instanceof Error ? error.message : String(error)}`,
142
+ },
143
+ ],
144
+ };
145
+ }
146
+ });
147
+ server.tool('get_security_exchange', '根据 ID 获取单条交流记录的完整详情。', {
148
+ id: z.string().describe('交流记录 ID'),
149
+ }, async ({ id }) => {
150
+ try {
151
+ const result = await client.query(queries.GET_SECURITY_EXCHANGE, { id });
152
+ if (result.errors) {
153
+ return {
154
+ content: [
155
+ {
156
+ type: 'text',
157
+ text: `查询失败: ${result.errors.map((e) => e.message).join(', ')}`,
158
+ },
159
+ ],
160
+ };
161
+ }
162
+ const record = result.data?.getSecurityExchange;
163
+ if (!record) {
164
+ return {
165
+ content: [{ type: 'text', text: `未找到 ID 为 "${id}" 的交流记录` }],
166
+ };
167
+ }
168
+ return {
169
+ content: [
170
+ {
171
+ type: 'text',
172
+ text: JSON.stringify(record, null, 2),
173
+ },
174
+ ],
175
+ };
176
+ }
177
+ catch (error) {
178
+ return {
179
+ content: [
180
+ {
181
+ type: 'text',
182
+ text: `获取交流记录详情时出错: ${error instanceof Error ? error.message : String(error)}`,
183
+ },
184
+ ],
185
+ };
186
+ }
187
+ });
188
+ server.tool('update_security_exchange', '更新已有的交流记录。只需传入要更新的字段。', {
189
+ id: z.string().describe('要更新的交流记录 ID'),
190
+ exchangeTime: z.string().optional().describe('交流时间'),
191
+ exchangeType: z.string().optional().describe('交流类型'),
192
+ sfdcCompanyName: z.string().optional().describe('SFDC公司名称'),
193
+ customerName: z.string().optional().describe('客户名称'),
194
+ notes: z.string().optional().describe('备注'),
195
+ communicators: z.array(z.string()).optional().describe('交流者列表'),
196
+ preAwsServices: z.array(z.string()).optional().describe('交流前AWS服务'),
197
+ postAwsServices: z.array(z.string()).optional().describe('交流后AWS服务'),
198
+ oppLink: z.string().optional().describe('机会链接'),
199
+ oppAmount: z.number().optional().describe('机会金额'),
200
+ oppStatus: z.string().optional().describe('OPP状态'),
201
+ isNotableCase: z.boolean().optional().describe('是否Notable Case'),
202
+ }, async (params) => {
203
+ try {
204
+ const input = { ...params };
205
+ const result = await client.mutate(queries.UPDATE_SECURITY_EXCHANGE, { input });
206
+ if (result.errors) {
207
+ return {
208
+ content: [
209
+ {
210
+ type: 'text',
211
+ text: `更新失败: ${result.errors.map((e) => e.message).join(', ')}`,
212
+ },
213
+ ],
214
+ };
215
+ }
216
+ return {
217
+ content: [
218
+ { type: 'text', text: `✅ 交流记录 ${params.id} 更新成功` },
219
+ ],
220
+ };
221
+ }
222
+ catch (error) {
223
+ return {
224
+ content: [
225
+ {
226
+ type: 'text',
227
+ text: `更新交流记录时出错: ${error instanceof Error ? error.message : String(error)}`,
228
+ },
229
+ ],
230
+ };
231
+ }
232
+ });
233
+ server.tool('delete_security_exchange', '删除一条交流记录(不可恢复,请谨慎操作)。', {
234
+ id: z.string().describe('要删除的交流记录 ID'),
235
+ }, async ({ id }) => {
236
+ try {
237
+ const result = await client.mutate(queries.DELETE_SECURITY_EXCHANGE, {
238
+ input: { id },
239
+ });
240
+ if (result.errors) {
241
+ return {
242
+ content: [
243
+ {
244
+ type: 'text',
245
+ text: `删除失败: ${result.errors.map((e) => e.message).join(', ')}`,
246
+ },
247
+ ],
248
+ };
249
+ }
250
+ return {
251
+ content: [{ type: 'text', text: `✅ 交流记录 ${id} 已删除` }],
252
+ };
253
+ }
254
+ catch (error) {
255
+ return {
256
+ content: [
257
+ {
258
+ type: 'text',
259
+ text: `删除交流记录时出错: ${error instanceof Error ? error.message : String(error)}`,
260
+ },
261
+ ],
262
+ };
263
+ }
264
+ });
265
+ // ============================================================
266
+ // Tools: Course (课程)
267
+ // ============================================================
268
+ server.tool('list_courses', '查询安全培训课程列表。', {
269
+ limit: z.number().optional().default(20).describe('返回数量,默认20'),
270
+ nextToken: z.string().optional().describe('分页 token'),
271
+ }, async ({ limit, nextToken }) => {
272
+ try {
273
+ const result = await client.query(queries.LIST_COURSES, { limit, nextToken });
274
+ if (result.errors) {
275
+ return {
276
+ content: [
277
+ { type: 'text', text: `查询失败: ${result.errors.map((e) => e.message).join(', ')}` },
278
+ ],
279
+ };
280
+ }
281
+ const data = result.data?.listCourses;
282
+ const items = data?.items || [];
283
+ let text = `📚 课程列表 (共 ${items.length} 条)\n\n`;
284
+ for (const item of items) {
285
+ text += `- **${item.course_name}** (ID: ${item.id})\n`;
286
+ text += ` ${item.description || '无描述'}\n`;
287
+ text += ` 观看次数: ${item.view_count || 0} | 创建者: ${item.owner || '未知'}\n\n`;
288
+ }
289
+ return { content: [{ type: 'text', text }] };
290
+ }
291
+ catch (error) {
292
+ return {
293
+ content: [
294
+ { type: 'text', text: `查询课程时出错: ${error instanceof Error ? error.message : String(error)}` },
295
+ ],
296
+ };
297
+ }
298
+ });
299
+ server.tool('create_course', '创建一门新的安全培训课程。', {
300
+ course_name: z.string().describe('课程名称'),
301
+ description: z.string().optional().describe('课程描述'),
302
+ content: z.string().optional().describe('课程内容(Markdown)'),
303
+ brief_input: z.string().optional().describe('课程简介输入'),
304
+ ppt_url: z.string().optional().describe('PPT 链接'),
305
+ video_url: z.string().optional().describe('视频链接'),
306
+ resource_url: z.string().optional().describe('资源链接'),
307
+ owner: z.string().describe('创建者'),
308
+ }, async (params) => {
309
+ try {
310
+ const result = await client.mutate(queries.CREATE_COURSE, { input: params });
311
+ if (result.errors) {
312
+ return {
313
+ content: [
314
+ { type: 'text', text: `创建失败: ${result.errors.map((e) => e.message).join(', ')}` },
315
+ ],
316
+ };
317
+ }
318
+ const record = result.data?.createCourse;
319
+ return {
320
+ content: [
321
+ { type: 'text', text: `✅ 课程创建成功!\n\nID: ${record?.id}\n名称: ${record?.course_name}` },
322
+ ],
323
+ };
324
+ }
325
+ catch (error) {
326
+ return {
327
+ content: [
328
+ { type: 'text', text: `创建课程时出错: ${error instanceof Error ? error.message : String(error)}` },
329
+ ],
330
+ };
331
+ }
332
+ });
333
+ // ============================================================
334
+ // Tools: Solution (解决方案)
335
+ // ============================================================
336
+ server.tool('list_solutions', '查询安全解决方案列表。', {
337
+ limit: z.number().optional().default(20).describe('返回数量,默认20'),
338
+ nextToken: z.string().optional().describe('分页 token'),
339
+ }, async ({ limit, nextToken }) => {
340
+ try {
341
+ const result = await client.query(queries.LIST_SOLUTIONS, { limit, nextToken });
342
+ if (result.errors) {
343
+ return {
344
+ content: [
345
+ { type: 'text', text: `查询失败: ${result.errors.map((e) => e.message).join(', ')}` },
346
+ ],
347
+ };
348
+ }
349
+ const data = result.data?.listSolutions;
350
+ const items = data?.items || [];
351
+ let text = `💡 解决方案列表 (共 ${items.length} 条)\n\n`;
352
+ for (const item of items) {
353
+ text += `- **${item.solutionName}** (${item.status})\n`;
354
+ text += ` 负责人: ${item.responsiblePerson} | 分类: ${item.category || '未分类'}\n`;
355
+ text += ` ${item.description?.substring(0, 80) || '无描述'}\n\n`;
356
+ }
357
+ return { content: [{ type: 'text', text }] };
358
+ }
359
+ catch (error) {
360
+ return {
361
+ content: [
362
+ { type: 'text', text: `查询解决方案时出错: ${error instanceof Error ? error.message : String(error)}` },
363
+ ],
364
+ };
365
+ }
366
+ });
367
+ // ============================================================
368
+ // Tools: WeeklySummary (周报)
369
+ // ============================================================
370
+ server.tool('list_weekly_summaries', '查询周报总结列表。', {
371
+ limit: z.number().optional().default(10).describe('返回数量,默认10'),
372
+ nextToken: z.string().optional().describe('分页 token'),
373
+ }, async ({ limit, nextToken }) => {
374
+ try {
375
+ const result = await client.query(queries.LIST_WEEKLY_SUMMARIES, { limit, nextToken });
376
+ if (result.errors) {
377
+ return {
378
+ content: [
379
+ { type: 'text', text: `查询失败: ${result.errors.map((e) => e.message).join(', ')}` },
380
+ ],
381
+ };
382
+ }
383
+ const data = result.data?.listWeeklySummaries;
384
+ const items = data?.items || [];
385
+ let text = `📝 周报列表 (共 ${items.length} 条)\n\n`;
386
+ for (const item of items) {
387
+ text += `- **${item.weekStart}** - ${item.communicator}\n`;
388
+ text += ` ${item.summary?.substring(0, 120) || '无内容'}...\n\n`;
389
+ }
390
+ return { content: [{ type: 'text', text }] };
391
+ }
392
+ catch (error) {
393
+ return {
394
+ content: [
395
+ { type: 'text', text: `查询周报时出错: ${error instanceof Error ? error.message : String(error)}` },
396
+ ],
397
+ };
398
+ }
399
+ });
400
+ server.tool('create_weekly_summary', '创建一条周报总结。', {
401
+ weekStart: z.string().describe('周一日期,格式 YYYY-MM-DD'),
402
+ communicator: z.string().describe('交流者/负责人'),
403
+ summary: z.string().describe('周报总结内容'),
404
+ updatedBy: z.string().optional().describe('最后编辑者'),
405
+ }, async (params) => {
406
+ try {
407
+ const result = await client.mutate(queries.CREATE_WEEKLY_SUMMARY, { input: params });
408
+ if (result.errors) {
409
+ return {
410
+ content: [
411
+ { type: 'text', text: `创建失败: ${result.errors.map((e) => e.message).join(', ')}` },
412
+ ],
413
+ };
414
+ }
415
+ const record = result.data?.createWeeklySummary;
416
+ return {
417
+ content: [
418
+ {
419
+ type: 'text',
420
+ text: `✅ 周报创建成功!\n\nID: ${record?.id}\n周起始: ${record?.weekStart}\n交流者: ${record?.communicator}`,
421
+ },
422
+ ],
423
+ };
424
+ }
425
+ catch (error) {
426
+ return {
427
+ content: [
428
+ { type: 'text', text: `创建周报时出错: ${error instanceof Error ? error.message : String(error)}` },
429
+ ],
430
+ };
431
+ }
432
+ });
433
+ // ============================================================
434
+ // Start Server
435
+ // ============================================================
436
+ async function main() {
437
+ const transport = new StdioServerTransport();
438
+ await server.connect(transport);
439
+ console.error('🚀 Security Team Admin MCP Server is running');
440
+ }
441
+ main().catch((error) => {
442
+ console.error('Failed to start MCP server:', error);
443
+ process.exit(1);
444
+ });
445
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * GraphQL Queries & Mutations for Security Team Admin
3
+ */
4
+ export declare const CREATE_SECURITY_EXCHANGE = "\n mutation CreateSecurityExchange($input: CreateSecurityExchangeInput!) {\n createSecurityExchange(input: $input) {\n id\n exchangeTime\n exchangeDate\n sfdcCompanyName\n companySize\n customerName\n exchangeType\n customerIndustry\n bu\n businessType\n communicators\n notes\n owner\n preAwsServices\n postAwsServices\n securityBestPractices\n complianceCategory\n preComplianceItems\n postComplianceItems\n workshopLink\n blogLink\n attendeeCount\n emergencyCategory\n problemDescription\n solutionPlan\n trainingServices\n onlineParticipants\n trainingDescription\n aiSecurityStage\n aiSecuritySolution\n aiSecurityWorkshopLink\n oppLink\n oppAmount\n oppStatus\n specReqLink\n accountTeam\n hasFollowUp\n parentExchangeID\n isNotableCase\n createdAt\n updatedAt\n }\n }\n";
5
+ export declare const LIST_SECURITY_EXCHANGES = "\n query ListSecurityExchanges($limit: Int, $nextToken: String) {\n listSecurityExchanges(limit: $limit, nextToken: $nextToken) {\n items {\n id\n exchangeTime\n exchangeDate\n sfdcCompanyName\n companySize\n customerName\n exchangeType\n customerIndustry\n bu\n businessType\n communicators\n notes\n owner\n preAwsServices\n postAwsServices\n securityBestPractices\n oppLink\n oppAmount\n oppStatus\n isNotableCase\n createdAt\n updatedAt\n }\n nextToken\n }\n }\n";
6
+ export declare const GET_SECURITY_EXCHANGE = "\n query GetSecurityExchange($id: ID!) {\n getSecurityExchange(id: $id) {\n id\n exchangeTime\n exchangeDate\n sfdcCompanyName\n companySize\n customerName\n exchangeType\n customerIndustry\n bu\n businessType\n communicators\n notes\n owner\n preAwsServices\n postAwsServices\n securityBestPractices\n complianceCategory\n preComplianceItems\n postComplianceItems\n workshopLink\n blogLink\n attendeeCount\n emergencyCategory\n problemDescription\n solutionPlan\n trainingServices\n onlineParticipants\n trainingDescription\n aiSecurityStage\n aiSecuritySolution\n aiSecurityWorkshopLink\n oppLink\n oppAmount\n oppStatus\n specReqLink\n accountTeam\n hasFollowUp\n parentExchangeID\n excludedRelatedExchangeIDs\n isNotableCase\n createdAt\n updatedAt\n }\n }\n";
7
+ export declare const UPDATE_SECURITY_EXCHANGE = "\n mutation UpdateSecurityExchange($input: UpdateSecurityExchangeInput!) {\n updateSecurityExchange(input: $input) {\n id\n exchangeTime\n exchangeDate\n sfdcCompanyName\n customerName\n exchangeType\n owner\n updatedAt\n }\n }\n";
8
+ export declare const DELETE_SECURITY_EXCHANGE = "\n mutation DeleteSecurityExchange($input: DeleteSecurityExchangeInput!) {\n deleteSecurityExchange(input: $input) {\n id\n }\n }\n";
9
+ export declare const LIST_COURSES = "\n query ListCourses($limit: Int, $nextToken: String) {\n listCourses(limit: $limit, nextToken: $nextToken) {\n items {\n id\n course_name\n description\n content\n brief_input\n ppt_url\n video_url\n view_count\n resource_url\n owner\n createdAt\n updatedAt\n }\n nextToken\n }\n }\n";
10
+ export declare const CREATE_COURSE = "\n mutation CreateCourse($input: CreateCourseInput!) {\n createCourse(input: $input) {\n id\n course_name\n description\n content\n brief_input\n ppt_url\n video_url\n view_count\n resource_url\n owner\n createdAt\n }\n }\n";
11
+ export declare const LIST_SOLUTIONS = "\n query ListSolutions($limit: Int, $nextToken: String) {\n listSolutions(limit: $limit, nextToken: $nextToken) {\n items {\n id\n solutionName\n responsiblePerson\n resourceUrl\n description\n category\n status\n owner\n createdAt\n updatedAt\n }\n nextToken\n }\n }\n";
12
+ export declare const LIST_WEEKLY_SUMMARIES = "\n query ListWeeklySummaries($limit: Int, $nextToken: String) {\n listWeeklySummaries(limit: $limit, nextToken: $nextToken) {\n items {\n id\n weekStart\n communicator\n summary\n updatedBy\n createdAt\n updatedAt\n }\n nextToken\n }\n }\n";
13
+ export declare const CREATE_WEEKLY_SUMMARY = "\n mutation CreateWeeklySummary($input: CreateWeeklySummaryInput!) {\n createWeeklySummary(input: $input) {\n id\n weekStart\n communicator\n summary\n updatedBy\n createdAt\n }\n }\n";
14
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,wBAAwB,k+BA8CpC,CAAC;AAEF,eAAO,MAAM,uBAAuB,woBA8BnC,CAAC;AAEF,eAAO,MAAM,qBAAqB,y9BA+CjC,CAAC;AAEF,eAAO,MAAM,wBAAwB,0RAapC,CAAC;AAEF,eAAO,MAAM,wBAAwB,qJAMpC,CAAC;AAMF,eAAO,MAAM,YAAY,4YAoBxB,CAAC;AAEF,eAAO,MAAM,aAAa,mSAgBzB,CAAC;AAMF,eAAO,MAAM,cAAc,+WAkB1B,CAAC;AAMF,eAAO,MAAM,qBAAqB,4TAejC,CAAC;AAEF,eAAO,MAAM,qBAAqB,kOAWjC,CAAC"}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * GraphQL Queries & Mutations for Security Team Admin
3
+ */
4
+ // ============================================================
5
+ // SecurityExchange
6
+ // ============================================================
7
+ export const CREATE_SECURITY_EXCHANGE = `
8
+ mutation CreateSecurityExchange($input: CreateSecurityExchangeInput!) {
9
+ createSecurityExchange(input: $input) {
10
+ id
11
+ exchangeTime
12
+ exchangeDate
13
+ sfdcCompanyName
14
+ companySize
15
+ customerName
16
+ exchangeType
17
+ customerIndustry
18
+ bu
19
+ businessType
20
+ communicators
21
+ notes
22
+ owner
23
+ preAwsServices
24
+ postAwsServices
25
+ securityBestPractices
26
+ complianceCategory
27
+ preComplianceItems
28
+ postComplianceItems
29
+ workshopLink
30
+ blogLink
31
+ attendeeCount
32
+ emergencyCategory
33
+ problemDescription
34
+ solutionPlan
35
+ trainingServices
36
+ onlineParticipants
37
+ trainingDescription
38
+ aiSecurityStage
39
+ aiSecuritySolution
40
+ aiSecurityWorkshopLink
41
+ oppLink
42
+ oppAmount
43
+ oppStatus
44
+ specReqLink
45
+ accountTeam
46
+ hasFollowUp
47
+ parentExchangeID
48
+ isNotableCase
49
+ createdAt
50
+ updatedAt
51
+ }
52
+ }
53
+ `;
54
+ export const LIST_SECURITY_EXCHANGES = `
55
+ query ListSecurityExchanges($limit: Int, $nextToken: String) {
56
+ listSecurityExchanges(limit: $limit, nextToken: $nextToken) {
57
+ items {
58
+ id
59
+ exchangeTime
60
+ exchangeDate
61
+ sfdcCompanyName
62
+ companySize
63
+ customerName
64
+ exchangeType
65
+ customerIndustry
66
+ bu
67
+ businessType
68
+ communicators
69
+ notes
70
+ owner
71
+ preAwsServices
72
+ postAwsServices
73
+ securityBestPractices
74
+ oppLink
75
+ oppAmount
76
+ oppStatus
77
+ isNotableCase
78
+ createdAt
79
+ updatedAt
80
+ }
81
+ nextToken
82
+ }
83
+ }
84
+ `;
85
+ export const GET_SECURITY_EXCHANGE = `
86
+ query GetSecurityExchange($id: ID!) {
87
+ getSecurityExchange(id: $id) {
88
+ id
89
+ exchangeTime
90
+ exchangeDate
91
+ sfdcCompanyName
92
+ companySize
93
+ customerName
94
+ exchangeType
95
+ customerIndustry
96
+ bu
97
+ businessType
98
+ communicators
99
+ notes
100
+ owner
101
+ preAwsServices
102
+ postAwsServices
103
+ securityBestPractices
104
+ complianceCategory
105
+ preComplianceItems
106
+ postComplianceItems
107
+ workshopLink
108
+ blogLink
109
+ attendeeCount
110
+ emergencyCategory
111
+ problemDescription
112
+ solutionPlan
113
+ trainingServices
114
+ onlineParticipants
115
+ trainingDescription
116
+ aiSecurityStage
117
+ aiSecuritySolution
118
+ aiSecurityWorkshopLink
119
+ oppLink
120
+ oppAmount
121
+ oppStatus
122
+ specReqLink
123
+ accountTeam
124
+ hasFollowUp
125
+ parentExchangeID
126
+ excludedRelatedExchangeIDs
127
+ isNotableCase
128
+ createdAt
129
+ updatedAt
130
+ }
131
+ }
132
+ `;
133
+ export const UPDATE_SECURITY_EXCHANGE = `
134
+ mutation UpdateSecurityExchange($input: UpdateSecurityExchangeInput!) {
135
+ updateSecurityExchange(input: $input) {
136
+ id
137
+ exchangeTime
138
+ exchangeDate
139
+ sfdcCompanyName
140
+ customerName
141
+ exchangeType
142
+ owner
143
+ updatedAt
144
+ }
145
+ }
146
+ `;
147
+ export const DELETE_SECURITY_EXCHANGE = `
148
+ mutation DeleteSecurityExchange($input: DeleteSecurityExchangeInput!) {
149
+ deleteSecurityExchange(input: $input) {
150
+ id
151
+ }
152
+ }
153
+ `;
154
+ // ============================================================
155
+ // Course
156
+ // ============================================================
157
+ export const LIST_COURSES = `
158
+ query ListCourses($limit: Int, $nextToken: String) {
159
+ listCourses(limit: $limit, nextToken: $nextToken) {
160
+ items {
161
+ id
162
+ course_name
163
+ description
164
+ content
165
+ brief_input
166
+ ppt_url
167
+ video_url
168
+ view_count
169
+ resource_url
170
+ owner
171
+ createdAt
172
+ updatedAt
173
+ }
174
+ nextToken
175
+ }
176
+ }
177
+ `;
178
+ export const CREATE_COURSE = `
179
+ mutation CreateCourse($input: CreateCourseInput!) {
180
+ createCourse(input: $input) {
181
+ id
182
+ course_name
183
+ description
184
+ content
185
+ brief_input
186
+ ppt_url
187
+ video_url
188
+ view_count
189
+ resource_url
190
+ owner
191
+ createdAt
192
+ }
193
+ }
194
+ `;
195
+ // ============================================================
196
+ // Solution
197
+ // ============================================================
198
+ export const LIST_SOLUTIONS = `
199
+ query ListSolutions($limit: Int, $nextToken: String) {
200
+ listSolutions(limit: $limit, nextToken: $nextToken) {
201
+ items {
202
+ id
203
+ solutionName
204
+ responsiblePerson
205
+ resourceUrl
206
+ description
207
+ category
208
+ status
209
+ owner
210
+ createdAt
211
+ updatedAt
212
+ }
213
+ nextToken
214
+ }
215
+ }
216
+ `;
217
+ // ============================================================
218
+ // WeeklySummary
219
+ // ============================================================
220
+ export const LIST_WEEKLY_SUMMARIES = `
221
+ query ListWeeklySummaries($limit: Int, $nextToken: String) {
222
+ listWeeklySummaries(limit: $limit, nextToken: $nextToken) {
223
+ items {
224
+ id
225
+ weekStart
226
+ communicator
227
+ summary
228
+ updatedBy
229
+ createdAt
230
+ updatedAt
231
+ }
232
+ nextToken
233
+ }
234
+ }
235
+ `;
236
+ export const CREATE_WEEKLY_SUMMARY = `
237
+ mutation CreateWeeklySummary($input: CreateWeeklySummaryInput!) {
238
+ createWeeklySummary(input: $input) {
239
+ id
240
+ weekStart
241
+ communicator
242
+ summary
243
+ updatedBy
244
+ createdAt
245
+ }
246
+ }
247
+ `;
248
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,+DAA+D;AAC/D,mBAAmB;AACnB,+DAA+D;AAE/D,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CvC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BtC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CpC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;CAavC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;CAMvC,CAAC;AAEF,+DAA+D;AAC/D,SAAS;AACT,+DAA+D;AAE/D,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;CAoB3B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;CAgB5B,CAAC;AAEF,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAE/D,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;CAkB7B,CAAC;AAEF,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAE/D,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;CAepC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;CAWpC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@cmhk-wwso-sec/team-admin-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP Server for Security Team Admin - 通过 MCP 协议访问安全团队管理系统数据",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "sec-team-admin-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "prepublishOnly": "npm run build",
16
+ "start": "node dist/index.js",
17
+ "dev": "tsx src/index.ts"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "security",
22
+ "admin",
23
+ "appsync",
24
+ "graphql"
25
+ ],
26
+ "license": "UNLICENSED",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "^1.12.1",
32
+ "zod": "^3.23.8"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.12.5",
36
+ "tsx": "^4.7.2",
37
+ "typescript": "^5.4.5"
38
+ },
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ }
42
+ }