tnkzw.sake

HomeSeriesTagsAbout

clineと無料で作るMCPサーバー入門

Series
やってみた

話題沸騰の MCP サーバーを Gemini の無料 API で cline 君を動かして作ってみました。
かなりさっくりできてイメージもついたので手順を記録しておきます。

事前準備

構築手順

1 cline の設定

VSCode 拡張で入れた cline のAPI ProviderGoogle Geminiとし、取得した API キーを貼り付けるだけです。
Model は最新のgemini-2.5-pro-exp-03-25を利用しました。

2 cline と実装する

以下、作業内容を cline にまとめてもらいました。一部加筆修正しています。

2.1 UUID 生成 MCP サーバーの作成依頼

まずは Plan モードで操作します。

  • ユーザーのプロンプト:

    こんにちはcline, uuidを返却するMCPサーバーを作ってみたいんだけど、できますか?
    
  • Cline の行動: まず計画を立て、UUID のバージョンについて質問

  • 成果物:

    計画としては、以下の手順で進めたいと思います。
    
    1. プロジェクトの作成: @modelcontextprotocol/create-server を使用して、TypeScriptベースのMCPサーバープロジェクトを /Users/xxx/Documents/Cline/MCP ディレクトリに作成します。
    2. 依存関係のインストール: UUIDを生成するために uuid パッケージとその型定義 (@types/uuid) をインストールします。
    3. サーバーの実装:
      - src/index.ts ファイルを編集します。
      - uuid パッケージをインポートします。
      - generate_uuid という名前のツールを定義します。このツールはパラメータを受け取らず、呼び出されると新しいUUID (デフォルトではv4) を生成して返します。
      - MCPサーバーの基本的なセットアップ(サーバーインスタンスの作成、ツールハンドラーの設定など)を行います。
    4. ビルド: TypeScriptコードをJavaScriptにコンパイルします。
    5. MCP設定の更新: 作成したサーバーを実行可能にするために、MCP設定ファイル (`/Users/xxx/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`) にサーバーのエントリーを追加します。
    

2.2 実行計画に対する条件

2.1 の結果で cline がcline_mcp_settings.jsonなるものを触ろうとしますが、これが何かよくわかっていません。
なので、その制御も合わせてまずは実装だけしてもらうようにいくつか条件をつけます。

  • ユーザーのプロンプト:

    いくつか条件をつけさせてください。
    1. projectはすでにgit initされた./uuid-mcp-serverで作成すること
    2. nodeで実行する場合は、pnpmを使ってパッケージ管理などを行うこと
    3. cline_mcp_settings.jsonの更新は一旦待ってください。
    

よしなな計画が出てきたので Act Mode に切り替えます。

2.3 プロジェクトの初期化と依存関係のインストール

  • Cline の行動: ユーザーからの条件を反映し、プロジェクトを初期化

    • pnpm init を実行
  • 成果物: package.json

  • Cline の行動: 必要な依存関係をインストール

    • pnpm add uuid @modelcontextprotocol/sdk typescript @types/node --save-dev を実行
  • 成果物: node_modules, pnpm-lock.yaml

2.4 関数ベースでの実装

一度実装されましたが、class 形式で実装されたので以下の指示を出して実装を変更してもらいました。

  • ユーザーの指示:

    関数ベースで実装すること
    
  • Cline の行動: src/index.ts ファイルを関数ベースで実装

  • 成果物: src/index.ts (関数ベース)

    #!/usr/bin/env node
    import { Server } from "@modelcontextprotocol/sdk/server/index.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    import {
      CallToolRequestSchema,
      ErrorCode,
      ListToolsRequestSchema,
      McpError,
    } from "@modelcontextprotocol/sdk/types.js";
    import { v4 as uuidv4 } from "uuid";
    
    async function main() {
      const server = new Server(
        {
          name: "uuid-mcp-server",
          version: "1.0.0",
        },
        {
          capabilities: {
            resources: {},
            tools: {},
          },
        }
      );
    
      server.setRequestHandler(ListToolsRequestSchema, async () => ({
        tools: [
          {
            name: "generate_uuid",
            description: "Generate a version 4 UUID.",
            inputSchema: {
              type: "object",
              properties: {},
              required: [],
            },
          },
        ],
      }));
    
      server.setRequestHandler(CallToolRequestSchema, async (request) => {
        if (request.params.name !== "generate_uuid") {
          throw new McpError(
            ErrorCode.MethodNotFound,
            `Unknown tool: ${request.params.name}`
          );
        }
    
        try {
          const newUuid = uuidv4();
          return {
            content: [
              {
                type: "text",
                text: newUuid,
              },
            ],
          };
        } catch (error) {
          console.error("Error generating UUID:", error);
          throw new McpError(ErrorCode.InternalError, "Failed to generate UUID.");
        }
      });
    
      server.onerror = (error) => console.error("[MCP Error]", error);
      process.on("SIGINT", async () => {
        await server.close();
        process.exit(0);
      });
    
      const transport = new StdioServerTransport();
      await server.connect(transport);
      console.error("UUID MCP server running on stdio");
    }
    
    main().catch(console.error);
    

2.5 .gitignore の作成

  • ユーザーの指示:

    .gitignore を作成すること
    
  • Cline の行動: .gitignore ファイルを作成

2.6 ビルド成果物が出力されない問題の修正

  • ユーザーの指示:

    buildしても成果物が出ていないので修正すること
    
  • Cline の行動: tsconfig.json"noEmit": true をコメントアウト

2.7 ドキュメントの作成

  • ユーザーの指示:

    実装成果のドキュメントを作成すること
    
  • Cline の行動: 以下のドキュメントファイルを作成

  • 成果物:

    • README.md
    • docs/design.md
    • docs/code_explanation.md
    • docs/usage.md

このドキュメントと実際のコードを見て内容のキャッチアップをします。
たしかに形式の決まった Json をやり取りしているだけのようなコードです。

2.8 MCP 設定ファイル (cline_mcp_settings.json) の設定

これは cline の設定から飛べるファイルでした。ローカルの MCP サーバーを設定する場合、ここにサーバーの情報や起動コマンドを記載します。
今回は結局追加の指示を出して cline に編集してもらいました。

{
  "mcpServers": {
    "uuid-generator": {
      "command": "node",
      "args": ["/Users/xxx/xxx/uuid-mcp-server/dist/index.js"],
      "env": {},
      "disabled": false,
      "autoApprove": []
    }
  }
}

2.9 動作確認

呼び出してみると uuid がちゃんと返ってきています!

uuidが返っている様子
cline が MCP サーバーと通信し uuid を取得している様子

まとめ

cline はすぐに API 料金がとんでもないことになるので無料でここまでできるのは本当にありがたいです。
.gitignoreの作成などもやってくれるので、ほとんど何も触らずにできてしまったリポジトリはこちらです。

https://github.com/tomoaki-sake/uuid-mcp-serverhttps://github.com/tomoaki-sake/uuid-mcp-server

MCP サーバーは肩肘張らなくても自社用に作っていけそうな気軽さを感じました。
一方、まだまだ新しいものなのでセキュリティ等々も動向を注視したいところ。ひとまず仕組みがイメージできたので、話題の Playwright MCP や GitHub の MCP など公式系から活用を模索してみます。