Open34

Claude Desktop for Linux をインストールして、MCPのQuick Startを行ったときのメモ

しんせいたろうしんせいたろう
git clone https://github.com/aaddrick/claude-desktop-debian.git
cd claude-desktop-debian
sudo ./build.sh 

対話形式で聞かれるので、選択していく

====== Select Build Format ======
  [1] Debian Package (.deb)
  [2] AppImage       (.AppImage)
=================================

Enter choice (1 or 2, any other key to cancel): 1
✔ You selected Debian Package (.deb)
-------------------------------------
--- Cleanup Selection ---

====== Cleanup Build Files ======
This refers to the intermediate files created in the '/tmp/hoge/claude-desktop-debian/build' directory.
  [1] Yes, remove intermediate build files after completion
  [2] No, keep intermediate build files
=================================

Enter choice (1 or 2, any other key defaults to "No".): 1

.....


✅ Build process finished.

====== Next Steps ======
📦 To install the Debian package, run:
   sudo apt install ./claude-desktop_0.9.1_amd64.deb
   (or `sudo dpkg -i ./claude-desktop_0.9.1_amd64.deb`)
======================

ビルドが完了したのでインストール

sudo apt install ./claude-desktop_0.9.1_amd64.deb
しんせいたろうしんせいたろう

スタートから、Claudeを選べるようになるので起動

さっくり起動した。ありがたい。

しんせいたろうしんせいたろう

前準備

  • uv 0.4.18以上(uv --versionで確認)
  • Git(git --versionで確認)
  • SQLite(sqlite3 --versionで確認)

uv は入っていなかったので、Installation | uv を参照してインストールした。

curl -LsSf https://astral.sh/uv/install.sh | sh
# インストール後、ターミナル再起動
しんせいたろうしんせいたろう

SQLITEを用意

mkdir tutorial
cd tutorial

sample.sql を用意

sample.sql
CREATE TABLE products (
  id INTEGER PRIMARY KEY,
  name TEXT,
  price REAL
);

INSERT INTO products (name, price) VALUES
  ('Widget', 19.99),
  ('Gadget', 29.99),
  ('Gizmo', 39.99),
  ('Smart Watch', 199.99),
  ('Wireless Earbuds', 89.99),
  ('Portable Charger', 24.99),
  ('Bluetooth Speaker', 79.99),
  ('Phone Stand', 15.99),
  ('Laptop Sleeve', 34.99),
  ('Mini Drone', 299.99),
  ('LED Desk Lamp', 45.99),
  ('Keyboard', 129.99),
  ('Mouse Pad', 12.99),
  ('USB Hub', 49.99),
  ('Webcam', 69.99),
  ('Screen Protector', 9.99),
  ('Travel Adapter', 27.99),
  ('Gaming Headset', 159.99),
  ('Fitness Tracker', 119.99),
  ('Portable SSD', 179.99);

insert

sqlite3 test.db < sample.sql 

確認

sqlite3 test.db 
SQLite version 3.45.3 2024-04-15 13:34:05
Enter ".help" for usage hints.

sqlite> select * from products;
1|Widget|19.99
2|Gadget|29.99
3|Gizmo|39.99
4|Smart Watch|199.99
5|Wireless Earbuds|89.99
6|Portable Charger|24.99
7|Bluetooth Speaker|79.99
8|Phone Stand|15.99
9|Laptop Sleeve|34.99
10|Mini Drone|299.99
11|LED Desk Lamp|45.99
12|Keyboard|129.99
13|Mouse Pad|12.99
14|USB Hub|49.99
15|Webcam|69.99
16|Screen Protector|9.99
17|Travel Adapter|27.99
18|Gaming Headset|159.99
19|Fitness Tracker|119.99
20|Portable SSD|179.99
sqlite> 

しんせいたろうしんせいたろう

