「Claude、LINEで連絡して」- MCPで実現する新しい会話の形

<!-- 以下本文 -->
## はじめに
先日サイバーエージェントさん主催のAI Code Agents 祭りに参加してきました。色々な企業・個人のAI活用や今のAIの進化を体感してきましたが、中でもすごそう！と個人的に思ったのが**MCP(Model Context Protocol)** でした。
MCPとは何なのか、復習も兼ねて、実際にMCPサーバーを立ててClaude Desktopから使ってみました。

https://code-agents.connpass.com/event/342240/

## MCPの概要と魅力
### MCP (Model Context Protocol) とは
Anthropicが提唱したLLM(大規模言語モデル)が外部ツールやサービスと通信するためのプロトコルです。LLMが安全に外部サービスの知識や機能を使えるように、通信のクライアントとサーバーが守るべき作法を定めています。まだ盛んに議論されており発展中です。

https://spec.modelcontextprotocol.io/specification/2024-11-05/

### ここがすごそう
LLMは基本的に外界と接続されてないため、知識・能力には限界があります。
LLMエージェントが自社の資料や外部のサービスのAPIを閲覧・操作できるようになるのは必然の流れです。
MCPはどういう風に外部サービスとやりとりするようにすればセキュアにできるかを議論し、標準化しようとしています。
この標準化により、誰もが安全かつ一貫した方法でLLMの機能を拡張できるようになります。
つまり、開発者がMCPサーバーを実装することで、特定の目的に特化したLLMの能力強化が簡単になり、「AIを強化していく時代」が本格的に始まるということですね。
さらにOpenAIがMCPをサポートすることを発表し、ますますデファクトスタンダード感が強くなっている情勢です。

https://x.com/OpenAIDevs/status/1904957755829481737?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1904957755829481737%7Ctwgr%5Ebbdcd531710f92691606c909c278de1a29bf3cf5%7Ctwcon%5Es1_c10&ref_url=https%3A%2F%2Fgihyo.jp%2Farticle%2F2025%2F03%2Fopenai-mcp

## MCPのアーキテクチャ
### 主要コンポーネント
#### 1. MCPサーバー
LLMに機能を提供するサーバーです。
例えば：
- Wether APIから天気を取得する機能を提供
- Github APIを使ってpull requestを作成しpushする機能を提供
#### 2. MCPクライアント
LLMとMCPサーバーを繋ぐ通信の受け取り手となるものです。
例えば：
- Claude Desktop
- CursorやClineなども一部対応
- 自前で作ることも可能


利用可能なクライアントの例↓ 

https://modelcontextprotocol.io/clients

#### 3. LLM（MCPホスト）
MCPクライアントを通じてMCPサーバーの機能を使用する言語モデルです。Claude DesktopならClaude、自前で立てる場合はAPIキーを使ってリモートのLLMまたはローカルLLMを使用します。

## 実装例: MCPサーバーをローカルに立てて、LINE送信機能を実装
百聞は一見にしかずということで、実際にMCPを使ってみることで理解を深めてみます。
### プロジェクト概要
今回は以下の構成で試します：
- MCPクライアント: Claude Desktop
- MCPサーバー: 自前で実装
- 機能: LINE Messaging API経由でClaudeからLINEメッセージを送信

![improved-architecture-diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4025713/42460566-d028-48a3-8d48-01bf86c66477.png)

### 1. MCP Serverの実装
#### 前準備: package.jsonの設定

```json: package.json
{
  "name": "line-mcp-server",
  "version": "1.0.0",
  "main": "build/index.js",
  "scripts": {
    "start": "node build/index.js",
    "build": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.7.0",
    "axios": "^1.8.4",
    "zod": "^3.24.2"
  },
  "devDependencies": {
    "@types/node": "^22.13.11",
    "typescript": "^5.8.2"
  }
}
```

> Point: @modelcontextprotocol/sdk は公式が提供するMCPのSDKです。TypeScript以外にもPython、Java、Kotlinなど様々な言語で利用可能です。


https://github.com/modelcontextprotocol

#### メインのサーバー実装
``` typescript:index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import axios from 'axios';

const server = new McpServer({
  name: "LineMessage",
  version: "1.0.0"
});

server.tool(
  "lineTextMessage",
  { message: z.string() },
  async ({ message }) => {
    try {
      const client = new LineMessagingClient();
      const userId = process.env.LINE_USER_ID;
      if (userId === undefined) {
        return {
          content: [{ type: "text", text: `user_id is null` }]
        };
      }
      
      await client.sendTextMessage(userId, `${message}`);
      
      return {
        content: [{ type: "text", text: `Tool echo: ${message}` }]
      };
    } catch (error) {
      return {
        content: [{ type: "text", text: `Error occured ${error}` }]
      };
    }
  }
);

const transport = new StdioServerTransport();
(async () => {
  await server.connect(transport);
})();
```
#### 技術解説: MCPの主要コンポーネント
##### 1. server.tool の役割
MCPサーバーがMCPクライアントに提供できる機能は3種類あります：
- Prompts: ユーザーが使用できるプロンプトのテンプレート
- Resources: クライアントが使用しモデルに添付できる追加のリソース
- Tools: モデルが使用できるサーバーの機能

