木曜日, 5月 1, 2025
ホームニューステックニュース【備忘録】今更MCPサーバを勉強した #Python - Qiita

【備忘録】今更MCPサーバを勉強した #Python – Qiita



【備忘録】今更MCPサーバを勉強した #Python - Qiita

Google Cloud Next 25でGCPがMCP (Model Context Protocol) を取り入れているのを見て、今更ながらMCPを勉強してみました。
本記事は、勉強過程の記録です。

STEP1: MCPサーバの概要を学ぶ

下記の「松尾研究所テックブログ」が分かりやすかったです。

STEP2: 公開されているMCP Serverをたててみる

MCPサーバ

公開されているMCPサーバは主に以下2種類に大別されます。

私はDockerを用いてサーバをたてており、サーバごとにコンテナを分けています。
TypeScript製・Python製いずれもDockerコンテナで立ちあげてしまえば、サーバごとに環境を分離できて便利です。

下記に実際にたてたMCPサーバを記載します。

MCPクライアント

MCPクライアントにはClaude Desktopを利用しました。
MCPの設定を記載するclaude_desktop_config.jsonのパスはMac OSでは/Users//Library/Application Support/Claude/claude_desktop_config.jsonです。

実際にたてたMCPサーバ

Anthoropic公式 MCPサーバ (Filesystem MCP Server)

GitHubリポジトリ:

解説記事:

GitHub

解説記事:

GitHubリポジトリ:

AWS Documentation MCP Server

解説記事:

公式ページ:

Notion

解説記事:

GitHubリポジトリ:

LINE

解説記事:

GitHubリポジトリ:

STEP3: MCPサーバを作って学ぶ

基本、下記Anthoropic公式Quick Startが参考になります。

Python

FastMCPを利用します。

前提:
Claude Desktopアプリは立ち上がっていない状態

手順:

  1. 下記の通り各種ファイルを作成
  2. プロジェクトのルートディレクトリ (Dockerfileと同じ階層) でdocker build -t my-mcp-server-python . を実行し、Docker image作成
  3. Claude Desktopを立ち上げる

ディレクトリ構造

.
├── Dockerfile
├── app.py
└── pyproject.toml

Dockerfile

FROM python:3.12-slim-bookworm

WORKDIR /app

COPY pyproject.toml ./
COPY app.py ./

RUN pip install uv
RUN uv venv
RUN . .venv/bin/activate
RUN uv add "mcp[cli]"

CMD ["uv", "run", "app.py"]

pyproject.toml

[project]
name = "my-mcp-server-python"
version = "0.1.0"
dependencies = [
    "mcp[cli]"
]

app.py

# server.py
from mcp.server.fastmcp import FastMCP

# Create an MCP server with debug enabled
mcp = FastMCP("my-mcp-server-python", debug=True)


# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

# Add this part to run the server
if __name__ == "__main__":
    # stdioトランスポートを使用
    print("Starting MCP server in stdio mode")
    mcp.run(transport="stdio")

claude_desktop_config.json

{
  "mcpServers": {
    "my-mcp-server-python": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "my-mcp-server-python"
      ]
    }
  }
}

コード参考;

TypeScript

@modelcontextprotocol/sdkを利用します。

前提:

  • Claude Desktopアプリは立ち上がっていない状態
  • node, npmのバージョンは下記の通り
    • node: v22.7.0
    • npm: 10.8.2

手順:

  1. プロジェクトのルートディレクトリ (Dockerfileと同じ階層) でnpm init -yを実行
  2. プロジェクトのルートディレクトリで下記を実行
    npm install @modelcontextprotocol/sdk zod
    npm install -D @types/node typescript vitest
    
  3. 下記の通りDockerfile, package.json, tsconfig.json, src/index.test.ts, src/index.tsを作成 (package-lock.jsonは自動生成されたものをそのまま使用)
  4. プロジェクトのルートディレクトリでnpm run testを実行し、パスするのを確認
  5. プロジェクトのルートディレクトリでnpm run buildを実行し、正常にビルドできることを確認 (buildディレクトリ配下にindex.jsindex.test.jsが作成される)
  6. プロジェクトのルートディレクトリでdocker build -t my-mcp-server-typescript . を実行し、Docker image作成
  7. Claude Desktopを立ち上げる

