@line-harness/mcp-server 0.5.0 → 0.6.1

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/dist/index.js CHANGED
@@ -1150,6 +1150,287 @@ function registerListCrmObjects(server2) {
1150
1150
  );
1151
1151
  }
1152
1152
 
1153
+ // src/tools/manage-ad-platforms.ts
1154
+ import { z as z15 } from "zod";
1155
+ function registerManageAdPlatforms(server2) {
1156
+ server2.tool(
1157
+ "manage_ad_platforms",
1158
+ "Manage ad platform integrations for conversion tracking. Supports Meta (Facebook/Instagram), X (Twitter), Google Ads, and TikTok. Use 'list' to see configured platforms, 'create' to add a new one, 'update' to modify settings, 'delete' to remove, or 'test' to verify the connection.",
1159
+ {
1160
+ action: z15.enum(["list", "create", "update", "delete", "test"]).describe("Action to perform"),
1161
+ platformId: z15.string().optional().describe("Platform ID (required for 'update' and 'delete')"),
1162
+ name: z15.enum(["meta", "x", "google", "tiktok"]).optional().describe("Platform name (required for 'create' and 'test')"),
1163
+ displayName: z15.string().optional().describe("Display name for the platform (e.g. 'Meta\u5E83\u544A')"),
1164
+ config: z15.record(z15.unknown()).optional().describe(
1165
+ "Platform config JSON. Meta: {pixel_id, access_token, test_event_code?}. X: {pixel_id, api_key, api_secret}. Google: {customer_id, conversion_action_id, oauth_token}. TikTok: {pixel_code, access_token}"
1166
+ ),
1167
+ isActive: z15.boolean().optional().describe("Enable/disable the platform (for 'update')"),
1168
+ eventName: z15.string().optional().describe("Event name for test conversion (for 'test', e.g. 'Lead')"),
1169
+ friendId: z15.string().optional().describe("Friend ID for test conversion (for 'test')")
1170
+ },
1171
+ async ({ action, platformId, name, displayName, config, isActive, eventName, friendId }) => {
1172
+ try {
1173
+ const client = getClient();
1174
+ switch (action) {
1175
+ case "list": {
1176
+ const platforms = await client.adPlatforms.list();
1177
+ return {
1178
+ content: [
1179
+ {
1180
+ type: "text",
1181
+ text: JSON.stringify(
1182
+ {
1183
+ success: true,
1184
+ count: platforms.length,
1185
+ platforms
1186
+ },
1187
+ null,
1188
+ 2
1189
+ )
1190
+ }
1191
+ ]
1192
+ };
1193
+ }
1194
+ case "create": {
1195
+ if (!name) throw new Error("name is required for create action");
1196
+ if (!config)
1197
+ throw new Error("config is required for create action");
1198
+ const platform = await client.adPlatforms.create({
1199
+ name,
1200
+ displayName,
1201
+ config
1202
+ });
1203
+ return {
1204
+ content: [
1205
+ {
1206
+ type: "text",
1207
+ text: JSON.stringify({ success: true, platform }, null, 2)
1208
+ }
1209
+ ]
1210
+ };
1211
+ }
1212
+ case "update": {
1213
+ if (!platformId)
1214
+ throw new Error("platformId is required for update action");
1215
+ const platform = await client.adPlatforms.update(platformId, {
1216
+ name,
1217
+ displayName,
1218
+ config,
1219
+ isActive
1220
+ });
1221
+ return {
1222
+ content: [
1223
+ {
1224
+ type: "text",
1225
+ text: JSON.stringify({ success: true, platform }, null, 2)
1226
+ }
1227
+ ]
1228
+ };
1229
+ }
1230
+ case "delete": {
1231
+ if (!platformId)
1232
+ throw new Error("platformId is required for delete action");
1233
+ await client.adPlatforms.delete(platformId);
1234
+ return {
1235
+ content: [
1236
+ {
1237
+ type: "text",
1238
+ text: JSON.stringify({
1239
+ success: true,
1240
+ message: `Platform ${platformId} deleted`
1241
+ })
1242
+ }
1243
+ ]
1244
+ };
1245
+ }
1246
+ case "test": {
1247
+ if (!name) throw new Error("name is required for test action");
1248
+ if (!eventName)
1249
+ throw new Error("eventName is required for test action");
1250
+ const result = await client.adPlatforms.test(
1251
+ name,
1252
+ eventName,
1253
+ friendId
1254
+ );
1255
+ return {
1256
+ content: [
1257
+ {
1258
+ type: "text",
1259
+ text: JSON.stringify({ success: true, ...result }, null, 2)
1260
+ }
1261
+ ]
1262
+ };
1263
+ }
1264
+ default:
1265
+ throw new Error(`Unknown action: ${action}`);
1266
+ }
1267
+ } catch (error) {
1268
+ return {
1269
+ content: [
1270
+ {
1271
+ type: "text",
1272
+ text: JSON.stringify(
1273
+ { success: false, error: String(error) },
1274
+ null,
1275
+ 2
1276
+ )
1277
+ }
1278
+ ],
1279
+ isError: true
1280
+ };
1281
+ }
1282
+ }
1283
+ );
1284
+ }
1285
+
1286
+ // src/tools/get-conversion-logs.ts
1287
+ import { z as z16 } from "zod";
1288
+ function registerGetConversionLogs(server2) {
1289
+ server2.tool(
1290
+ "get_conversion_logs",
1291
+ "View ad conversion send logs for a specific platform. Shows the history of conversion events sent to Meta CAPI, X, Google Ads, or TikTok, including status (sent/failed) and error details.",
1292
+ {
1293
+ platformId: z16.string().describe(
1294
+ "Ad platform ID to get logs for. Use manage_ad_platforms with action 'list' first to get the ID."
1295
+ ),
1296
+ limit: z16.number().optional().default(50).describe("Maximum number of logs to return (default: 50)")
1297
+ },
1298
+ async ({ platformId, limit }) => {
1299
+ try {
1300
+ const client = getClient();
1301
+ const logs = await client.adPlatforms.getLogs(platformId, limit);
1302
+ const summary = {
1303
+ total: logs.length,
1304
+ sent: logs.filter((l) => l.status === "sent").length,
1305
+ failed: logs.filter((l) => l.status === "failed").length
1306
+ };
1307
+ return {
1308
+ content: [
1309
+ {
1310
+ type: "text",
1311
+ text: JSON.stringify(
1312
+ { success: true, summary, logs },
1313
+ null,
1314
+ 2
1315
+ )
1316
+ }
1317
+ ]
1318
+ };
1319
+ } catch (error) {
1320
+ return {
1321
+ content: [
1322
+ {
1323
+ type: "text",
1324
+ text: JSON.stringify(
1325
+ { success: false, error: String(error) },
1326
+ null,
1327
+ 2
1328
+ )
1329
+ }
1330
+ ],
1331
+ isError: true
1332
+ };
1333
+ }
1334
+ }
1335
+ );
1336
+ }
1337
+
1338
+ // src/tools/manage-staff.ts
1339
+ import { z as z17 } from "zod";
1340
+ function registerManageStaff(server2) {
1341
+ server2.tool(
1342
+ "manage_staff",
1343
+ "\u30B9\u30BF\u30C3\u30D5\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u8FFD\u52A0\u30FB\u4E00\u89A7\u30FB\u66F4\u65B0\u30FB\u524A\u9664\u30FBAPI\u30AD\u30FC\u518D\u751F\u6210\u3002\u30AA\u30FC\u30CA\u30FC\u6A29\u9650\u304C\u5FC5\u8981\u3067\u3059\u3002",
1344
+ {
1345
+ action: z17.enum(["create", "list", "get", "update", "delete", "regenerate_key", "me"]).describe("Action to perform"),
1346
+ name: z17.string().optional().describe("Staff name (for 'create' action)"),
1347
+ email: z17.string().nullable().optional().describe("Staff email (optional, null to clear)"),
1348
+ role: z17.enum(["admin", "staff"]).optional().describe("Staff role (for 'create'/'update')"),
1349
+ staffId: z17.string().optional().describe("Staff ID (for 'get','update','delete','regenerate_key')"),
1350
+ isActive: z17.boolean().optional().describe("Activate/deactivate (for 'update')")
1351
+ },
1352
+ async ({ action, name, email, role, staffId, isActive }) => {
1353
+ try {
1354
+ const client = getClient();
1355
+ if (action === "me") {
1356
+ const profile = await client.staff.me();
1357
+ return {
1358
+ content: [{ type: "text", text: JSON.stringify({ success: true, profile }, null, 2) }]
1359
+ };
1360
+ }
1361
+ if (action === "list") {
1362
+ const members = await client.staff.list();
1363
+ return {
1364
+ content: [{ type: "text", text: JSON.stringify({ success: true, members }, null, 2) }]
1365
+ };
1366
+ }
1367
+ if (action === "create") {
1368
+ if (!name) throw new Error("name is required for create action");
1369
+ if (!role) throw new Error("role is required for create action");
1370
+ const member = await client.staff.create({ name, email, role });
1371
+ return {
1372
+ content: [{
1373
+ type: "text",
1374
+ text: JSON.stringify({
1375
+ success: true,
1376
+ member,
1377
+ note: "API\u30AD\u30FC\u306F\u4E00\u5EA6\u3060\u3051\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u5B89\u5168\u306B\u4FDD\u7BA1\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
1378
+ }, null, 2)
1379
+ }]
1380
+ };
1381
+ }
1382
+ if (action === "get") {
1383
+ if (!staffId) throw new Error("staffId is required for get action");
1384
+ const member = await client.staff.get(staffId);
1385
+ return {
1386
+ content: [{ type: "text", text: JSON.stringify({ success: true, member }, null, 2) }]
1387
+ };
1388
+ }
1389
+ if (action === "update") {
1390
+ if (!staffId) throw new Error("staffId is required for update action");
1391
+ const updates = {};
1392
+ if (name !== void 0) updates.name = name;
1393
+ if (email !== void 0) updates.email = email;
1394
+ if (role !== void 0) updates.role = role;
1395
+ if (isActive !== void 0) updates.isActive = isActive;
1396
+ const member = await client.staff.update(staffId, updates);
1397
+ return {
1398
+ content: [{ type: "text", text: JSON.stringify({ success: true, member }, null, 2) }]
1399
+ };
1400
+ }
1401
+ if (action === "delete") {
1402
+ if (!staffId) throw new Error("staffId is required for delete action");
1403
+ await client.staff.delete(staffId);
1404
+ return {
1405
+ content: [{ type: "text", text: JSON.stringify({ success: true, deleted: staffId }, null, 2) }]
1406
+ };
1407
+ }
1408
+ if (action === "regenerate_key") {
1409
+ if (!staffId) throw new Error("staffId is required for regenerate_key action");
1410
+ const result = await client.staff.regenerateKey(staffId);
1411
+ return {
1412
+ content: [{
1413
+ type: "text",
1414
+ text: JSON.stringify({
1415
+ success: true,
1416
+ staffId,
1417
+ newApiKey: result.apiKey,
1418
+ note: "\u65B0\u3057\u3044API\u30AD\u30FC\u306F\u4E00\u5EA6\u3060\u3051\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u5B89\u5168\u306B\u4FDD\u7BA1\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
1419
+ }, null, 2)
1420
+ }]
1421
+ };
1422
+ }
1423
+ throw new Error(`Unknown action: ${action}`);
1424
+ } catch (error) {
1425
+ return {
1426
+ content: [{ type: "text", text: JSON.stringify({ success: false, error: String(error) }, null, 2) }],
1427
+ isError: true
1428
+ };
1429
+ }
1430
+ }
1431
+ );
1432
+ }
1433
+
1153
1434
  // src/tools/index.ts