Claude Desktopの設定ファイルに設定追加

  1. Claude Desktop > ファイル > 設定
  2. 開発者 > 構成を編集
  3. claude_desktop_config.json があるディレクトリが開くと思うので、claude_desktop_config.json をエディタで開く
  4. 以下の設定を追加する。"/Users/YOUR_USERNAME/test.db" は自身のディレクトリパスへ変更してください。
    claude_desktop_config.json
    {
      "mcpServers": {
        "sqlite": {
          "command": "uvx",
          "args": ["mcp-server-sqlite", "--db-path", "/Users/YOUR_USERNAME/test.db"]
        }
      }
    }
    
しんせいたろうしんせいたろう

claude_desktop_config.json に設定の解説

  • sqlite という名前のMCPサーバを定義
  • uvx コマンドを使ってサーバを起動
  • args にMCPサーバと実際のDBパスを指定
しんせいたろうしんせいたろう
  1. Claude Desktopアプリケーションを再起動
  2. 開いたら色々叱られる⇐一旦無視する(これが出ない人もいると思うので、とりあえずあとで解決します)
  3. ☰ > ヘルプ > 開発者モードを有効にする
  4. 有効にしますか?と聞かれるので有効化
  5. トンカチマークみたいなものが出たらOK
しんせいたろうしんせいたろう

エラーの解決

  1. エラーに出てきた【MCP設定を開く】を押す
  2. Failしたものはなにかを教えてくれる画面が出るのでログフォルダを開く
  3. ログの内容をClaudeさんなどに相談する
    • 今回の場合は uvx がどこにあるかわからないから起きた問題だったようなので、一時的に claude_desktop_config.json の設定を
    "command": "uvx",
    
    から、
    "command": "/home/taro/.local/bin/uvx",
    
    へフルパスを渡すという形に変えたら解決しました。

Claudeさんは、フルパス指定でうまく動作している現状では、その設定を維持するのが最も実用的な解決策でしょう。 というので、このままフルパスを渡すことにします。

しんせいたろうしんせいたろう

SQLITE MCP サーバテスト

  1. トンカチマークを押す
  2. 利用可能なMCPツールというメッセージが出る
    • クエリしたり新規データ作ったり更新したり、色々できますね。
  3. desktop に戻って、プロンプトを書いてみます
  4. プロンプトを読み取って、list_tables を実行すると判断したようです。

    ローカルのDBへ許可を求めて来ていますので、このチャットでは許可することにします。
  5. describe_table も実行したいと言ってきたので、許可します
  6. read_query も実行したいときましたので、許可します
  7. 回答してくれました
しんせいたろうしんせいたろう

続いて filesystem MCP サーバを通して、ファイルシステムへのアクセスしてみよう

しんせいたろうしんせいたろう
  • SQLITEの時と同じ様に claude_desktop_config.json を編集
  1. ☰ > ファイル > 設定 > 開発者 > 構成を編集
  2. claude_desktop_config.json 開く
  3. filesystem サーバ設定を追加。
claude_desktop_config.json
{
    "mcpServers": {
        "sqlite": {
            "command": "uvx",
            "args": [
                "mcp-server-sqlite",
                "--db-path",
                "/tmp/sqlite-mcp-server/test.db"
            ]
        },
        "filesystem": {
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "/tmp/sqlite-mcp-server"
            ]
        }
    }
}
しんせいたろうしんせいたろう
  1. Claude Desktop再起動
  2. トンカチマーク(数が増えてるハズ)を押す
  3. ソースサーバが filesystem というのが追加されているハズ
しんせいたろうしんせいたろう
  1. Claude Desktopにプロンプトを書く
  2. list_allowed_directories を実行するから許可くれって言ってきた。
  3. list_directory もいるから許可くれと言ってきた
  4. 自然言語でお返事くれた。はい。そのとおりです。
しんせいたろうしんせいたろう

MCP Server

  • これまでは Claude Desktop に buildin されていたMCPサーバを使った
  • ここからは自分でのMCPサーバを実装をTutorialに従って実装する

OpenWeather API MCP サーバを実装

  • OpenWeatherは、さまざまな気象APIを提供
  • これを外部リソースとするMCPサーバを作る
しんせいたろうしんせいたろう

