LINE公式のMCPサーバーを使ってみた話
こんにちは。今回は LINEのMCPサーバー を使ってみた記録を共有します。
🎯 この記事でやること
- DBと連携して公式アカウントと繋がっているユーザーの情報を取得
- ユーザーに対してメッセージを送信
- 【補足】
replyToken
がある場合はリプライ優先に切り替える
1. 🚀 LINE公式のMCPの確認
GitHubで公開されている line-bot-mcp-server
に含まれるサンプルをそのまま動かすと、
以下のような基本機能がすぐ使えます。
📦 初期状態でできること
- 環境変数
LINE_USER_ID
に指定したユーザーに対してプッシュメッセージを送信可能 - 同様に、そのユーザーの ユーザー情報(プロフィール)を取得可能
-
flexMessage
も簡単に送信できる
例えば、Claude Desktopに自然言語でお願いすると、以下のようなメッセージ送信ができます(作るだけじゃなくて本当に送ってくれる)
{
"type": "flex",
"altText": "注文が入りました!",
"contents": {
"type": "bubble",
"body": {
"type": "box",
"layout": "vertical",
"contents": [
{ "type": "text", "text": "注文が入りました!", "weight": "bold", "size": "xl" }
]
}
}
}
2. DB連携で任意のユーザーに送信できるようにした
デフォルトでは環境変数で指定したユーザーIDに対してしか処理ができない仕様になっています。
const userIdSchema = z
.string()
.default(destinationId)
.describe(
"The user ID to receive a message. Defaults to DESTINATION_USER_ID.",
);
他の人にも送るためにはその人のuserIdが必要になります。
そのため、以下のフローを取りました。
🔁 実行したフロー
-
公式アカウントからの WebhookEvent を受け取るための API サーバーを作成
-
API サーバーから DBへ userId を含むイベント履歴を保存
-
DB を読み取る MCP サーバーを作成
-
DB 用 MCP サーバーと LINE 公式の MCP サーバーを連携
これにより、アクションのあったメンバー全員に対してメッセージを送ることができるようになりました。
3. 使ってみた
まず公式アカウントをフォローした履歴を見てもらいました。
補足. 💬 replyToken があればリプライを優先するようにした
LINE Messaging API の仕様では、ユーザーのアクションから20分以内だと、そのアクションに対するリプライメッセージを送信できます。(プッシュメッセージよりお財布に優しい)
そのため、デフォルトのMCPサーバーにリプライメッセージ送信用のツールを一つ追加しました。
「リプライ送れそうなら送ってみて」とかお願いすると、できる場合は送るし、できないときはプッシュメッセージに切り替えてくれます。
// 引数用のスキーマ
const replyMessageSchema = z
.object({
flexMessage: flexMessageSchema.optional(),
textMessage: textMessageSchema.optional(),
})
.describe(
"A message object that can be either a flex message or a text message. " +
"when use this schema, flexMessage or textMessage is required",
);
const replyTokenSchema = z
.string()
.describe("The token to reply to the user.");
// 返信用ツール
server.tool(
"reply_text_message",
"Reply to a user with a simple text message via LINE. Use this for sending plain text messages without formatting.",
{
replyToken: replyTokenSchema,
message: replyMessageSchema,
},
async ({ replyToken, message }) => {
if (!replyToken) {
return createErrorResponse("Error: replyToken is required.");
}
const msg = message.flexMessage ?? message.textMessage;
if (!msg) {
return createErrorResponse("Error: message is required.");
}
try {
const response = await messagingApiClient.replyMessage({
replyToken,
messages: [msg as unknown as line.messagingApi.Message],
});
return createSuccessResponse(response);
} catch (error) {
return createErrorResponse(`Failed to reply message: ${error.message}`);
}
},
);
📝 最後に
色々便利だけど、使いこなせていない感。何かもっとこんなことすると面白いというアイデア思いつきたいなと思っています。
あと、Webhookイベントを綺麗に取得sるAPIサーバーの整備をしたけど、そっちの方もすごく便利だなと思いました。GW中にそれの記事書いてみようかな。