今回のサーバーでは、LINE送信機能を「Tool」として提供しています。

https://spec.modelcontextprotocol.io/specification/2024-11-05/server/

##### 2. StdioServerTransport の役割
MCPで定義されている通信路は2種類あります：
- stdio: MCPサーバーを子プロセスとして起動し、標準入出力を通じて通信
- HTTPS with SSE: リモートで起動しているMCPサーバーとやり取り

Claude Desktopはstdioのみ対応しているため、今回はStdioServerTransportを使用しています。

https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/

#### LINE Messaging API 連携部分
``` typescript:index.ts
class LineMessagingClient {
  private readonly channelAccessToken: string;
  private readonly apiUrl: string = 'https://api.line.me/v2/bot/message/push';
  
  constructor() {
    const token = process.env.LINE_CHANNEL_ACCESS_TOKEN;
    
    if (!token) {
      throw new Error('LINE_CHANNEL_ACCESS_TOKEN environment variable is required');
    }

    this.channelAccessToken = token;
  }

  async sendTextMessage(to: string, message: string): Promise<any> {
    const requestData = {
      to,
      messages: [
        {
          type: 'text',
          text: message
        }
      ]
    };
  
    try {
      const response = await axios.post(
        this.apiUrl,
        requestData,
        {
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.channelAccessToken}`
          }
        }
      );
    
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error)) {
        const status = error.response?.status;
        const responseData = error.response?.data;
      
        console.error(`Line API Error (${status}):`);
        if (responseData) {
          console.error('Response data:', responseData);
        }
      
        throw new Error(`Failed to send message: ${error.message}`);
      }  
    
      throw error;
    }
  }
}
```
ここまで終わったら、``npm run build``でjsにトランスパイルしておきます。

### 2. MCPクライアントの設定
Claude Desktopのインストール
MCPクライアントとしてClaude Desktopを使用します。

https://claude.ai/download


Claude Desktopの設定
1. Claude Desktopを起動
2. ファイル > 設定 > 開発者からMCPの設定を開く
3. 構成の編集をクリック
4. claude_desktop_config.jsonを以下のように編集:

``` json:claude_desktop_config.json
{
  "mcpServers": {
    "line": {
      "command": "node",
      "args": ["C:\\path-to-mcp-server\\build\\index.js"],
      "env": {
        "LINE_CHANNEL_ACCESS_TOKEN": "XXXXXXXXXXXXXXXXX",
        "LINE_USER_ID": "XXXXXXXXX"
      }
    }
  }
}
```
重要: "env"の項目にLINEのチャネルアクセストークンと送信先ユーザーIDを設定してください。

### 3. 実際に使ってみる

1. 設定完了後、Claude Desktopを再起動
2. 正常に連携できていれば、右下にハンマーのようなアイコンが表示されます
![スクリーンショット 2025-03-23 17.22.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4025713/bdd149cc-ff9c-487a-87af-8b941dae9d5a.png)

3. 会話の中で「LINE送って」と依頼すると、ツール使用の許可ポップアップが表示
![スクリーンショット 2025-03-23 17.28.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4025713/e68ff49e-3903-46df-9f53-cbe571703486.png)

4. 承諾すると、設定したLINEアカウントにメッセージが送信されます
![IMG_9950.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4025713/15850baa-0427-4524-925d-01f95c0c7dc3.jpeg)

## まとめと今後の展望
### 公式リソース
自前でMCPサーバーを実装しましたが、公式では以下のようなサンプルも提供されています：
- GitHub連携
- Slack連携
- ローカルファイルシステム連携

https://github.com/modelcontextprotocol/servers

### MCPの今後
- MCPはサーバーとクライアントの双方向通信を定義していますが、現状ではサーバーからクライアントへの通信をサポートしているMCPクライアントはほとんどないです。
- 議論が進んでMCPが成熟していけば、MCPサーバーがAI時代のSaaSサービスのようになっていく可能性があります。
- 今後LLMエージェントの機能拡張の標準的な方法として重要になると思われます。

### 学習リソース
Anthropicがチュートリアルを公開しています：

https://modelcontextprotocol.io/introduction

英語ではありますが、MCPを触ってみて理解するには良い教材だと思います。

自分でLLMを強化できるMCPは、これからのAI活用において重要なスキルになりそうです！

<!-- フッター -->

<hr>

### **▼採用情報**<br>
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/