Model Context Protocolを動かしてみる

# はじめに

Anthropicが開発した「Model Context Protocol (MCP)」は、AIモデル（特に大規模言語モデル、LLM）が外部のデータソースやツールと統合するためのプロトコルです。このプロトコルは、AIアプリケーションが必要なコンテキストを取得し、外部システムでアクションを実行するための標準化された方法を提供します。また、MCPサーバーごとに明確な権限設定が可能であり、安全性とプライバシーを重視した設計となっています。初期段階ではローカル環境での利用が推奨されており、今後クラウド対応が進む予定です。Python、TypeScript、Java/Kotlinなど複数の言語向けSDK(https://github.com/modelcontextprotocol )が提供されています。


# APIとの違いなどの図がわかりやすかった

https://norahsakal.com/blog/mcp-vs-api-model-context-protocol-explained/

プロトコルの説明であるとか、APIの違いであるとか。プロトコルとAPIの違いってあまりこれまで考えたことなかったけれどこうした説明はとてもわかりやすい。

![スクリーンショット 2025-04-15 10.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/5ca00f04-636b-4b14-b735-4a3612a5fdb0.png)

![スクリーンショット 2025-04-15 10.36.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/9a783cc2-acf1-4179-9bad-c631c1fcc2c4.png)



# 技術的な仕組み

MCPは以下の主要コンポーネントで構成されています

https://modelcontextprotocol.io/introduction

![IMG_0441.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f1a2fa54-cf62-4443-80f4-109a6ca1fc85.jpeg)

MCP Host with MCP Client Server との 1:1 接続を維持するプロトコル クライアント
MCP Server: 標準化されたモデル コンテキスト プロトコルを通じて特定の機能を公開する軽量プログラム
Local Resource: MCP Server が安全にアクセスできるコンピュータのリソース
Remote Resource: MCP Server が接続できるインターネット経由 (API 経由など) で利用可能なリソース

Clientの一覧は下記のような感じ。

![IMG_0442.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/d3eefbef-9482-4f53-bcd5-e8572b9d3695.jpeg)

https://modelcontextprotocol.io/clients

現状は、ClientとしてのClaude DesktopのMPCはマシン上で実行されているローカルServerへのみのアクセスであるため、ServerはYour Computerの中にある必要がある。


# Servers


MCP Serverは、公式サーバーと、コミュニティサーバーの２種類があります。

公式サーバー
https://github.com/modelcontextprotocol/servers?tab=readme-ov-file

コミュニティサーバー
https://github.com/punkpeye/awesome-mcp-servers


# チュートリアル

動作確認のために一番簡単なsqliteを活用したサンプルを実行してみます

https://modelcontextprotocol.io/quickstart#installing-prerequisites-macos

```bash

brew install uv git sqlite3


# Create a new SQLite database
sqlite3 ~/fruits.db <<EOF
CREATE TABLE fruits (
  id INTEGER PRIMARY KEY,
  name TEXT,
  price REAL
);

INSERT INTO fruits (name, price) VALUES
  ('リンゴ', 300),
  ('バナナ', 200),
  ('オレンジ', 320),
  ('いちご', 1200),
  ('パイナップル', 600),
  ('スイカ', 800),
  ('ブドウ', 1000);
EOF

sqlite3 ~/fruits.db "SELECT * FROM fruits;"

code ~/Library/Application\ Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "sqlite": {
      "command": "uvx",
      "args": ["mcp-server-sqlite", "--db-path", "/Users/user-name/fruits.db"]
    }
  }
}

```


Claudeの設定のところにsqliteが表示されている状態で準備完了です

![スクリーンショット 2025-04-10 9.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/d18b1f97-310a-4f46-9a6d-15054b018d2c.png)

SQLite データベースに接続して、果物の名前と価格のリストを表示して！と質問します

![スクリーンショット 2025-04-10 9.29.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/21bbdf05-f988-4432-8bb1-57033da696fc.png)

ちなみに重複データを入れておいたのですが、出力する時には排他した状態で出してくれています

![スクリーンショット 2025-04-10 9.29.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/89821e8f-c38a-48fc-a4eb-d1ddb6903a63.png)


元データからも、重複データをそれらを排他するようにお願いします

![スクリーンショット 2025-04-10 9.31.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8a92c280-d36e-4f0d-95a8-e22d3c604b24.png)

すると、一時テーブルを作成して、重複データを削除してくれています

![スクリーンショット 2025-04-10 9.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/aa5b8e17-ac72-426c-820a-d6d8b2a5dc90.png)


コンソールでも確認するとしっかり削除されています

![スクリーンショット 2025-04-10 9.31.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/078da1a1-092b-4a4a-ad9a-6e812a529c58.png)



# プログラム例

Python SDKを使用して簡単なMCPサーバーを構築できます。以下は基本的なコード例です：

```javascript index.js

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
    name: "oreore-encryption",
    version: "1.0.0",
    capabilities: {
        resources: {},
        tools: {},
    },
});

server.tool(
    "oreore-encryption-3numbers",
    "３つの数からオレオレ暗号を作る",
    {
        a: z.number().describe("数1"),
        b: z.number().describe("数2"),
        c: z.number().describe("数3"),
    },
    async ({ a, b, c }) => {
        return {
            content: [
                {
                    type: "text",
                    text: `${a * b * c + a * c + b}`,
                },
            ],
        };
    },
);

async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
}

main().catch((error) => {
    console.error("Fatal error in main():", error);
    process.exit(1);
});

```

![スクリーンショット 2025-04-14 16.34.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/b14a3829-641b-4189-ae00-b7ef18d4c1d7.png)

https://github.com/modelcontextprotocol/create-python-server


# debug

inspectorを起動することでデバッグができますー

```bash
$ npx -y @modelcontextprotocol/inspector node ./build/index.js
```

![スクリーンショット 2025-04-14 16.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/43863701-5a79-41f8-b1bd-61848d56dc3b.png)




<iframe width="560" height="315" src="https://www.youtube.com/embed/KPrFd-vhzpk?si=r0jZi9QpJHpjCuxf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>