@line-harness/mcp-server 0.7.0 → 0.7.2

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
@@ -725,7 +725,7 @@ import { z as z8 } from "zod";
725
725
  function registerCreateRichMenu(server2) {
726
726
  server2.tool(
727
727
  "create_rich_menu",
728
- "Create a LINE rich menu (the persistent menu at the bottom of the chat). Image must be uploaded separately via LINE Developers Console. This creates the menu structure and button areas.",
728
+ "Create a LINE rich menu with optional image upload. Provide imageData (base64) to attach the menu image in one step.",
729
729
  {
730
730
  name: z8.string().describe("Rich menu name"),
731
731
  chatBarText: z8.string().default("\u30E1\u30CB\u30E5\u30FC").describe("Text shown on the chat bar button"),
@@ -737,9 +737,11 @@ function registerCreateRichMenu(server2) {
737
737
  areas: z8.string().describe(
738
738
  "JSON string of menu button areas. Format: [{ bounds: { x, y, width, height }, action: { type: 'uri'|'message'|'postback', uri?, text?, data? } }]"
739
739
  ),
740
+ imageData: z8.string().optional().describe("Base64-encoded image data for the rich menu (PNG or JPEG, 2500x1686 or 2500x843)"),
741
+ imageContentType: z8.enum(["image/png", "image/jpeg"]).default("image/jpeg").describe("Image MIME type"),
740
742
  setAsDefault: z8.boolean().default(false).describe("Set this as the default rich menu for all friends")
741
743
  },
742
- async ({ name, chatBarText, size, selected, areas, setAsDefault }) => {
744
+ async ({ name, chatBarText, size, selected, areas, imageData, imageContentType, setAsDefault }) => {
743
745
  try {
744
746
  const client = getClient();
745
747
  const menu = await client.richMenus.create({
@@ -749,6 +751,9 @@ function registerCreateRichMenu(server2) {
749
751
  selected,
750
752
  areas: JSON.parse(areas)
751
753
  });
754
+ if (imageData) {
755
+ await client.richMenus.uploadImage(menu.richMenuId, imageData, imageContentType);
756
+ }
752
757
  if (setAsDefault) {
753
758
  await client.richMenus.setDefault(menu.richMenuId);
754
759
  }
@@ -760,6 +765,7 @@ function registerCreateRichMenu(server2) {
760
765
  {
761
766
  success: true,
762
767
  richMenuId: menu.richMenuId,
768
+ imageUploaded: !!imageData,
763
769
  isDefault: setAsDefault
764
770
  },
765
771
  null,
@@ -792,20 +798,23 @@ import { z as z9 } from "zod";
792
798
  function registerListFriends(server2) {
793
799
  server2.tool(
794
800
  "list_friends",
795
- "List friends with optional filtering by tag or name search. Returns paginated results with friend details.",
801
+ "List friends with optional filtering by tag, name search, or metadata values. Returns paginated results with friend details.",
796
802
  {
797
803
  search: z9.string().optional().describe("Search friends by display name (partial match)"),
798
804
  tagId: z9.string().optional().describe("Filter by tag ID"),
805
+ metadataFilter: z9.string().optional().describe(`JSON string of metadata filters. e.g. '{"monthly_cost": "\u301C100\u4E07\u5186", "business_type": "EC\u30FB\u7269\u8CA9"}'`),
799
806
  limit: z9.number().default(20).describe("Number of friends to return (max 100)"),
800
807
  offset: z9.number().default(0).describe("Offset for pagination"),
801
808
  accountId: z9.string().optional().describe("LINE account ID (uses default if omitted)")
802
809
  },
803
- async ({ search, tagId, limit, offset, accountId }) => {
810
+ async ({ search, tagId, metadataFilter, limit, offset, accountId }) => {
804
811
  try {
805
812
  const client = getClient();
813
+ const metadata = metadataFilter ? JSON.parse(metadataFilter) : void 0;
806
814
  const result = await client.friends.list({
807
815
  search,
808
816
  tagId,
817
+ metadata,
809
818
  limit,
810
819
  offset,
811
820
  accountId
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@line-harness/mcp-server",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "line-harness-mcp": "./dist/index.js"
@@ -9,7 +9,7 @@
9
9
  "dependencies": {
10
10
  "@modelcontextprotocol/sdk": "^1.12.1",
11
11
  "zod": "^3.24.4",
12
- "@line-harness/sdk": "0.2.4"
12
+ "@line-harness/sdk": "0.2.6"
13
13
  },
14
14
  "devDependencies": {
15
15
  "tsup": "^8.4.0",
@@ -5,7 +5,7 @@ import { getClient } from "../client.js";
5
5
  export function registerCreateRichMenu(server: McpServer): void {
6
6
  server.tool(
7
7
  "create_rich_menu",
8
- "Create a LINE rich menu (the persistent menu at the bottom of the chat). Image must be uploaded separately via LINE Developers Console. This creates the menu structure and button areas.",
8
+ "Create a LINE rich menu with optional image upload. Provide imageData (base64) to attach the menu image in one step.",
9
9
  {
10
10
  name: z.string().describe("Rich menu name"),
11
11
  chatBarText: z
@@ -34,12 +34,20 @@ export function registerCreateRichMenu(server: McpServer): void {
34
34
  .describe(
35
35
  "JSON string of menu button areas. Format: [{ bounds: { x, y, width, height }, action: { type: 'uri'|'message'|'postback', uri?, text?, data? } }]",
36
36
  ),
37
+ imageData: z
38
+ .string()
39
+ .optional()
40
+ .describe("Base64-encoded image data for the rich menu (PNG or JPEG, 2500x1686 or 2500x843)"),
41
+ imageContentType: z
42
+ .enum(["image/png", "image/jpeg"])
43
+ .default("image/jpeg")
44
+ .describe("Image MIME type"),
37
45
  setAsDefault: z
38
46
  .boolean()
39
47
  .default(false)
40
48
  .describe("Set this as the default rich menu for all friends"),
41
49
  },
42
- async ({ name, chatBarText, size, selected, areas, setAsDefault }) => {
50
+ async ({ name, chatBarText, size, selected, areas, imageData, imageContentType, setAsDefault }) => {
43
51
  try {
44
52
  const client = getClient();
45
53
  const menu = await client.richMenus.create({
@@ -50,6 +58,10 @@ export function registerCreateRichMenu(server: McpServer): void {
50
58
  areas: JSON.parse(areas),
51
59
  });
52
60
 
61
+ if (imageData) {
62
+ await client.richMenus.uploadImage(menu.richMenuId, imageData, imageContentType);
63
+ }
64
+
53
65
  if (setAsDefault) {
54
66
  await client.richMenus.setDefault(menu.richMenuId);
55
67
  }
@@ -62,6 +74,7 @@ export function registerCreateRichMenu(server: McpServer): void {
62
74
  {
63
75
  success: true,
64
76
  richMenuId: menu.richMenuId,
77
+ imageUploaded: !!imageData,
65
78
  isDefault: setAsDefault,
66
79
  },
67
80
  null,
@@ -5,10 +5,14 @@ import { getClient } from "../client.js";
5
5
  export function registerListFriends(server: McpServer): void {
6
6
  server.tool(
7
7
  "list_friends",
8
- "List friends with optional filtering by tag or name search. Returns paginated results with friend details.",
8
+ "List friends with optional filtering by tag, name search, or metadata values. Returns paginated results with friend details.",
9
9
  {
10
10
  search: z.string().optional().describe("Search friends by display name (partial match)"),
11
11
  tagId: z.string().optional().describe("Filter by tag ID"),
12
+ metadataFilter: z
13
+ .string()
14
+ .optional()
15
+ .describe("JSON string of metadata filters. e.g. '{\"monthly_cost\": \"〜100万円\", \"business_type\": \"EC・物販\"}'"),
12
16
  limit: z
13
17
  .number()
14
18
  .default(20)
@@ -19,12 +23,14 @@ export function registerListFriends(server: McpServer): void {
19
23
  .optional()
20
24
  .describe("LINE account ID (uses default if omitted)"),
21
25
  },
22
- async ({ search, tagId, limit, offset, accountId }) => {
26
+ async ({ search, tagId, metadataFilter, limit, offset, accountId }) => {
23
27
  try {
24
28
  const client = getClient();
29
+ const metadata = metadataFilter ? JSON.parse(metadataFilter) as Record<string, string> : undefined;
25
30
  const result = await client.friends.list({
26
31
  search,
27
32
  tagId,
33
+ metadata,
28
34
  limit,
29
35
  offset,
30
36
  accountId,