@line-harness/mcp-server 0.6.1 → 0.6.3

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
@@ -119,9 +119,12 @@ function registerSendMessage(server2) {
119
119
  ),
120
120
  messageType: z.enum(["text", "flex"]).default("text").describe(
121
121
  "Message type: 'text' for plain text, 'flex' for Flex Message JSON"
122
+ ),
123
+ altText: z.string().optional().describe(
124
+ "Custom notification preview text for Flex Messages (shown on lock screen). If omitted, auto-extracted from Flex content."
122
125
  )
123
126
  },
124
- async ({ friendId, content, messageType }) => {
127
+ async ({ friendId, content, messageType, altText }) => {
125
128
  try {
126
129
  const client = getClient();
127
130
  const { content: trackedContent } = await autoTrackUrls(
@@ -133,7 +136,8 @@ function registerSendMessage(server2) {
133
136
  const result = await client.friends.sendMessage(
134
137
  friendId,
135
138
  trackedContent,
136
- messageType
139
+ messageType,
140
+ altText
137
141
  );
138
142
  return {
139
143
  content: [
@@ -186,6 +190,9 @@ function registerBroadcast(server2) {
186
190
  "JSON string of segment conditions when targetType is 'segment'. Format: { operator: 'AND'|'OR', rules: [{ type: 'tag_exists'|'tag_not_exists'|'metadata_equals'|'metadata_not_equals'|'ref_code'|'is_following', value: string|boolean|{key,value} }] }"
187
191
  ),
188
192
  scheduledAt: z2.string().optional().describe("ISO 8601 datetime to schedule. Omit to send immediately."),
193
+ altText: z2.string().optional().describe(
194
+ "Custom notification preview text for Flex Messages (shown on lock screen). If omitted, auto-extracted from Flex content."
195
+ ),
189
196
  accountId: z2.string().optional().describe("LINE account ID (uses default if omitted)")
190
197
  },
191
198
  async ({
@@ -196,6 +203,7 @@ function registerBroadcast(server2) {
196
203
  targetTagId,
197
204
  segmentConditions,
198
205
  scheduledAt,
206
+ altText,
199
207
  accountId
200
208
  }) => {
201
209
  try {
@@ -1431,6 +1439,53 @@ function registerManageStaff(server2) {
1431
1439
  );
1432
1440
  }
1433
1441
 
1442
+ // src/tools/upload-image.ts
1443
+ import { z as z18 } from "zod";
1444
+ function registerUploadImage(server2) {
1445
+ server2.tool(
1446
+ "upload_image",
1447
+ "Upload an image to get a public URL for use in LINE messages (Flex Message hero images, image messages, etc.). Accepts base64-encoded image data. Returns public URL.",
1448
+ {
1449
+ data: z18.string().describe("Base64-encoded image data (with or without data:image/...;base64, prefix)"),
1450
+ mimeType: z18.enum(["image/png", "image/jpeg", "image/gif", "image/webp"]).default("image/png").describe("Image MIME type"),
1451
+ filename: z18.string().optional().describe("Optional original filename for reference")
1452
+ },
1453
+ async ({ data, mimeType, filename }) => {
1454
+ try {
1455
+ const client = getClient();
1456
+ const result = await client.images.upload({ data, mimeType, filename });
1457
+ return {
1458
+ content: [
1459
+ {
1460
+ type: "text",
1461
+ text: JSON.stringify(
1462
+ {
1463
+ success: true,
1464
+ url: result.url,
1465
+ key: result.key,
1466
+ mimeType: result.mimeType,
1467
+ size: result.size
1468
+ },
1469
+ null,
1470
+ 2
1471
+ )
1472
+ }
1473
+ ]
1474
+ };
1475
+ } catch (err) {
1476
+ return {
1477
+ content: [
1478
+ {
1479
+ type: "text",
1480
+ text: JSON.stringify({ success: false, error: String(err) })
1481
+ }
1482
+ ]
1483
+ };
1484
+ }
1485
+ }
1486
+ );
1487
+ }
1488
+
1434
1489
  // src/tools/index.ts
1435
1490
  function registerAllTools(server2) {
1436
1491
  registerSendMessage(server2);
@@ -1450,6 +1505,7 @@ function registerAllTools(server2) {
1450
1505
  registerManageAdPlatforms(server2);
1451
1506
  registerGetConversionLogs(server2);
1452
1507
  registerManageStaff(server2);
1508
+ registerUploadImage(server2);
1453
1509
  }
1454
1510
 
1455
1511
  // src/resources/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@line-harness/mcp-server",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
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.2.1",
14
+ "@line-harness/sdk": "workspace:*",
15
15
  "@modelcontextprotocol/sdk": "^1.12.1",
16
16
  "zod": "^3.24.4"
17
17
  },
@@ -37,6 +37,12 @@ export function registerBroadcast(server: McpServer): void {
37
37
  .string()
38
38
  .optional()
39
39
  .describe("ISO 8601 datetime to schedule. Omit to send immediately."),
40
+ altText: z
41
+ .string()
42
+ .optional()
43
+ .describe(
44
+ "Custom notification preview text for Flex Messages (shown on lock screen). If omitted, auto-extracted from Flex content.",
45
+ ),
40
46
  accountId: z
41
47
  .string()
42
48
  .optional()
@@ -50,6 +56,7 @@ export function registerBroadcast(server: McpServer): void {
50
56
  targetTagId,
51
57
  segmentConditions,
52
58
  scheduledAt,
59
+ altText,
53
60
  accountId,
54
61
  }) => {
55
62
  try {
@@ -16,6 +16,7 @@ import { registerListCrmObjects } from "./list-crm-objects.js";
16
16
  import { registerManageAdPlatforms } from "./manage-ad-platforms.js";
17
17
  import { registerGetConversionLogs } from "./get-conversion-logs.js";
18
18
  import { registerManageStaff } from "./manage-staff.js";
19
+ import { registerUploadImage } from "./upload-image.js";
19
20
 
20
21
  export function registerAllTools(server: McpServer): void {
21
22
  registerSendMessage(server);
@@ -35,4 +36,5 @@ export function registerAllTools(server: McpServer): void {
35
36
  registerManageAdPlatforms(server);
36
37
  registerGetConversionLogs(server);
37
38
  registerManageStaff(server);
39
+ registerUploadImage(server);
38
40
  }
@@ -20,8 +20,14 @@ export function registerSendMessage(server: McpServer): void {
20
20
  .describe(
21
21
  "Message type: 'text' for plain text, 'flex' for Flex Message JSON",
22
22
  ),
23
+ altText: z
24
+ .string()
25
+ .optional()
26
+ .describe(
27
+ "Custom notification preview text for Flex Messages (shown on lock screen). If omitted, auto-extracted from Flex content.",
28
+ ),
23
29
  },
24
- async ({ friendId, content, messageType }) => {
30
+ async ({ friendId, content, messageType, altText }) => {
25
31
  try {
26
32
  const client = getClient();
27
33
 
@@ -37,6 +43,7 @@ export function registerSendMessage(server: McpServer): void {
37
43
  friendId,
38
44
  trackedContent,
39
45
  messageType,
46
+ altText,
40
47
  );
41
48
  return {
42
49
  content: [
@@ -0,0 +1,52 @@
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 registerUploadImage(server: McpServer): void {
6
+ server.tool(
7
+ "upload_image",
8
+ "Upload an image to get a public URL for use in LINE messages (Flex Message hero images, image messages, etc.). Accepts base64-encoded image data. Returns public URL.",
9
+ {
10
+ data: z.string().describe("Base64-encoded image data (with or without data:image/...;base64, prefix)"),
11
+ mimeType: z
12
+ .enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
13
+ .default("image/png")
14
+ .describe("Image MIME type"),
15
+ filename: z.string().optional().describe("Optional original filename for reference"),
16
+ },
17
+ async ({ data, mimeType, filename }) => {
18
+ try {
19
+ const client = getClient();
20
+ const result = await client.images.upload({ data, mimeType, filename });
21
+
22
+ return {
23
+ content: [
24
+ {
25
+ type: "text" as const,
26
+ text: JSON.stringify(
27
+ {
28
+ success: true,
29
+ url: result.url,
30
+ key: result.key,
31
+ mimeType: result.mimeType,
32
+ size: result.size,
33
+ },
34
+ null,
35
+ 2,
36
+ ),
37
+ },
38
+ ],
39
+ };
40
+ } catch (err) {
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text" as const,
45
+ text: JSON.stringify({ success: false, error: String(err) }),
46
+ },
47
+ ],
48
+ };
49
+ }
50
+ },
51
+ );
52
+ }