• プログラミング

【生成 AI】MCP サーバーを書いてみた

a.hayashi
a.hayashi
  • C#
  • .NET
  • AIチャット
  • 生成AI
【生成 AI】MCP サーバーを書いてみた

どうもこんにちは、IT 基盤本部兼生成 AI 推進センタの林です。

今回は「MCP (Model Context Protocol) サーバー」を自作してみたので、その経緯や実装内容についてご紹介いたします。

MCP (Model Context Protocol) とは? なぜ必要なのか

まずは MCP とはなんぞや?というところから話を始めていきたいと思います。

MCP とは

MCP (Model Context Protocol) は、もともと生成 AI サービス「Claude」で有名な Anthropic 社が提唱し始めた AI 向けの共通プロトコルです。最近では OpenAI 社も利用を始めているなど、業界で徐々に広がりつつあります。

MCP は、「AI が道具を使うためのプロトコル」です。AI が情報取得や各種システムとの連携・操作を行うためのプロトコルとして急速に広まっています。

なぜ MCP が必要なのか?

ChatGPT などを皮切りに広がり始めた生成 AI によるチャット サービスはもともと人間の質問に答えてくれたり、指示に従ってテキストや画像などのデータを生成してくれることが利用の中心でした。人間であるユーザーが与えた指示やデータをもとに AI が結果を出力する ── 我々生成 AI 推進センタが EDS で展開している社内向け業務用 AI チャット サービス Excellia もいま現在 (2025.06 現在) はこれが中心です。

しかし今は AI エージェントの時代を迎えようとしています。ユーザーが欲していることに対して AI が自ら行動プランを立案し、人間の代わりにタスクをこなしてくれる時代が迫ってきています。

ここで必要になるのがすなわち MCP なのです。

MCP で嬉しくなること

例えば、Excellia と経費精算システムならびに社員情報のデータベースが MCP で連携できたとします。これは飽くまで仮定で、今のところそのような機能は残念ながら存在していませんが……。

例えば私が Excellia に 「06/13 に幕張メッセで開催されていた展示会 “APPS JAPAN 2025” に行ってきたから経費精算申請おねがい!」 と依頼します。すると、Excellia の AI が社員情報データベースから私の居住地・最寄り駅を取得します。そして幕張メッセというワードから海浜幕張駅が目的地の最寄り駅であると推論します。(実際はここも別の地図データシステムと MCP 連携するのかな?)

そして、Excellia の AI が MCP 連携している経費精算システムで新規経費申請をあげます。

  • 日付: 2025/06/13
  • 区間: 〇〇駅 ~ 海浜幕張駅 (往復)
  • 費用: x,xxx
  • 目的: 展示会訪問 (APPS JAPAN 2025)

まぁここまで都合よくできるのかは実際やってみないとわからない部分もありますが、AI に自然言語で依頼するだけで経費申請が上がるなら楽ですよね。

ここで取り上げたのは、AI が MCP によって道具を使えるようになると、こういうことも考えられるという一例です。私はこんな日常業務レベルでの例しか思いつきませんが、もしかしたら MCP でこうすることができれば、自分の業務がもっと効率化できるかも、というより良いアイデアが浮かんでくる方も多いかもしれません。

MCP の仕組み

図 AI が MCP で処理を実行する流れ (超簡略版)

MCP は上記の図のような構成で動きます。正確には MCP Client という登場人物もいるのですがざっくり描くとこんな感じです。これはかなり簡単に書いた図です。予めご了承ください。

ステップを簡単に説明すると次のような流れです

  1. AI に対して事前に使える道具の提供者である MCP サーバーを予め登録しておきます (手動)
  2. ユーザーから何か AI に指示が来た際、事前に登録された MCP サーバーとしてどんなものがあるのかを確認し、またそれぞれの MCP サーバーが実際にどんな機能を提供してくれるのか必要に応じて AI から MCP サーバーに問い合わせます
  3. MCP サーバーから送られた利用可能な機能を鑑みて AI が具体的な行動計画を立て、実行します

MCP の中では MCP サーバーが重要な役割を果たします。つまるところ MCP サーバーは AI が MCP 経由で道具 (Web サービスなど) を使えるようにするための仲介役のようなものです。

MCP サーバーは SDK などを用いることで誰でも作成することができます。例えば SNS などのサービスについて MCP サーバーが提供されていない場合でも、MCP のリクエストに応じて API をコールする MCP サーバーを作ってしまうことも可能ということです。

シンプル・スクレイピング・MCP

今回は、C# で「指定した URL の Web ページ内容を取得する MCP サーバー」を作成しました。MCP 公式が出している.NET 向け SDK や、Web ページのソースからテキストを抽出 (スクレイピング) する OSS ライブラリを活用したので、比較的簡単に実装できました。

今回実装した MCP サーバーの役割は、AI が「この URL の Web ページの内容を知りたい」と判断したときに、読み取りに行ってもらうというものです。

Visual Studio Code の拡張機能として提供される AI ツール「Cline」から MCP で今回作った MCP サーバーを呼び出している様子は下記の通りです。