MCP サーバのひながたを作成

npx @modelcontextprotocol/create-server weather-server

Need to install the following packages:
@modelcontextprotocol/create-server@0.3.1
Ok to proceed? (y) y

## ここからはエンター押せばいい
? What is the name of your MCP server? weather-server
? What is the description of your server? A Model Context Protocol server
✔ MCP server created successfully!

Next steps:
  cd weather-server
  npm install
  npm run build  # or: npm run watch
  npm link       # optional, to make available globally

Next steps に従ってインストールとビルド

cd weather-server
npm install
npm run build 

依存関係をインストール

npm install --save axios dotenv

.env ファイルを新規作成

touch .env

OpenWeather で取得したAPIキーを書き込んで保存

.env
OPENWEATHER_API_KEY=your-api-key-here

.gitignore に .env を追加(デフォルトですでに追加されていることもある)

.gitignore
node_modules/
build/
*.log
.env*
しんせいたろうしんせいたろう

現在の構成

.
├── .env
├── .gitignore
├── README.md
├── build
├── node_modules
├── package-lock.json
├── package.json
├── src
└── tsconfig.json
しんせいたろうしんせいたろう

src/index.ts を読む

(注意: 私は javascript を全然知りませんので、言葉の使い方が間違っていることがあると思います。)

src/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  ReadResourceRequestSchema,
  ListPromptsRequestSchema,
  GetPromptRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
  • Server : MCP サーバオブジェクトを作るクラス
  • CallToolRequestSchema から GetPromptRequestSchema まで: MCP で定義された request schema と呼ばれるリクエストタイプ
しんせいたろうしんせいたろう

MCPサーバオブジェクトを作る

src/index.ts
const server = new Server(
  {
    name: "weather-server",
    version: "0.1.0",
  },
  {
    capabilities: {
      resources: {},
      tools: {},
      prompts: {},
    },
  }
);
しんせいたろうしんせいたろう

作ったサーバにハンドラを登録

  • server オブジェクトが持つ setRequestHandler メソッドを使ってハンドラを登録
  • これは利用可能な note の一覧を表示するハンドラを登録している
src/index.ts
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: Object.entries(notes).map(([id, note]) => ({
      uri: `note:///${id}`,
      mimeType: "text/plain",
      name: note.title,
      description: `A text note: ${note.title}`
    }))
  };
});
  • これにより serverListResourcesRequestSchema リクエストを受け取ると、return の内容が返される
    • note:// URI scheme
    • Plain text MIME type
    • 人が読める note の名前とタイトル
しんせいたろうしんせいたろう

MCPのコンセプトにおいてResourceとは

return されている resources とは

  • 外部リソース( test.db / 自分のファイル / OpenWeatherAPI など)の読み取りや操作ができるオブジェクトのこと
  • MCPサーバを通じて、外部リソースのコンテンツを公開できるようになるし、
  • LLMは、ツールを通じて外部リソースを操作できるようになる
しんせいたろうしんせいたろう

実際に resource をコントロールするのは、Host側の clients

  • resource は application (Host ) によって制御されるように設計されている
  • つまり Host が 初期化時に作成した Client がリソースの使用方法やタイミングを決定している
  • よって MCP Host によって resource の扱い方が異なることがある

  • Claude Desktop は、ユーザが resource を明示的に選択する必要がある(2025/04/04現在)
  • resource を自動的に選択するクライアントアプリケーションもある
  • AIモデルが resource を決定することもできる

これは何を意味するか?

  • サーバ開発者は、上記いずれのパターンにも対応できるように準備しておかなくては行けない(たぶんこの3つだけじゃないよね?)
しんせいたろうしんせいたろう

resource の データタイプ
resource は MCP サーバを通じて client に渡したいデータタイプを表し、以下を含むことができます。resource は 一意の URI で識別され、テキストまたはバイナリデータを含むことができます。

  • ファイルの内容
  • データベースレコード
  • API応答
  • リアルタイムシステムデータ
  • スクリーンショットや画像
  • ログファイル
  • その他