概要
visual studio codeでエージェントモードが提供されたため、お試しでMCPサーバーを作成してみました。
GitHub Copilotでバイブコーディング:エージェントモードとMCPサポートがVS Codeユーザーに提供開始
作ったのはPlantUMLコードを検証するMCPサーバーです。
LLMはPlantUMLコードを生成してくれるんですが、実際に画像に変換する際にエラーがでることが多かったからです。
通信方式はServer-Sent Events (SSE)を採用しました。
動作イメージは以下な感じです。
docker版増やしました。
参考: Dockerizing your .NET C# MCP Server for AI Clients like Claude Desktop
イメージ作成
cd plantuml-mcp-server-stdio
dotnet publish /t:PublishContainer
host設定例
"mcp": {
"servers": {
"my-plantuml-mcp-server-docker": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--network=host",
"plantuml-mcp-server-stdio",
"PlantumlBaseUrl=http://your_plantuml_server/"
],
},
}
}
MCP サーバーを自作して GitHub Copilot の Agent に可読性の低いクラス名を作ってもらう
が大変参考になりました。ありがとうございました。
実装
使用した言語、ライブラリ、ツール
- C#
- .NET 9.0
- ModelContextProtocol.AspNetCore:0.1.0-preview.6
- docker
- github Copilot
MCPサーバーの実装例
Model Context Protocol (MCP)のC#用SDKがあり、それを使用しました。
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddCommandLine(args);
builder.Services.AddMcpServer()
.WithToolsFromAssembly();
var app = builder.Build();
app.MapMcp();
app.Run("http://0.0.0.0:3000");
余計な処理もありますけど、これだけでMCPサーバーとして待ち受けます。
ツールについては後述します。
app.MapMcp();
でエンドポイントに割り付けています。
デフォルトは/sseです。今回でいうと
http://localhost:3000/sse
が設定するurlになります。
src/ModelContextProtocol.AspNetCore/McpEndpointRouteBuilderExtensions.cs
に書かれています。
/messageというのもあるみたいです。
Toolの実装例
MCPにはToolsというコンセプトがあって、概要を機械翻訳すると
LLMがサーバーを通してアクションを実行できるようにする
ツールはモデル・コンテキスト・プロトコル(MCP)の強力なプリミティブで、サーバーが実行可能な機能をクライアントに公開できるようにします。ツールを通じて、LLMは外部システムと対話し、計算を実行し、実世界でアクションを起こすことができます。
だそうです。
今回はToolを実装してみました。
他にもPromptsやResourcesがあるみたいです。
namespace PlantUmlTools
{
[McpServerToolType]
public class PlantumlTool
{
[McpServerTool, Description("Validates the provided PlantUML message. If valid, returns 'Ok'. If invalid, returns detailed error information including error description, error line, and other metadata.")]
public async Task<string> ValidatePlantUml(string message)
{
try
{
var encodedMessage = EncodePlantUml(message);
Uri url = new (PlantUmlBaseUrl, $"txt/{encodedMessage}");
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
var responseContent = await response.Content.ReadAsStringAsync();
var headers = response.Headers.ToDictionary(h => h.Key, h => string.Join(", ", h.Value));
var errorDescription = headers.ContainsKey("X-PlantUML-Diagram-Description") && headers["X-PlantUML-Diagram-Description"].Contains("Error");
if (errorDescription == false)
{
return "Ok";
}
var errorDetails = new StringBuilder();
errorDetails.AppendLine($"FAIL");
errorDetails.AppendLine($"{headers["X-PlantUML-Diagram-Description"]}");
if (headers.ContainsKey("X-PlantUML-Diagram-Error"))
{
errorDetails.AppendLine($"{headers["X-PlantUML-Diagram-Error"]}");
}
if (headers.ContainsKey("X-PlantUML-Diagram-Error-Line"))
{
errorDetails.AppendLine($"Error-Line: {headers["X-PlantUML-Diagram-Error-Line"]}");
}
return errorDetails.ToString().Trim();
}
catch (Exception ex)
{
return ex.Message; // Return the exception message if an error occurs
}
}
}
}
実装はとても簡単でした。
登録したいクラスにMcpServerToolType属性を付与して、McpServerTool属性を登録したいメソッドに付与するだけです。
Description属性に説明を加えるとLLMが理解するのに役立つ、気がします。。
後はやりたいことをゴリゴリ書くだけです。
Toolの中身
以降はPlantUMLとのやりとりの話になります。
PlantUMLサーバーは異常時にはヘッダーにX-PlantUML-Diagram-ErrorとX-PlantUML-Diagram-Error-Lineを付与してくれます。(参考: how to detect error in plantuml server rendering)
それを利用してLLMから引数としてplantumlコードをもらい、PlantUML Serverに投げてコードの検証をお願いしています。
正常の場合はOKだけ返して、異常の場合はヘッダーの内容を付与して返してます。
使い方
0. cloneして移動
git clone https://github.com/kwhrkzk/plantuml-validator-mcp-server.git
cd plantuml-validator-mcp-server
1. Docker Compose実行
以下のコマンドを実行してサーバーを起動します。
docker compose up -d
2. VSCodeのMCP設定
Use MCP servers in VS Code (Preview)が参考になります。
MCP:List Servers コマンド
VSCodeのMCP (Model Context Protocol) 拡張機能で利用可能なコマンドの一つです。このコマンドは、現在設定されているMCPサーバーのリストを表示します。
主な用途
MCPサーバーの確認: 現在VSCodeに設定されているMCPサーバーの一覧を確認できます。
サーバーの状態確認: 各サーバーの接続状態や設定内容を確認するのに役立ちます。
MCP: Add Server コマンド
VSCodeのMCP (Model Context Protocol) 拡張機能で利用可能なコマンドの一つで、新しいMCPサーバーを設定に追加するために使用されます。
主な用途
新しいサーバーの登録: MCPサーバーをVSCodeの設定に追加します。
サーバーの接続設定: サーバーのURLやタイプ(例: SSE)を指定して、MCPサーバーとの通信を可能にします。
"mcp": {
"servers": {
"my-plantuml-mcp-server": {
"type": "sse",
"url": "http://localhost:3000/sse"
}
}
}
エージェントモードでスパナみたいなマークを押してサーバーと接続するとツールが見えていたら準備完了です。
実行例
その後何回かやりとりしましたけど出来上がったのが上のシーケンス図になります。
所感
Model Context Protocol (MCP)すごいですね。
XXXと連携できたらなぁという課題を一気に解決してくれる気がします。
実装も簡単で、実現したいところだけを書くだけでした。
コードもほとんどgithub Copilotがやってくれました。
PostgreSQLのMCPサーバーもあるようなのでよくわからないDBのテーブル構造の解析なんかにも使える気がしてきました。