1154
1435
  function registerAllTools(server2) {
1155
1436
  registerSendMessage(server2);
@@ -1166,6 +1447,9 @@ function registerAllTools(server2) {
1166
1447
  registerGetLinkClicks(server2);
1167
1448
  registerAccountSummary(server2);
1168
1449
  registerListCrmObjects(server2);
1450
+ registerManageAdPlatforms(server2);
1451
+ registerGetConversionLogs(server2);
1452
+ registerManageStaff(server2);
1169
1453
  }
1170
1454
 
1171
1455
  // src/resources/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@line-harness/mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "line-harness-mcp": "./dist/index.js"
@@ -11,7 +11,7 @@
11
11
  "dev": "tsup --watch"
12
12
  },
13
13
  "dependencies": {
14
- "@line-harness/sdk": "^0.1.0",
14
+ "@line-harness/sdk": "^0.2.1",
15
15
  "@modelcontextprotocol/sdk": "^1.12.1",
16
16
  "zod": "^3.24.4"
17
17
  },
@@ -0,0 +1,61 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { getClient } from "../client.js";
4
+
5
+ export function registerGetConversionLogs(server: McpServer): void {
6
+ server.tool(
7
+ "get_conversion_logs",
8
+ "View ad conversion send logs for a specific platform. Shows the history of conversion events sent to Meta CAPI, X, Google Ads, or TikTok, including status (sent/failed) and error details.",
9
+ {
10
+ platformId: z
11
+ .string()
12
+ .describe(
13
+ "Ad platform ID to get logs for. Use manage_ad_platforms with action 'list' first to get the ID.",
14
+ ),
15
+ limit: z
16
+ .number()
17
+ .optional()
18
+ .default(50)
19
+ .describe("Maximum number of logs to return (default: 50)"),
20
+ },
21
+ async ({ platformId, limit }) => {
22
+ try {
23
+ const client = getClient();
24
+ const logs = await client.adPlatforms.getLogs(platformId, limit);
25
+
26
+ const summary = {
27
+ total: logs.length,
28
+ sent: logs.filter((l) => l.status === "sent").length,
29
+ failed: logs.filter((l) => l.status === "failed").length,
30
+ };
31
+
32
+ return {
33
+ content: [
34
+ {
35
+ type: "text" as const,
36
+ text: JSON.stringify(
37
+ { success: true, summary, logs },
38
+ null,
39
+ 2,
40
+ ),
41
+ },
42
+ ],
43
+ };
44
+ } catch (error) {
45
+ return {
46
+ content: [
47
+ {
48
+ type: "text" as const,
49
+ text: JSON.stringify(
50
+ { success: false, error: String(error) },
51
+ null,
52
+ 2,
53
+ ),
54
+ },
55
+ ],
56
+ isError: true,
57
+ };
58
+ }
59
+ },
60
+ );
61
+ }
@@ -13,6 +13,9 @@ import { registerGetFormSubmissions } from "./get-form-submissions.js";
13
13
  import { registerGetLinkClicks } from "./get-link-clicks.js";