ディレクトリ構造

.
├── Dockerfile
├── build
│   ├── index.js
│   └── index.test.js
├── package-lock.json
├── package.json
├── src
│   ├── index.test.ts
│   └── index.ts
└── tsconfig.json

Dockerfile

FROM node:22-slim

WORKDIR /app

# 全てのファイルを一度にコピー
COPY . .

# 依存関係のインストール
RUN npm install

# TypeScriptのビルドとdistディレクトリの作成を確認
RUN npm run build && \
    if [ -d "build" ]; then \
        chmod +x build/*.js || true; \
    else \
        echo "Error: build directory was not created" && exit 1; \
    fi

# コンテナ起動時のコマンド
CMD ["node", "build/index.js"]

package.json

{
  "name": "my-mcp-server-typescript",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "bin": {
    "my-mcp-server": "./build/index.js"
  },
  "files": [
    "build"
  ],
  "scripts": {
    "test": "vitest",
    "build": "tsc && chmod 755 build/index.js"
  },
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.10.2",
    "zod": "^3.24.3"
  },
  "devDependencies": {
    "@types/jest": "^29.5.14",
    "@types/node": "^22.15.3",
    "typescript": "^5.8.3",
    "vitest": "^3.1.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"],
  "types": ["jest", "node"],
}

src/index.ts

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

export const server = new McpServer({
  name: "my-mcp-server",
  version: "1.0.0",
});

server.tool(
  "add",  // 提供するtoolの名前
  "足し算をする",  // toolの説明
  {
    a: z.number().describe("数値1"),
    b: z.number().describe("数値2"),
  },  // toolのパラメータ定義
  ({ a, b }) => ({ content: [{ type: "text", text: (a + b).toString() }] }),  // toolが提供する機能の本体
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Example MCP Server running on stdio");
}

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

src/index.test.ts

import { describe, it, expect } from "vitest";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { server } from "./index.js";
 
describe("my-mcp-serverのテスト", () => {
  it("add: 足し算の結果を返す", async () => {
    // テスト用クライアントの作成
    const client = new Client({
      name: "test client",
      version: "0.1.0",
    });
 
    // インメモリ通信チャネルの作成
    const [clientTransport, serverTransport] =
      InMemoryTransport.createLinkedPair();
      
    // クライアントとサーバーを接続
    await Promise.all([
      client.connect(clientTransport),
      server.connect(serverTransport),
    ]);
 
    // 6面サイコロを振る
    const result = await client.callTool({
      name: "add",
      arguments: {
        a: 3, b: 8
      },
    });
 
    // 結果が1-6の範囲の数字であることを確認
    expect(result).toEqual({
      content: [
        {
          type: "text",
          text: "11",
        },
      ],
    });
  });
});

claude-desktop-config.json

{
  "mcpServers": {
    "my-mcp-server-typescript": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "my-mcp-server-typescript"
      ]
    }
  }
}

コード参考:

気がついたらPythonのuvというライブラリが一世を風靡していた。

MCPとはなにか?はAnthoropicがMCPを公開した際に簡単に勉強しましたが、ここまで人気になるとは思わず、長らく放置してしまいました。
Node.js(TypeScript)があまり得意ではないというのも放置の原因ではありました。Pythonでも書けるのなら、もっと早く手をつけておけばよかったです(Node.jsも勉強しろ)。
個人的には、もっといろんなサービスが公式MCPを作成してくれると安心して使えるのになぁ…と思いました。



フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -

Most Popular

Recent Comments