MCPサーバーの機能を全部（Prompt, Resource, Tool）試してみる

# はじめに

先日AnthropicからMCP ([Model Context Protocol](https://modelcontextprotocol.io/introduction)) が発表され話題になっています。

MCPのサーバー側の基本機能としてはPrompt, Resource, Toolの３つが存在するのですが、SNS等で話題になっているMCPの利用例はToolの利用がほとんどであり、その他のResourceやPromptについては触れられているものが少なかったので、調べてみることにしました。


# MCPサーバーの３つの基本機能について

下記ページに記載の内容を日本語で整理します。

https://spec.modelcontextprotocol.io/specification/server/


> Prompts：LLMとのインタラクションをガイドする、事前定義されたテンプレートや指示
Resources：モデルに追加のコンテキストを提供する構造化データやコンテンツ
Tools：モデルが操作を行ったり、情報を取得したりできるようにする実行可能な関数
>
> 各要素は、以下の制御階層でまとめることができます。
>
| プリミティブ | 制御主体 | 説明 | 例 |
|--------------|----------|------|----|
| Prompts| ユーザー制御 | ユーザーの選択によって呼び出される対話型テンプレート | スラッシュコマンド、メニューオプション |
| Resources | アプリケーション制御 | クライアントによって付与・管理されるコンテキストデータ | ファイル内容、Git履歴 |
| Tools | モデル制御 | LLM（大規模言語モデル）に公開された実行関数 | API POSTリクエスト、ファイル書き込み |


また、大きな違いとしてPromptとToolは呼び出し時に変数を渡せるのに対し、ResourceはURIを指定することしかできません。
https://spec.modelcontextprotocol.io/specification/server/prompts/#getting-a-prompt
https://spec.modelcontextprotocol.io/specification/server/resources/#reading-resources
https://spec.modelcontextprotocol.io/specification/server/tools/#calling-tools


# Claude Desktop Appでの活用例

実際に、それぞれの機能を提供するMCPサーバーを、Claudeのデスクトップアプリを通して触ってみます。
(Apple sillicon, MacOS 15.1.1）

## Prompt
### Everything MCP Server
まずは簡単な例を確かめるために、以下のeverythingサーバーを使ってみます。

https://github.com/modelcontextprotocol/servers/tree/main/src/everything

この中で提供されているPromptは以下の２つです
- simple_prompt: シンプルな固定prompt
- complex_prompt: 変数ありのprompt

このサーバーを設定してClaudeを起動してみるとファイルを添付するボタンの横に `Attach from MCP` というボタンが出現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/6944ae83-8781-c076-aa66-22c64323e494.png)


このボタンをクリックすると、サーバーで定義されているPromptが表示されました。
（後述するResourceもここに表示されています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/bae64a1a-c1c9-ec9d-a084-9f56816e239f.png)

実際に `simple_prompt` を選択してみるとこのようにtxtファイルが添付されるだけでした。
選んだらpromptが展開される挙動を期待していたのですが、現状はそこまで実装されていないようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/e34323a6-ae51-0f9a-55e5-b5920affea1e.png)


続いて変数ありの `complex_prompt` を選択してみると、変数の入力モーダルが展開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/77db2a5a-a4fc-5c27-9719-da035ba037a9.png)

ただしこれも、値を入力してsubmitすると添付ファイルができるだけでした。
もちろんこれでも十分プロンプトテンプレートを提供する機能は果たせていますが、体験としてはちょっと物足りないかなと感じました。

### Fetch MCP Server

もう１つ、Prompt機能を提供しているサーバーがあったので、こちらも試してみます。

https://github.com/modelcontextprotocol/servers/tree/main/src/fetch

このサーバーでは、URLを引数として渡せる `fetch` promptが提供されています。

先ほど同様、設定をしてClaudeを起動すると `fetch` というpromptが選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/6b8423ea-82d7-71c7-8dc3-c04c7b1af2cd.png)

試しにqiitaのtopページのurlを入れてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/911fd8a1-b9d1-9f6a-60fe-432f3c759988.png)

すると先ほど同様に、txtファイルが添付ファイルとして添付されました。
そのファイルの中身を見てみるとPromptではなく実際にfetchしてきた内容そのものが入っていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/856d28a6-f2d7-1368-7183-c92528bf6446.png)