14
14
  import { registerAccountSummary } from "./account-summary.js";
15
15
  import { registerListCrmObjects } from "./list-crm-objects.js";
16
+ import { registerManageAdPlatforms } from "./manage-ad-platforms.js";
17
+ import { registerGetConversionLogs } from "./get-conversion-logs.js";
18
+ import { registerManageStaff } from "./manage-staff.js";
16
19
 
17
20
  export function registerAllTools(server: McpServer): void {
18
21
  registerSendMessage(server);
@@ -29,4 +32,7 @@ export function registerAllTools(server: McpServer): void {
29
32
  registerGetLinkClicks(server);
30
33
  registerAccountSummary(server);
31
34
  registerListCrmObjects(server);
35
+ registerManageAdPlatforms(server);
36
+ registerGetConversionLogs(server);
37
+ registerManageStaff(server);
32
38
  }
@@ -0,0 +1,170 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { getClient } from "../client.js";
4
+
5
+ export function registerManageAdPlatforms(server: McpServer): void {
6
+ server.tool(
7
+ "manage_ad_platforms",
8
+ "Manage ad platform integrations for conversion tracking. Supports Meta (Facebook/Instagram), X (Twitter), Google Ads, and TikTok. Use 'list' to see configured platforms, 'create' to add a new one, 'update' to modify settings, 'delete' to remove, or 'test' to verify the connection.",
9
+ {
10
+ action: z
11
+ .enum(["list", "create", "update", "delete", "test"])
12
+ .describe("Action to perform"),
13
+ platformId: z
14
+ .string()
15
+ .optional()
16
+ .describe("Platform ID (required for 'update' and 'delete')"),
17
+ name: z
18
+ .enum(["meta", "x", "google", "tiktok"])
19
+ .optional()
20
+ .describe("Platform name (required for 'create' and 'test')"),
21
+ displayName: z
22
+ .string()
23
+ .optional()
24
+ .describe("Display name for the platform (e.g. 'Meta広告')"),
25
+ config: z
26
+ .record(z.unknown())
27
+ .optional()
28
+ .describe(
29
+ "Platform config JSON. Meta: {pixel_id, access_token, test_event_code?}. X: {pixel_id, api_key, api_secret}. Google: {customer_id, conversion_action_id, oauth_token}. TikTok: {pixel_code, access_token}",
30
+ ),
31
+ isActive: z
32
+ .boolean()
33
+ .optional()
34
+ .describe("Enable/disable the platform (for 'update')"),
35
+ eventName: z
36
+ .string()
37
+ .optional()
38
+ .describe("Event name for test conversion (for 'test', e.g. 'Lead')"),
39
+ friendId: z
40
+ .string()
41
+ .optional()
42
+ .describe("Friend ID for test conversion (for 'test')"),
43
+ },
44
+ async ({ action, platformId, name, displayName, config, isActive, eventName, friendId }) => {
45
+ try {
46
+ const client = getClient();
47
+
48
+ switch (action) {
49
+ case "list": {
50
+ const platforms = await client.adPlatforms.list();
51
+ return {
52
+ content: [
53
+ {
54
+ type: "text" as const,
55
+ text: JSON.stringify(
56
+ {
57
+ success: true,
58
+ count: platforms.length,
59
+ platforms,
60
+ },
61
+ null,
62
+ 2,
63
+ ),
64
+ },
65
+ ],
66
+ };
67
+ }
68
+
69
+ case "create": {
70
+ if (!name) throw new Error("name is required for create action");
71
+ if (!config)
72
+ throw new Error("config is required for create action");
73
+
74
+ const platform = await client.adPlatforms.create({
75
+ name,
76
+ displayName,
77
+ config,
78
+ });
79
+
80
+ return {
81
+ content: [
82
+ {
83
+ type: "text" as const,
84
+ text: JSON.stringify({ success: true, platform }, null, 2),
85
+ },
86
+ ],
87
+ };
88
+ }
89
+
90
+ case "update": {
91
+ if (!platformId)
92
+ throw new Error("platformId is required for update action");
93
+
94
+ const platform = await client.adPlatforms.update(platformId, {
95
+ name,
96
+ displayName,
97
+ config,
98
+ isActive,
99
+ });
100
+
101
+ return {
102
+ content: [
103
+ {
104
+ type: "text" as const,
105
+ text: JSON.stringify({ success: true, platform }, null, 2),
106
+ },
107
+ ],
108
+ };
109
+ }
110
+
111
+ case "delete": {
112
+ if (!platformId)
113
+ throw new Error("platformId is required for delete action");
114
+
115
+ await client.adPlatforms.delete(platformId);
116
+ return {
117
+ content: [
118
+ {
119
+ type: "text" as const,
120
+ text: JSON.stringify({
121
+ success: true,
122
+ message: `Platform ${platformId} deleted`,
123
+ }),
124
+ },
125
+ ],
126
+ };
127
+ }
128
+
129
+ case "test": {
130
+ if (!name) throw new Error("name is required for test action");
131
+ if (!eventName)
132
+ throw new Error("eventName is required for test action");
133
+
134
+ const result = await client.adPlatforms.test(
135
+ name,
136
+ eventName,
137
+ friendId,
138
+ );
139
+
140
+ return {
141
+ content: [
142
+ {
143
+ type: "text" as const,
144
+ text: JSON.stringify({ success: true, ...result }, null, 2),
145
+ },
146
+ ],
147
+ };
148
+ }
149
+
150
+ default:
151
+ throw new Error(`Unknown action: ${action}`);
152
+ }
153
+ } catch (error) {
154
+ return {
155
+ content: [
156
+ {
157
+ type: "text" as const,
158
+ text: JSON.stringify(
159
+ { success: false, error: String(error) },
160
+ null,
161
+ 2,
162
+ ),
163
+ },
164
+ ],
165
+ isError: true,
166
+ };
167
+ }
168
+ },
169
+ );
170
+ }
@@ -0,0 +1,104 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { getClient } from "../client.js";
4
+
5
+ export function registerManageStaff(server: McpServer): void {
6
+ server.tool(
7
+ "manage_staff",
8
+ "スタッフアカウントの追加・一覧・更新・削除・APIキー再生成。オーナー権限が必要です。",
9
+ {
10
+ action: z
11
+ .enum(["create", "list", "get", "update", "delete", "regenerate_key", "me"])
12
+ .describe("Action to perform"),
13
+ name: z.string().optional().describe("Staff name (for 'create' action)"),
14
+ email: z.string().nullable().optional().describe("Staff email (optional, null to clear)"),
15
+ role: z.enum(["admin", "staff"]).optional().describe("Staff role (for 'create'/'update')"),
16
+ staffId: z.string().optional().describe("Staff ID (for 'get','update','delete','regenerate_key')"),
17
+ isActive: z.boolean().optional().describe("Activate/deactivate (for 'update')"),
18
+ },
19
+ async ({ action, name, email, role, staffId, isActive }) => {
20
+ try {
21
+ const client = getClient();
22
+
23
+ if (action === "me") {
24
+ const profile = await client.staff.me();
25
+ return {
26
+ content: [{ type: "text" as const, text: JSON.stringify({ success: true, profile }, null, 2) }],
27
+ };
28
+ }
29
+
30
+ if (action === "list") {
31
+ const members = await client.staff.list();
32
+ return {
33
+ content: [{ type: "text" as const, text: JSON.stringify({ success: true, members }, null, 2) }],
34
+ };
35
+ }
36
+
37
+ if (action === "create") {
38
+ if (!name) throw new Error("name is required for create action");
39
+ if (!role) throw new Error("role is required for create action");
40
+ const member = await client.staff.create({ name, email, role });
41
+ return {
42
+ content: [{
43
+ type: "text" as const,
44
+ text: JSON.stringify({
45
+ success: true, member,
46
+ note: "APIキーは一度だけ表示されます。安全に保管してください。",
47
+ }, null, 2),
48
+ }],
49
+ };
50
+ }
51
+
52
+ if (action === "get") {
53
+ if (!staffId) throw new Error("staffId is required for get action");
54
+ const member = await client.staff.get(staffId);
55
+ return {
56
+ content: [{ type: "text" as const, text: JSON.stringify({ success: true, member }, null, 2) }],
57
+ };
58
+ }
59
+
60
+ if (action === "update") {
61
+ if (!staffId) throw new Error("staffId is required for update action");
62
+ const updates: Record<string, unknown> = {};
63
+ if (name !== undefined) updates.name = name;
64
+ if (email !== undefined) updates.email = email;
65
+ if (role !== undefined) updates.role = role;
66
+ if (isActive !== undefined) updates.isActive = isActive;
67
+ const member = await client.staff.update(staffId, updates);
68
+ return {
69
+ content: [{ type: "text" as const, text: JSON.stringify({ success: true, member }, null, 2) }],
70
+ };
71
+ }
72
+
73
+ if (action === "delete") {
74
+ if (!staffId) throw new Error("staffId is required for delete action");
75
+ await client.staff.delete(staffId);
76
+ return {
77
+ content: [{ type: "text" as const, text: JSON.stringify({ success: true, deleted: staffId }, null, 2) }],
78
+ };
79
+ }
80
+
81
+ if (action === "regenerate_key") {
82
+ if (!staffId) throw new Error("staffId is required for regenerate_key action");
83
+ const result = await client.staff.regenerateKey(staffId);
84
+ return {
85
+ content: [{
86
+ type: "text" as const,
87
+ text: JSON.stringify({
88
+ success: true, staffId, newApiKey: result.apiKey,
89
+ note: "新しいAPIキーは一度だけ表示されます。安全に保管してください。",
90
+ }, null, 2),
91
+ }],
92
+ };
93
+ }
94
+
95
+ throw new Error(`Unknown action: ${action}`);
96
+ } catch (error) {
97
+ return {
98
+ content: [{ type: "text" as const, text: JSON.stringify({ success: false, error: String(error) }, null, 2) }],
99
+ isError: true,
100
+ };
101
+ }
102
+ },
103
+ );
104
+ }