MCPで飲み会番長をつくる

# はじめに
## 背景と目的
最近MCPという言葉をよく聞きます。皆さんが分かりやすい記事を出してくださっているものの、実際にMCPで何ができるのか、ドキュメントだけだとイメージが掴みきれなかったので、とりあえず簡単なデモを作って理解を深めようと思い立ちました。
テーマはなんでも良かったのですが、意外と時間が割かれる飲み会セッティングに着目し、この一連の流れを自動化する『飲み会番長』をClaude Desktopで実装してみました。

## MCPとは何か (Model Context Protocol)
MCPとは、AIアシスタントとあらゆるデータソースをつなぐための新しいオープン標準です。従来はツールや情報源ごとに個別のコネクタを作る必要があり、LLMが十分に外部データを活用しにくいという課題がありました。MCPを導入すると、標準化された方法でデータを公開・利用でき、たとえば企業のコンテンツリポジトリやシステムなどと容易に接続可能になります。これにより、AIが必要な情報を適切に取得して高度な応答や機能を実現しやすくなると期待されています。
[[1]](https://www.anthropic.com/news/model-context-protocol "Introducing the Model Context Protocol")

<img width=25%><img width=50% src="https://aisouken.blob.core.windows.net/article/10098/Claude%20MCP%E3%81%A8%E3%81%AF.webp">

※[【Anthoropic】Claude MCPとは？使い方・料金体系を徹底解説！](https://www.ai-souken.com/article/claude-mcp-overview "【Anthoropic】Claude MCPとは？使い方・料金体系を徹底解説！")から引用。

なお、MCPについての詳細は、以下の記事なども参考にできるかと思います。

https://speakerdeck.com/minorun365/yasasiimcpru-men

https://speakerdeck.com/shuntaka/introduction-to-mcp

https://zenn.dev/cloud_ace/articles/model-context-protocol

# デモアプリ『飲み会番長』の実装
## 概要
改めて、今回の「飲み会番長」では、主にClaudeとの対話を通じてお店を探し、最終的に得られた情報をSlackやGoogleカレンダーに連携する構成を採っています。具体的な流れは次のとおりです。

1. ユーザーが「金曜19時に渋谷で飲み会をしたい」「いい店探して」などと、Claudeに対して自然言語で指示を与える
2. Claudeは指示を解析し、必要に応じてMCP経由でBrave SearchやGoogle Mapsを呼び出す
3. Brave Searchで該当エリアのおすすめ店を検索し、候補を洗い出す
4. Google Maps APIを使って店の住所・評価・経路などを取得
5. Claudeは得られた情報（場所、候補店、予約ページなど）をまとめる
6. その内容をSlackに送信し、ユーザーに通知を行う
7. 同時に、決定した日程や場所をGoogleカレンダーに登録しておき、後から日程確認できるようにする

ざっくりと以下のようなイメージになります。
![スクリーンショット 2025-04-09 10.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632319/c0be9999-5668-4d7d-b391-e2a48b64448c.png)

## 手順
基本的にはこのGitに記載の手順を追えば実装することができます。

https://github.com/modelcontextprotocol/servers

### Claude Desktop, Node.jsをインストールする
まずはClaude Desktop, Node.jsをインストールします。Node.jsに関してはDockerを使う方法もありますが、今回は実装の容易さからNode.jsを選定しました。なお、インストールの際は以下を参考にさせていただきました。

https://note.com/maasaam276/n/ne3b61e239a0c

### SlackのAppを作成し、トークン等取得する
先にSlackのAppを作成し、SLACK_BOT_TOKEN, SLACK_TEAM_IDを取得します。既にAppがある方はそちらを使っていただくでも良いです。ここでは以下を参考にさせていただきました。

https://qiita.com/odm_knpr0122/items/04c342ec8d9fe85e0fe9

### Brave Search APIの取得
以下からBrave SearchのAPIを取得します。アカウントを持っていない際は登録からになり、月間2,000クエリまでであれば無料で使用することができます。

https://brave.com/search/api/

### Google MapのAPI取得
Google MapのAPIを取得します。こちらは以下を参考にさせていただきました。

https://www.softmachine.jp/blog/2024/02/%E3%80%90%E6%84%8F%E5%A4%96%E3%81%A8%E7%B0%A1%E5%8D%98%E3%80%91google-maps-api%E3%82%AD%E3%83%BC%E3%81%AE%E5%8F%96%E5%BE%97%E3%83%BB%E5%B0%8E%E5%85%A5%E3%80%90api%E3%82%AD%E3%83%BC%E3%81%AE%E5%8F%96/

### Google Calender APIの取得
これは上記のものと比べて少し手間がかかりましたが、基本的には以下のGitを参考にすれば設定ができます。注意点としては、APIを有効化することを忘れない、ユーザーの種類を外部にした場合はテストユーザーを追加する、ポートが埋まってたら適宜解放する、などです。

https://github.com/nspady/google-calendar-mcp?tab=readme-ov-file

### claude_desktop_config.jsonに記載する
上記で取得したAPIなどをclaude_desktop_config.jsonに記載します。Node.jsかDockerかで若干書き方が変わりますが、以下Node.jsの場合のサンプルを記載します。

```python
{
    "mcpServers": {
      "brave-search": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-brave-search"],
        "env": {
          "BRAVE_API_KEY": "YOUR_BRAVE_API"
        }
      },
      "google-maps": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-google-maps"],
        "env": {
          "GOOGLE_MAPS_API_KEY": "YOUR_MAPS_API"
        }
      },
      "slack": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-slack"],
        "env": {
          "SLACK_BOT_TOKEN": "YOUR_BOT_TOKEN",
          "SLACK_TEAM_ID": "YOUR_TEAM_ID"
        }
      },
      "google-calendar": {
        "command": "node",
        "args": ["YOUR_PATH"]
      }
      
    }
  }
```
## 結果
以下のクエリをClaudeに投げてみます。
> 渋谷で明日19時から10名で入れる空いている居酒屋を探し、レビューの良い店1つを選んでください。
お店のポイントや赤坂見附駅からの行き方などをおっちゃん風でSlackで教えてください。
最後にgoogle calenderに2時間枠で予定を入れてください。

Claudeでは以下のように、必要なツールを使いながら実行を進めています。
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632319/bcde6a51-8f24-45d2-8c47-13439cdef441.png" width="500" />
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632319/17fbdb7e-c76a-4c5b-8219-ad7fb214ed0c.png" width="500" />


Slackでは以下のように、おっちゃんが明日のことを知らせてくれます。ちなみに出てきたお店は[こちら](https://tabelog.com/tokyo/A1303/A130301/13158470/)ですね。

同時にGoogle Calenderにも登録されました。
<p align="center">
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632319/025b2377-e0b1-4959-b928-487d3fcf703b.jpeg" width="300" />
</p>

# MCPがもたらす柔軟性と課題
MCPを使って実装した今回の「飲み会番長」から分かる通り、MCPはLLMに非常に柔軟なツール連携能力を与える仕組みです。開発者が個別にAPIを呼び出して処理を組む必要はなく、「必要なら検索して」「予定をカレンダーに登録して」と自然言語で促すだけで、LLM自身が必要なツールを選んで呼び出してくれるのが大きな魅力です。

一方で、「すべてMCPでやるべきか？」というと、そうでもないというのが正直な感想です。たとえば一つのAPIだけを呼び出して定型処理するようなケースであれば、素直に普通のAPIクライアントとして実装した方が手軽で柔軟だったりもします。MCPは複数のツールを横断した処理や、LLMに判断と行動を任せたいケースに向いている印象です。今回のように「人の自然な指示をもとに、複数サービスを横断してタスクをこなす」といったユースケースでは、その力を発揮します。

また、MCPは非常に便利な反面、いくつか注意点や運用上の課題もあります。
例えば、セキュリティと権限管理の慎重さが挙げられます。
MCP経由でLLMにツールへのアクセス権を与えるということは、たとえばファイル操作やカレンダー登録などをLLMの判断で実行できるようにするということでもあります。設定によっては、誤った操作で意図しない情報の変更・削除が起きたり、過剰な権限でデータ漏洩のリスクも生まれます。今後こうしたAIアシスタントを継続的に使う場合は、LLMが行った操作履歴を記録・確認できるような管理機能を用意しておくのが理想かと考えられます。

このように、MCPは「自然言語を起点に、LLMを介して外部サービスをつなげる」という開発パラダイムそのものを一段階進化させる仕組みです。ただし、便利なだけでなく、その裏で起きる操作やデータの動きを開発者がきちんと把握・管理できるように設計することが、実用化のためのカギになりそうです。

# さいごに
技術の理解を深めるには、やはり簡単な実装をしてみるのが一番わかりやすいと改めて感じました。
今後、MCPを利用したさまざまな連携が想定されますが、他の技術と同様に「どのような目的で」「どのような設計をし」「MCPの利用によって何が嬉しいのか」をあらかじめ明確にしておくことが重要です。そうすることで、MCPを活用する意義がよりいっそう際立つはずです。今後も色々と取り組んでみようと思います。

# 参考/引用文献
- [1] "Introducing the Model Context Protocol" , https://www.anthropic.com/news/model-context-protocol