個人的にはPromptの使い方としてはあくまで、MCPサーバー内のツールをうまく使えるプロンプトなどをスラッシュコマンドなどで呼び出し、展開するようなものだと考えていました。
しかしこのように、ResourceのURI指定だけだと対応できない、動的なコンテキスト付与を行いたい場合にもPromptが活用できるようです。

## Resource

### Google Drive server
Resourceに関してはGoogle DriveのMCPサーバーを使って検証します。

https://github.com/modelcontextprotocol/servers/tree/main/src/gdrive

<details><summary>Google Driveサーバーの設定</summary>


google driveのサーバーだけ、READMEの通りだとうまくいかなかったので少し設定を補足します。
まずREADMEの[Getting started](https://github.com/modelcontextprotocol/servers/tree/main/src/gdrive#getting-started)の1~6までを実行します。

その後
```sh
# このリポジトリをclone
git clone git@github.com:modelcontextprotocol/servers.git

# 6で落としてきたjsonファイルを `servers/` に　`gcp-oauth.keys.json` という名前で置く
mv （DLしてきたcredential情報が載っているjson） servers/gcp-oauth.keys.json

# ディレクトリ移動
cd path/to/servers/src/gdrive
npm install
npm run build

# googleの認証を通す
# このコマンドを実行すると、ブラウザが開いて認証画面が表示される
node ./dist auth

```

ここまでやったら `claude_desktop_config.json` に
```json
{
  "mcpServers": {
    "gdrive": {
      "command": "node",
      "args": [
        "path/to/servers/src/gdrive/dist/index.js"
      ]
    }
  }
}
```
を設定し、Claudeアプリを再起動してください。


</details>

Google Driveサーバーでは、接続したDrive内のファイルがリソースとして活用できます。
設定を済ませてClaudeを起動し、Promptの時同様「Attach from MCP」ボタンをクリックしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/10b6b87f-0e75-cdfa-126c-f427db4a6185.png)

Drive内のファイルたちが、選択できるようになっています。
ファイルを選択すると、コンテキストとして添付することができます。

ただし現状のClaudeアプリだと、検索窓もなく、表示件数もサーバーで指定されている数だけ（デフォルトだと10件）でページャーもないので、かなり使い勝手は悪いです。


## Tool
### Slack MCP Server

Toolに関しては、下記のSlackのMCPサーバーで試します。

https://github.com/modelcontextprotocol/servers/tree/main/src/slack

このMCPサーバーでは、以下の8つのツールが提供されています。

- slack_list_channels
- slack_post_message
- slack_reply_to_thread
- slack_add_reaction
- slack_get_channel_history
- slack_get_thread_replies
- slack_get_users
- slack_get_user_profile

今回は `slack_list_channel` で自分のtimesを見つけ、 `slack_post_message` でテスト投稿をするところまでやってみます。

設定に関しては [slackのMCPサーバーのREADME](https://github.com/modelcontextprotocol/servers/blob/main/src/slack/README.md)に沿ってやれば問題ありません。
（ただし今回は、作ったbotをいちいちチャンネルに参加させるのが面倒だったので、Bot TokenのScopeに `chat:write.public` を追加しています。）

無事接続に成功すると、チャットエリアの右下に🔨アイコンと `8` という数字が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/9c85b797-932f-9232-4e24-ca37cf3f21cd.png)

ここをクリックすると、無事SlackのMCPサーバーが提供しているtoolが使えるようになっていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/d8527a17-734e-f60b-b549-af498eff9d7b.png)

実際にtimesを探してテスト投稿をしてもらうようにお願いしてみると、適切なtoolを活用してちゃんと正しいチャンネルに投稿してくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539670/b38b39ec-a9ec-b011-2aa5-7183a5c0a459.png)




# まとめ

Prompt, Resource, Toolそれぞれについて、Claudeアプリをクライアントとして実際に試してみましたが、現状Tool以外は体験としてはなんともいえませんでした。
Promptを動的なコンテキスト付与だと捉えると少し活用幅は広がりそうかなと思いましたが、クライアント側の機能拡張がもう少し進まないと、引き続きToolの利用が主目的になるかなという感じです。

逆に自分がクライアント側の実装をする時には、これらの機能をフル活用できるように作りたいなと思います