図 AI に自然言語でページの内容の要約を依頼すると今回作成した MCP サーバーが利用される
図 MCP サーバー経由で取得した Web ページの内容を AI が要約

今回作ってみようとおもったきっかけ

最近、Visual Studio Code で使える AI アシスタント「Cline」 を活用するのがとても楽しいです。と言いますのも生成 AI に絡む R&D の中では様々なモダンなプログラミング言語やフレームワークが登場します。私は .NET 大好きをこれまで貫いてきた人間なので、現在取り組んでいる分野では、見慣れぬ言語や知らないフレームワークで実装されたモノを扱う機会も一気に増えました。

これまではその手の見知らぬモノに触れる時は 1 から調べながら時間を掛けて読み解いていたのですが、いまは git pull してきたものを Cline に読ませて解説させるだけで大幅な時短になるのです。

しかし、飽くまで AI が知っている時点情報ベースでの読み解きになりますので、例えば最新のフレームワークやらプロダクトやらに関連する OSS になると、途端に AI の読み取りの正確性が落ちてしまいます。ChatGPT などの汎用的なサービスにはインターネット検索を活用して最新の知識を役立てる機能が含まれていますが、Cline などで GPT モデルを生で利用するケースなどではこれらの機能が含まれていないためです。

これを解決するために AI が Web の知識を利用できるようにしてみようと思ったのです。

飽くまで勉強目的

まぁ私が思いつくレベルのことなんてとっくの昔に皆さん思いついてます。AI に Web 上の知識をもとにスクレイピングをやるための MCP サーバーとしてどんなものが既に存在しているのか聞いてみました。

図 AI に既存のスクレイピングできる MCP サーバーを聞いてみた結果

まぁそうっすよねぇーー。あるんですよ既に。でもいいんです。今回は個人的な勉強も兼ねているので。

この手のプロトコルは自分でサーバーやクライアントを実装してみるとより理解が深まるというのが私の持論です。今回は飽くまで勉強がメインの目的ということで車輪の再発明になってしまっていることはヨシとします。

主に実装した内容

今回の実装のポイントは以下の通りです

  1. .NET 8.0 / C# で MCP 公式の SDK を利用
  2. 取得した HTML ソースから情報となるテキストだけを抽出する部分は HtmlAgilityPack という OSS ライブラリを利用
  3. AI 向けに機能として提供する各種メソッドやパラメーターを説明するエンドポイントを設ける必要があるが、ここは MCP の SDK の力により Attribute だけで実装可能

MCP の処理の流れの図でも示しましたが、MCP では最初 AI が MCP サーバーに対して「君はどんな機能を提供してくれるの?」と問い合わせるところから始まります。ここで機能名と機能の内容、必要なパラメーターの説明を MCP サーバーが返します。本来であれば、各種機能本体とは別で AI に対して説明する機能を設ける必要がありますが、SDK が Attribute (Java で言うところの Annotation に相当) で説明を書くことで実装を省略できるようにしてくれています。素晴らしい。

実際の機能部分 (一部抜粋):

using ModelContextProtocol.Server;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleScrapingMCP
{
    [McpServerToolType]
    public static class SimpleScrapingTool
    {
        // AI 向けのメソッド説明: これは Web ページからデータをスクレイピングするための道具です
        [McpServerTool, Description("A tool for scraping data from web pages.")]
        public static async Task<string> ScrapeAsync(
            HttpClient client,
            // AI 向けのパラメータ説明: スクレイピングする URL
            [Description("The URL of the page to be scraped.")] string url)
        {
            // 指定された URL の HTML ソースを取得
            var response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            var html = await response.Content.ReadAsStringAsync();

            // ライブラリ "HtmlAgilityPack" の力を借りて HTML を解析
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            // タイトルを抽出
            var titleNode = doc.DocumentNode.SelectSingleNode("//title");
            string title = titleNode != null ? titleNode.InnerText.Trim() : "(no title)";

            // 本文を抽出
            var bodyNode = doc.DocumentNode.SelectSingleNode("//body");
            string body = bodyNode != null ? bodyNode.InnerText.Trim() : "(no body)";

            // AI に読み込んだ結果として返す文字列を作成
            var sb = new StringBuilder();
            sb.AppendLine($"URL: {url}");
            sb.AppendLine($"Title: {title}");
            sb.AppendLine("Body:");
            sb.AppendLine(body);

            return sb.ToString();
        }
    }
}

こんな感じで Attribute で AI 向けの説明が仕込めるのは便利ですね。

実装にかかった時間と今後やってみたいこと

この程度の機能であれば、MCP 公式のドキュメントを参照することで 30 分程度で実装できました。

今後は、さまざまな Web API を利用した MCP サーバーを作ってみるのも面白そうだなと思っています。実際、有名なプロダクトの API を MCP で利用するための MCP サーバーは、すでに有志によっていろいろ作成されています。

Web に限らず API が公開されていれば比較的簡単に実装できるでしょう。例えば社内の電子稟議システムの API を利用した MCP サーバーを実装して、今から自分が起案しようとしている稟議の参考情報として類似事例の過去の稟議を提示してもらったりもできるかと思います。夢が広がりますね。

ありがとうございました!

新着記事一覧へ